Compare commits

...
47 Commits
Author SHA1 Message Date
Mervin Praison 82b83ded41 Merge pull request #298 from MervinPraison/develop
Update PraisonAI and praisonaiagents to versions 2.0.46 and 0.0.36 re…
2025-01-14 13:47:58 +00:00
MervinPraison fc80db32c2 Update PraisonAI and praisonaiagents to versions 2.0.46 and 0.0.36 respectively
- Bumped the PraisonAI package version from 2.0.45 to 2.0.46 in Dockerfile, pyproject.toml, and related files.
- Updated the installation command in Dockerfile and deployment scripts to reflect the new version.
- Updated the praisonaiagents package version from 0.0.35 to 0.0.36 in relevant files.
- Introduced new agents for data analysis, finance, image processing, and more, enhancing the framework's capabilities.
- Added new example scripts demonstrating the usage of the newly created agents.
- Updated documentation to include new agents and their functionalities, improving user guidance and accessibility.

This commit enhances the overall functionality of the PraisonAI framework while ensuring that all components are up-to-date.
2025-01-14 13:46:43 +00:00
Mervin Praison 3f115ca7ba Merge pull request #297 from MervinPraison/develop
Refactor multimodal agent execution and enhance documentation structure
2025-01-14 09:48:14 +00:00
MervinPraison a32d45e6da Refactor multimodal agent execution and enhance documentation structure
- Simplified the execution of the multimodal agent by removing unnecessary result printing, allowing for a cleaner start method call.
- Updated `mint.json` to include new tabs for "Documentation" and "Use Cases," improving navigation and accessibility of relevant information.
- Added a new "Usecases" group in the navigation section of `mint.json`, detailing various use cases for better user guidance.

This commit streamlines the multimodal agent's functionality and enhances the documentation for improved user experience.
2025-01-14 09:47:50 +00:00
Mervin Praison 8823df26ff Merge pull request #294 from MervinPraison/develop
Add EXASearchTool class and integrate with AI agents
2025-01-13 13:20:26 +00:00
MervinPraison 9c2126fbd6 Add EXASearchTool class and integrate with AI agents
- Introduced a new `EXASearchTool` class to interact with the EXA Search API, allowing AI agents to perform searches and retrieve results.
- Implemented methods for running queries and parsing results into a readable format.
- Created a `SearchAgent` to utilize the `EXASearchTool` for searching information about the 'AI Agents Framework'.
- Added a task definition for the `SearchAgent` to demonstrate the tool's functionality.
- Updated documentation to include the new `tools_class` and provide a comprehensive guide on using class-based tools with AI agents.
2025-01-13 13:20:00 +00:00
Mervin Praison 741b01bdf0 Merge pull request #293 from MervinPraison/develop
Refactor autonomous agent workflow and enhance documentation
2025-01-13 12:25:56 +00:00
MervinPraison 6ed9a69cd8 Refactor autonomous agent workflow and enhance documentation
- Renamed and refactored functions in `autonomous-agent.py` to improve clarity and functionality, including changing `get_environment_feedback` to `get_environment_state`.
- Introduced new agents: `Environment Monitor`, `Action Executor`, and `Feedback Processor` to better structure the workflow.
- Updated task definitions to create a more coherent feedback loop and action execution process.
- Added a `main` function to encapsulate the workflow execution and result printing.
- Updated `mint.json` to include a new "Workflows" group for better organization of documentation.
- Removed the outdated `agenticrouting.mdx` documentation file to streamline content.

This commit enhances the overall structure and readability of the autonomous agent system while improving documentation organization.
2025-01-13 12:24:51 +00:00
Mervin Praison 56a42e6d95 Merge pull request #292 from MervinPraison/develop
Update PraisonAI and praisonaiagents to version 2.0.45 and 0.0.35 res…
2025-01-13 11:49:53 +00:00
MervinPraison d2b4affdd1 Update PraisonAI and praisonaiagents to version 2.0.45 and 0.0.35 respectively
- Bumped the PraisonAI package version from 2.0.44 to 2.0.45 in Dockerfile, pyproject.toml, and related files.
- Updated the installation command in Dockerfile and deployment scripts to reflect the new version.
- Updated the praisonaiagents package version from 0.0.34 to 0.0.35 in relevant files.
- Introduced new evaluator-optimiser and parallelisation features with corresponding agent and task implementations.
- Added documentation for the evaluator-optimiser feature and updated existing documentation for parallelisation.
- Adjusted dependencies in uv.lock for compatibility with the new versions.
2025-01-13 11:49:32 +00:00
Mervin Praison 0d5c8b478f Merge pull request #291 from MervinPraison/develop
Add parallelisation feature and update documentation
2025-01-13 07:52:07 +00:00
MervinPraison fdfad70319 Update PraisonAI and praisonaiagents to version 2.0.44 and 0.0.34 respectively
- Bumped the PraisonAI package version from 2.0.43 to 2.0.44 in Dockerfile, pyproject.toml, and related files.
- Updated the installation command in Dockerfile and deployment scripts to reflect the new version.
- Updated the praisonaiagents package version from 0.0.33 to 0.0.34 in relevant files.
- Adjusted dependencies in uv.lock for compatibility with the new versions.
- Refactored agent definitions in parallelization scripts to remove unnecessary verbosity parameters for cleaner code.
2025-01-13 07:51:14 +00:00
MervinPraison fba6b2e2a0 Add parallelisation feature and update documentation
- Introduced a new `parallelisation.py` file to implement parallel processing using AI agents, allowing concurrent execution of tasks for improved performance.
- Created multiple agents and tasks to demonstrate parallel execution and result aggregation.
- Added a new documentation file `parallelisation.mdx` detailing the setup, usage, and benefits of the parallelisation feature.
- Updated `mint.json` to include the new parallelisation feature for better tracking and visibility.
2025-01-13 07:38:24 +00:00
Mervin Praison f9bfb85f44 Merge pull request #290 from MervinPraison/develop
2.0.43
2025-01-13 07:33:48 +00:00
MervinPraison aab4b5b466 Update PraisonAI to version 2.0.43 and praisonaiagents to version 0.0.33
- Bumped the PraisonAI package version from 2.0.42 to 2.0.43 in Dockerfile, pyproject.toml, and related files.
- Updated the installation command in Dockerfile and deployment scripts to reflect the new version.
- Updated the praisonaiagents package version from 0.0.32 to 0.0.33 in relevant files.
- Modified task descriptions in evaluator-optimizer.py to enhance clarity and functionality.
- Adjusted documentation to ensure consistency with the new version.
- Updated dependencies in uv.lock for compatibility with the new versions.
2025-01-13 07:33:15 +00:00
MervinPraison 7ccadde004 Update praisonaiagents to version 0.0.33 and enhance agent functionality
- Bumped the version of the praisonaiagents package from 0.0.32 to 0.0.33 in pyproject.toml and related files.
- Improved tool availability handling by ensuring tools from both tasks and agents are combined for better execution.
- Enhanced parallel task execution logic to efficiently manage asynchronous tasks within workflows.
- Updated callback execution to handle running event loops more gracefully, improving overall stability and error handling.
- Adjusted dependencies in uv.lock for compatibility with the new version.
2025-01-13 06:36:27 +00:00
Mervin Praison 22a9d5ff23 Merge pull request #287 from MervinPraison/develop
Refactor prompt chaining and update JSON configuration
2025-01-12 07:03:55 +00:00
MervinPraison 98a11209ea Refactor prompt chaining and update JSON configuration
- Simplified import statements in agents/prompt_chaining.py for better readability.
- Updated the condition handling in the initial_task to specify "exit" for odd conditions, clarifying task flow.
- Added "features/promptchaining" to the mint.json configuration, enhancing feature tracking for prompt chaining capabilities.
2025-01-12 07:03:32 +00:00
Mervin Praison df3c97e73a Merge pull request #286 from MervinPraison/develop
Update PraisonAI to version 2.0.42 and praisonaiagents to version 0.0.32
2025-01-12 06:40:44 +00:00
MervinPraison 27808964be Update PraisonAI to version 2.0.42 and praisonaiagents to version 0.0.32
- Updated the PraisonAI package version from 2.0.41 to 2.0.42 in Dockerfile, pyproject.toml, and related files.
- Adjusted installation command in Dockerfile and deploy scripts to reflect the new version.
- Updated the praisonaiagents package version from 0.0.31 to 0.0.32 in relevant files.
- Enhanced the prompt chaining implementation in agents/prompt_chaining.py for improved task management and workflow execution.
- Added new documentation on agentic prompt chaining to guide users in creating complex workflows.
- Updated dependencies in uv.lock for compatibility with the new versions.
2025-01-12 06:40:29 +00:00
Mervin Praison b5daf16e0d Merge pull request #285 from MervinPraison/develop
adding docs
2025-01-11 17:13:14 +00:00
MervinPraison a2cac05d16 adding docs 2025-01-11 17:12:56 +00:00
Mervin Praison ad9828d3bb Merge pull request #284 from MervinPraison/develop
Update PraisonAI to version 2.0.41 and enhance documentation
2025-01-11 16:13:02 +00:00
MervinPraison 85ddf04b47 Update PraisonAI to version 2.0.41 and enhance documentation
- Updated PraisonAI package version from 2.0.40 to 2.0.41 in Dockerfile, pyproject.toml, and related files.
- Adjusted installation command in Dockerfile and deploy scripts to reflect the new version.
- Improved logging in agents_generator.py to handle missing tools.py file gracefully.
- Updated deployment documentation to ensure consistency with the new version.
- Adjusted dependencies in uv.lock for compatibility with the updated PraisonAI version.
2025-01-11 16:12:41 +00:00
Mervin Praison 1c1a1b719b Merge pull request #283 from MervinPraison/develop
Update PraisonAI to version 2.0.40 and enhance logging
2025-01-11 16:02:16 +00:00
MervinPraison a8e0914e05 Update PraisonAI to version 2.0.40 and enhance logging
- Updated the PraisonAI package version from 2.0.39 to 2.0.40 in Dockerfile, pyproject.toml, and related files.
- Added a new memory configuration option in agents.yaml to control memory usage.
- Improved logging throughout the codebase by changing info logs to debug logs for better traceability.
- Updated .gitignore to include new files for better project management.
- Adjusted dependencies in pyproject.toml and uv.lock for compatibility with the new version.
2025-01-11 16:01:54 +00:00
Mervin Praison ec6d883f4f Merge pull request #282 from MervinPraison/develop
adding langchain agent doc
2025-01-11 08:21:48 +00:00
MervinPraison d094cbfac5 adding langchain agent doc 2025-01-11 08:21:25 +00:00
Mervin Praison 14e3724aed Merge pull request #281 from MervinPraison/develop
Update praisonaiagents to version 0.0.31 and enhance agent functionality
2025-01-11 07:51:59 +00:00
MervinPraison 92436277d9 Update praisonaiagents to version 0.0.31 and enhance agent functionality
- Updated the version of the praisonaiagents package from 0.0.30 to 0.0.31 in pyproject.toml and related files.
- Added a new Fact Agent to store and retrieve facts, improving the overall functionality of the agent system.
- Enhanced the Research Agent with multiple tasks focused on AI topics, including healthcare and education.
- Updated display functions to include agent information in the output, improving clarity during interactions.
- Improved logging for agent processing and responses, aiding in debugging and tracking agent activities.
- Adjusted dependencies in pyproject.toml and uv.lock for compatibility with the new version.
2025-01-11 07:51:05 +00:00
Mervin Praison 3e0fd298e2 Merge pull request #280 from MervinPraison/develop
AI Agents with memory
2025-01-10 17:21:44 +00:00
MervinPraison fad0b41b52 Update PraisonAI to version 2.0.38 and enhance memory management
- Updated PraisonAI package version from 2.0.37 to 2.0.38 in Dockerfile, pyproject.toml, and related files.
- Refactored memory handling in memory_example.py to improve database path management and logging.
- Introduced new memory management features in the PraisonAIAgents class, allowing for better context retention across tasks.
- Enhanced logging throughout the codebase for improved debugging and tracking of memory operations.
- Added comprehensive documentation on memory capabilities, including short-term and long-term memory management.
- Updated dependencies in pyproject.toml and uv.lock for compatibility with the new version.
2025-01-10 17:20:54 +00:00
MervinPraison 6c3e5ee187 Agents(memory=True) working
Refactor memory management and enhance agent initialization

- Removed direct memory initialization from memory_example.py and integrated shared memory handling into PraisonAIAgents class.
- Updated PraisonAIAgents constructor to accept a memory flag, initializing shared memory if enabled.
- Assigned shared memory to tasks dynamically, improving data sharing between agents.
- Enhanced logging for memory initialization and task assignment to facilitate debugging.
2025-01-10 06:11:35 +00:00
MervinPraison f842ee7048 Update chainlit dependency to version 2.0.1 and improve tool registration in realtime.py
- Updated chainlit version from 1.3.2 to 2.0.1 in pyproject.toml and uv.lock.
- Enhanced tool registration logic in realtime.py to ensure only valid tools are added, with improved error handling and logging for invalid tool definitions.
- Refactored custom tools processing to support both formatted and unformatted tool definitions.
2025-01-10 06:01:47 +00:00
MervinPraison b0ff6f3f60 Update .gitignore and add new ignore files; enhance memory_example.py and memory.py functionality
- Updated .gitignore to include chroma_db/ directory.
- Added .praisoncontext and .praisonignore files for better project structure.
- Refactored memory_example.py to improve memory retrieval and logging.
- Enhanced memory.py to handle exceptions during ChromaDB collection initialization and updated embedding model to 'text-embedding-3-small'.
- Improved logging for embedding operations and ensured API key is set correctly.
2025-01-10 05:40:32 +00:00
MervinPraison 798f6dad14 Refactor memory handling and enhance task execution flow
- Improved memory initialization and management in memory_example.py and Task class.
- Integrated shared memory for tasks to facilitate data sharing between agents.
- Enhanced error handling and logging for memory operations in the Memory class.
- Updated task execution to include memory context and quality metrics.
- Added new task for querying both short-term and long-term memory.
- Improved overall structure and clarity of code with better logging practices.
2025-01-09 10:24:53 +00:00
MervinPraison 629bf0d669 Refactor memory management and enhance search functionality
- Removed unused imports and improved logging in memory_example.py.
- Updated Task description and expected output for clarity.
- Enhanced Memory class to support OpenAI embeddings for improved search capabilities.
- Added quality and relevance filtering in search_short_term and search_long_term methods.
- Implemented deletion of existing ChromaDB collection before creating a new one.
- Improved error handling and logging for database operations.
2025-01-09 06:44:25 +00:00
MervinPraison eaca447b82 Enhance code structure and documentation:
- Updated cursor rules for minimal code changes and user-friendly function naming.
- Integrated Memory module into the PraisonAIAgents initialization.
- Modified Agent class parameters for improved flexibility and default values.
- Enhanced Task class with memory and quality check features, including logging for quality metrics during execution.
2025-01-09 06:23:00 +00:00
Mervin Praison bef3693627 Merge pull request #278 from MervinPraison/develop
updating docs
2025-01-08 16:43:47 +00:00
MervinPraison aa62babed6 updating docs 2025-01-08 16:43:30 +00:00
Mervin Praison b73f181200 Merge pull request #277 from MervinPraison/develop
Updating Docs
2025-01-08 13:42:39 +00:00
MervinPraison 66d2998047 Updating Docs 2025-01-08 13:42:00 +00:00
Mervin Praison c5b6f8b91a Merge pull request #276 from MervinPraison/develop
adding autoagents
2025-01-08 06:47:17 +00:00
MervinPraison 823e46ca84 adding autoagents 2025-01-08 06:47:02 +00:00
Mervin Praison 57040333a7 Merge pull request #275 from MervinPraison/develop
Develop
2025-01-07 18:19:17 +00:00
MervinPraison 8c6800f876 adding langchain with uv 2025-01-07 18:18:46 +00:00
MervinPraison 0d701ae43c adding langchain 2025-01-07 14:15:32 +00:00
203 changed files with 22871 additions and 40924 deletions

No files matched your search

+2 -1
View File
@@ -65,4 +65,5 @@ outputs
agents/praisonaiagents/build
agents/praisonaiagents/dist
agents/praisonaiagents/praisonaiagents.egg-info
.codegpt
.codegpt
.praison
+1 -1
View File
@@ -1,6 +1,6 @@
FROM python:3.11-slim
WORKDIR /app
COPY . .
RUN pip install flask praisonai==2.0.35 gunicorn markdown
RUN pip install flask praisonai==2.0.46 gunicorn markdown
EXPOSE 8080
CMD ["gunicorn", "-b", "0.0.0.0:8080", "api:app"]
+1
View File
@@ -1,6 +1,7 @@
framework: praisonai
process: sequential
topic: create movie script about cat in mars
memory: false
roles:
researcher:
backstory: Skilled in research, with a focus on gathering accurate and relevant
+8
View File
@@ -0,0 +1,8 @@
1. Make minimal code changes as possible
2. if you are creating function, make sure to name it in more easy, user friendly , optimised manner.
3. Never copy the exact code if presented with a code from other location or file or codebase, just make it optimised
4. Always Follow the principle LESS IS MORE
5. Make it minimal change as possible
6. Firstly try not to make any modification to the existing code as possible
7. Only modify the existing code if its highly required, without that if it cant be done, then add new code section.
8. If you are adding new code, make sure to add it in a way that it can be easily integrated with the existing codebase.
+2 -1
View File
@@ -83,4 +83,5 @@ dist
build
*.mp4
*.png
graph.py
graph.py
chroma_db/
View File
Whitespace-only changes.
+32
View File
@@ -0,0 +1,32 @@
.cursorrules
.gitignore
.praisoncontext
.praisonignore
.windsurfrules
async_example.py
async_example_full.py
async_example_full_multigroups.py
auto_agents_example.py
code_agents_example.py
example_callback.py
example_custom_tools.py
example_sequential.py
image.jpg
langchain_example.py
langchain_logs.py
long_term.db
mini_agents_example.py
multimodal.py
praisonaiagents/tools/*
praisonaiagents/process/*
pyproject.toml
short_term.db
structured_agents_example.py
structured_response_example.py
test.py
tools_example.py
uv.lock
workflow_example_basic.py
workflow_example_detailed.py
__pycache__
__pycache__/*
+8
View File
@@ -0,0 +1,8 @@
1. Make minimal code changes as possible
2. if you are creating function, make sure to name it in more easy, user friendly , optimised manner.
3. Never copy the exact code if presented with a code from other location or file or codebase, just make it optimised
4. Always Follow the principle LESS IS MORE
5. Make it minimal change as possible
6. Firstly try not to make any modification to the existing code as possible
7. Only modify the existing code if its highly required, without that if it cant be done, then add new code section.
8. If you are adding new code, make sure to add it in a way that it can be easily integrated with the existing codebase.
+11
View File
@@ -0,0 +1,11 @@
from praisonaiagents import AutoAgents
from praisonaiagents.tools import duckduckgo
agents = AutoAgents(
instructions="Search for information about AI Agents",
tools=[duckduckgo],
process="sequential",
verbose=True
)
agents.start()
+114
View File
@@ -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()
+108
View File
@@ -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()
+10
View File
@@ -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
""")
+70
View File
@@ -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}")
+151
View File
@@ -0,0 +1,151 @@
from praisonaiagents import Agent, Task, PraisonAIAgents
from typing import List, Dict, Union
from duckduckgo_search import DDGS
from langchain_community.tools import YouTubeSearchTool
from langchain_community.utilities import WikipediaAPIWrapper
# 1. Tool
def internet_search_tool(query: str) -> List[Dict]:
"""
Perform a search using DuckDuckGo.
Args:
query (str): The search query.
Returns:
list: A list of search result titles, URLs, and snippets.
"""
try:
results = []
ddgs = DDGS()
for result in ddgs.text(keywords=query, max_results=10):
results.append({
"title": result.get("title", ""),
"url": result.get("href", ""),
"snippet": result.get("body", "")
})
return results
except Exception as e:
print(f"Error during DuckDuckGo search: {e}")
return []
def youtube_search_tool(query: str, inspect: bool = False, max_results: int = 2):
"""
Provide a custom wrapper around the YouTubeSearchTool.
Args:
query (str): The search query for YouTube.
inspect (bool): If True, returns tool inspection info instead of search results.
max_results (int): Maximum number of results to return (default: 2).
Returns:
Union[List[str], dict]: List of YouTube video URLs or tool inspection info.
"""
yt = YouTubeSearchTool()
if inspect:
inspection_info = {
"type": type(yt),
"attributes": [attr for attr in dir(yt) if not attr.startswith('_')],
"methods": {
"run": getattr(yt, 'run', None),
"arun": getattr(yt, 'arun', None)
},
"properties": {
"name": getattr(yt, 'name', 'youtube_search'),
"description": getattr(yt, 'description', 'Search YouTube videos'),
"return_direct": getattr(yt, 'return_direct', False)
}
}
return inspection_info
# Format query with max_results
formatted_query = f"{query}, {max_results}"
return yt.run(formatted_query)
def wikipedia_search_tool(query: str, inspect: bool = False, max_chars: int = 4000, top_k: int = 3):
"""
Provide a custom wrapper around langchain_community's WikipediaAPIWrapper.
Args:
query (str): A search query for Wikipedia.
inspect (bool): If True, returns tool inspection info instead of search results.
max_chars (int): Maximum characters to return (default: 4000).
top_k (int): Number of top results to consider (default: 3).
Returns:
Union[str, dict]: Summary from Wikipedia or tool inspection info if inspect=True.
"""
w = WikipediaAPIWrapper(
top_k_results=top_k,
doc_content_chars_max=max_chars,
lang='en'
)
if inspect:
inspection_info = {
"type": type(w),
"attributes": [attr for attr in dir(w) if not attr.startswith('_')],
"methods": {
"run": getattr(w, 'run', None),
"arun": getattr(w, 'arun', None)
},
"properties": {
"name": "wikipedia",
"description": "Search and get summaries from Wikipedia",
"top_k": w.top_k_results,
"lang": w.lang,
"max_chars": w.doc_content_chars_max
}
}
return inspection_info
try:
result = w.run(query)
return result
except Exception as e:
return f"Error searching Wikipedia: {str(e)}"
# 2. Agent
data_agent = Agent(
name="DataCollector",
role="Search Specialist",
goal="Perform internet searches to collect relevant information.",
backstory="Expert in finding and organizing internet data from multiple sources.",
tools=[internet_search_tool, youtube_search_tool, wikipedia_search_tool],
self_reflect=False
)
# 3. Tasks
collect_task = Task(
description="Perform an internet search using the query: 'AI job trends in 2024'. Return results as a list of title, URL, and snippet.",
expected_output="List of search results with titles, URLs, and snippets.",
agent=data_agent,
name="collect_data",
is_start=True,
next_tasks=["validate_data"]
)
validate_task = Task(
description="""Validate the collected data. Check if:
1. At least 5 results are returned.
2. Each result contains a title and a URL.
Return validation_result as 'valid' or 'invalid' only no other text.""",
expected_output="Validation result indicating if data is valid or invalid.",
agent=data_agent,
name="validate_data",
task_type="decision",
condition={
"valid": [], # End the workflow on valid data
"invalid": ["collect_data"] # Retry data collection on invalid data
},
)
# 4. Workflow
agents = PraisonAIAgents(
agents=[data_agent],
tasks=[collect_task, validate_task],
verbose=1,
process="workflow"
)
agents.start()
File renamed without changes.
+5
View File
@@ -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")
-28535
View File
File diff suppressed because it is too large. Load diff
+47
View File
@@ -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()
+47
View File
@@ -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()
+30
View File
@@ -0,0 +1,30 @@
from praisonaiagents import Agent, Task, PraisonAIAgents
from langchain_community.tools import YouTubeSearchTool
from langchain_community.utilities import WikipediaAPIWrapper
# Create an agent with both tools
agent = Agent(
name="SearchAgent",
role="Research Assistant",
goal="Search for information from multiple sources",
backstory="I am an AI assistant that can search YouTube and Wikipedia.",
tools=[YouTubeSearchTool, WikipediaAPIWrapper],
self_reflect=False
)
# Create tasks to demonstrate both tools
task = Task(
name="search_task",
description="Search for information about 'AI advancements' on both YouTube and Wikipedia",
expected_output="Combined information from YouTube videos and Wikipedia articles",
agent=agent
)
# Create and start the workflow
agents = PraisonAIAgents(
agents=[agent],
tasks=[task],
verbose=True
)
agents.start()
+73
View File
@@ -0,0 +1,73 @@
from langchain_community.tools import YouTubeSearchTool
from langchain_community.utilities import WikipediaAPIWrapper
def test_tools():
"""Test both YouTube and Wikipedia tools"""
print("\n=== Testing YouTube Search ===")
# Test YouTube
yt = YouTubeSearchTool()
# Test basic search
print("\nBasic YouTube Search:")
query = "AI advancements 2024"
print(f"Query: {query}")
result = yt.run(query)
print(f"Results: {result}")
# Test with max results
print("\nYouTube Search with max results:")
query = "AI advancements 2024, 3" # Format: query, max_results
print(f"Query: {query}")
result = yt.run(query)
print(f"Results: {result}")
print("\n=== Testing Wikipedia Search ===")
# Test Wikipedia
wiki = WikipediaAPIWrapper(
top_k_results=2,
doc_content_chars_max=500
)
# Test basic search
print("\nBasic Wikipedia Search:")
query = "Artificial Intelligence"
print(f"Query: {query}")
result = wiki.run(query)
print(f"Results: {result[:200]}..." if result else "No result")
# Test with different parameters
print("\nWikipedia Search with different language:")
wiki_fr = WikipediaAPIWrapper(
lang='fr',
top_k_results=1,
doc_content_chars_max=300
)
result = wiki_fr.run("Intelligence Artificielle")
print(f"French Results: {result[:200]}..." if result else "No result")
def print_tool_info():
"""Print detailed information about the tools"""
print("\n=== Tool Information ===")
# YouTube Tool Info
print("\nYouTube Tool:")
yt = YouTubeSearchTool()
print("Type:", type(yt))
print("Name:", getattr(yt, 'name', None))
print("Description:", getattr(yt, 'description', None))
print("Arguments:", getattr(yt, 'args', None))
# Wikipedia Tool Info
print("\nWikipedia Tool:")
wiki = WikipediaAPIWrapper()
print("Type:", type(wiki))
print("Available Settings:")
print("- Language:", wiki.lang)
print("- Top K Results:", wiki.top_k_results)
print("- Max Characters:", wiki.doc_content_chars_max)
if __name__ == "__main__":
print_tool_info()
test_tools()
View File
Whitespace-only changes.
+4
View File
@@ -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")
+183
View File
@@ -0,0 +1,183 @@
from praisonaiagents import Agent, Task, PraisonAIAgents
import logging
import os
def main():
# Initialize memory config
memory_config = {
"provider": "rag",
"use_embedding": True,
"storage": {
"type": "sqlite",
"path": "./.praison/memory.db"
},
"rag_db_path": "./.praison/chroma_db"
}
# Test facts
fact1 = "The capital city of Jujuha is Hahanu and its population is 102300"
fact2 = "Three main ingredients in a classic proloder are eggs, sugar, and flour"
fact3 = "The year the first Josinga was released is 2007"
# # Check if database exists
# if os.path.exists("./memory.db"):
# logger.info("Found existing memory database")
# else:
# logger.info("Creating new memory database")
# Create task config (without memory config since it's moved to PraisonAIAgents)
task_config = {}
# Create agents with different roles
researcher = Agent(
role="Research Analyst",
goal="Research and document key information about topics",
backstory="Expert at analyzing and storing information in memory",
llm="gpt-4o-mini"
)
retriever = Agent(
role="Information Retriever",
goal="Retrieve and verify stored information from memory",
backstory="Specialist in searching and validating information from memory",
llm="gpt-4o-mini"
)
# Task 1: Process the facts
store_task = Task(
description=f"""
Process and analyze this information:
1. {fact1}
2. {fact2}
3. {fact3}
Provide a clear summary of each fact.
""",
expected_output="""
Clear statements summarizing each fact.
Example format:
1. [Summary of fact 1]
2. [Summary of fact 2]
3. [Summary of fact 3]
""",
agent=researcher
)
# Task 2: Write essay about AI
verify_task = Task(
description="""
write few points about AI
""",
expected_output="Points about AI",
agent=retriever
)
# Task 3: Query memory
query_task = Task(
description="""
Using ONLY information found in memory:
1. What is stored in memory about Hahanu?
2. What ingredients for proloder are recorded in memory?
3. What year is stored in memory for the Josinga release?
For each answer, cite the memory record you found.
""",
expected_output="Answers based solely on memory records with citations",
agent=retriever
)
# Task 4: Query both short-term and long-term memory
query_both_task = Task(
description="""
Using ONLY information found in memory:
1. What is stored in both short-term and long-term memory about Jujuha?
2. What ingredients for proloder are recorded in both short-term and long-term memory?
3. What year is stored in both short-term and long-term memory for the Josinga release?
For each answer, cite the memory record you found.
""",
expected_output="Answers based solely on memory records with citations",
agent=retriever
)
# Initialize PraisonAIAgents with memory configuration
agents = PraisonAIAgents(
agents=[researcher, retriever],
tasks=[store_task, verify_task, query_task, query_both_task],
verbose=True, # Use same verbose level as memory
memory=True,
embedder={
"provider": "openai",
"config": {
"model": "text-embedding-3-small"
}
}
)
# agents = PraisonAIAgents(
# agents=[researcher, retriever],
# tasks=[store_task, verify_task, query_task, query_both_task],
# verbose=True, # Use same verbose level as memory
# memory=True
# )
# Execute tasks
print("\nExecuting Memory Test Tasks...")
print("-" * 50)
agents.start()
# Use shared memory for final checks
memory = agents.shared_memory
# Test memory retrieval with different quality thresholds
if memory:
print("\nFinal Memory Check:")
print("-" * 50)
queries = ["Jujuha", "proloder", "Josinga"]
for query in queries:
print(f"\nSearching memory for: {query}")
# Search in both short-term and long-term memory
print("\nShort-term memory results:")
stm_results = memory.search_short_term(query)
if stm_results:
for item in stm_results:
print(f"Content: {item.get('content', '')[:200]}")
if 'meta' in item:
print(f"Metadata: {item['meta']}")
print("-" * 20)
else:
print("No results found in short-term memory")
print("\nLong-term memory results:")
ltm_results = memory.search_long_term(query)
if ltm_results:
for item in ltm_results:
print(f"Content: {item.get('text', '')[:200]}")
if 'metadata' in item:
print(f"Metadata: {item['metadata']}")
print("-" * 20)
else:
print("No results found in long-term memory")
# Also check ChromaDB if using RAG
if memory.use_rag and hasattr(memory, "chroma_col"):
print("\nChromaDB results:")
try:
all_items = memory.chroma_col.get()
print(f"Found {len(all_items['ids'])} items in ChromaDB")
for i in range(len(all_items['ids'])):
print(f"ID: {all_items['ids'][i]}")
print(f"Content: {all_items['documents'][i][:200]}")
print(f"Metadata: {all_items['metadatas'][i]}")
print("-" * 20)
except Exception as e:
print(f"Error querying ChromaDB: {e}")
print("-" * 30)
else:
print("\nNo memory available for final checks")
if __name__ == "__main__":
main()
+63
View File
@@ -0,0 +1,63 @@
from praisonaiagents.agents.agents import Agent, Task, PraisonAIAgents
from praisonaiagents.tools import duckduckgo
# Test facts
fact1 = "The capital city of Jujuha is Hahanu and its population is 102300"
fact2 = "Three main ingredients in a classic proloder are eggs, sugar, and flour"
fact3 = "The year the first Josinga was released is 2007"
fact_agent = Agent(
name="Fact Agent",
instructions="You are a fact agent, you store and retrieve facts in memory",
llm="gpt-4o-mini"
)
research_agent = Agent(
name="Research Agent",
instructions="You are a research analyst, you research and document key points about topics",
llm="gpt-4o-mini"
)
blog_agent = Agent(
name="Blog Agent",
instructions="You are a blog writer, you write a blog post about the research",
llm="gpt-4o-mini"
)
fact_task = Task(
description="Store the following facts in memory: " + fact1 + ", " + fact2 + ", " + fact3,
agent=fact_agent
)
research_task = Task(
description="Research and document 2 key points about AI",
agent=research_agent
)
research_task2 = Task(
description="Research and document 2 key points about AI in healthcare",
agent=research_agent
)
research_task3 = Task(
description="Research and document 2 key points about AI in education",
agent=research_agent
)
research_task4 = Task(
description="Research and document 2 key points about AI in finance",
agent=research_agent
)
blog_task = Task(
description="Write a blog post about Jujuha",
agent=blog_agent
)
agents = PraisonAIAgents(
agents=[fact_agent, research_agent, blog_agent],
tasks=[fact_task, research_task, research_task2, research_task3, research_task4, blog_task],
memory=True
)
agents.start()
+1 -6
View File
@@ -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()
+110
View File
@@ -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}")
+95
View File
@@ -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())
+41
View File
@@ -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()
+5
View File
@@ -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")
+4
View File
@@ -6,6 +6,8 @@ from .agent.agent import Agent
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 .main import (
TaskOutput,
ReflectionOutput,
@@ -33,6 +35,8 @@ __all__ = [
'Task',
'TaskOutput',
'ReflectionOutput',
'AutoAgents',
'Memory',
'display_interaction',
'display_self_reflection',
'display_instruction',
+73 -18
View File
@@ -16,8 +16,10 @@ from ..main import (
display_self_reflection,
ReflectionOutput,
client,
error_logs
error_logs,
adisplay_instruction
)
import inspect
if TYPE_CHECKING:
from ..task.task import Task
@@ -67,9 +69,24 @@ class Agent:
return None
import inspect
# Langchain tools
if 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}")
# Skip self, *args, **kwargs, so they don't get passed in arguments
parameters_list = []
for name, param in sig.parameters.items():
if name == "self":
continue
if param.kind in (inspect.Parameter.VAR_POSITIONAL, inspect.Parameter.VAR_KEYWORD):
continue
parameters_list.append((name, param))
parameters = {
"type": "object",
"properties": {},
@@ -95,7 +112,7 @@ class Agent:
logging.debug(f"Parameter descriptions: {param_descriptions}")
for name, param in sig.parameters.items():
for name, param in parameters_list:
param_type = "string" # Default type
if param.annotation != inspect.Parameter.empty:
if param.annotation == int:
@@ -146,7 +163,7 @@ class Agent:
max_iter: int = 20,
max_rpm: Optional[int] = None,
max_execution_time: Optional[int] = None,
memory: bool = True,
memory: Optional[Any] = None,
verbose: bool = True,
allow_delegation: bool = False,
step_callback: Optional[Any] = None,
@@ -162,7 +179,7 @@ class Agent:
knowledge_sources: Optional[List[Any]] = None,
use_system_prompt: Optional[bool] = True,
markdown: bool = True,
self_reflect: Optional[bool] = None,
self_reflect: bool = False,
max_reflect: int = 3,
min_reflect: int = 1,
reflect_llm: Optional[str] = None
@@ -249,25 +266,31 @@ Your Goal: {self.goal}
# Try to find the function in the agent's tools list first
func = None
for tool in self.tools:
if callable(tool) and getattr(tool, '__name__', '') == function_name:
if (callable(tool) and getattr(tool, '__name__', '') == function_name) or \
(inspect.isclass(tool) and tool.__name__ == function_name):
func = tool
break
logging.debug(f"Looking for {function_name} in agent tools: {func is not None}")
# If not found in tools, try globals and main
if not func:
if func is None:
# If not found in tools, try globals and main
func = globals().get(function_name)
logging.debug(f"Looking for {function_name} in globals: {func is not None}")
if not func:
import __main__
func = getattr(__main__, function_name, None)
logging.debug(f"Looking for {function_name} in __main__: {func is not None}")
if func and callable(func):
if func:
try:
return func(**arguments)
# If it's a class with run method, instantiate and call run
if inspect.isclass(func) and 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'}
return instance.run(**run_params)
# Otherwise treat as regular function
elif callable(func):
return func(**arguments)
except Exception as e:
error_msg = str(e)
logging.error(f"Error executing tool {function_name}: {error_msg}")
@@ -359,7 +382,7 @@ Your Goal: {self.goal}
display_generating("", start_time),
console=self.console,
refresh_per_second=4,
transient=False, # Changed to False to preserve output
transient=True, # Changed to False to preserve output
vertical_overflow="ellipsis",
auto_refresh=True
) as live:
@@ -444,7 +467,15 @@ Your Goal: {self.goal}
display_text = next((item["text"] for item in prompt if item["type"] == "text"), "")
if display_text and str(display_text).strip():
display_instruction(f"Agent {self.name} is processing prompt: {display_text}", console=self.console)
# Pass agent information to display_instruction
agent_tools = [t.__name__ if hasattr(t, '__name__') else str(t) for t in self.tools]
display_instruction(
f"Agent {self.name} is processing prompt: {display_text}",
console=self.console,
agent_name=self.name,
agent_role=self.role,
agent_tools=agent_tools
)
response = self._chat_completion(messages, temperature=temperature, tools=tools if tools else None)
if not response:
@@ -503,7 +534,7 @@ Your Goal: {self.goal}
self.chat_history.append({"role": "user", "content": original_prompt})
self.chat_history.append({"role": "assistant", "content": response_text})
if self.verbose:
logging.info(f"Agent {self.name} final response: {response_text}")
logging.debug(f"Agent {self.name} final response: {response_text}")
display_interaction(original_prompt, response_text, markdown=self.markdown, generation_time=time.time() - start_time, console=self.console)
return response_text
@@ -608,6 +639,22 @@ Output MUST be JSON with 'reflection' and 'satisfactory'.
item["text"] += "\nReturn ONLY a valid JSON object. No other text or explanation."
break
# Display instruction with agent info if verbose
if self.verbose:
display_text = prompt
if isinstance(prompt, list):
display_text = next((item["text"] for item in prompt if item["type"] == "text"), "")
if display_text and str(display_text).strip():
agent_tools = [t.__name__ if hasattr(t, '__name__') else str(t) for t in self.tools]
await adisplay_instruction(
f"Agent {self.name} is processing prompt: {display_text}",
console=self.console,
agent_name=self.name,
agent_role=self.role,
agent_tools=agent_tools
)
# Format tools if provided
formatted_tools = []
if tools:
@@ -711,4 +758,12 @@ Output MUST be JSON with 'reflection' and 'satisfactory'.
return None
except Exception as e:
display_error(f"Error in _achat_completion: {e}")
return None
return None
def run(self):
"""Alias for start() method"""
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)
+2 -1
View File
@@ -1,4 +1,5 @@
"""Agents module for managing multiple AI agents"""
from .agents import PraisonAIAgents
from .autoagents import AutoAgents
__all__ = ['PraisonAIAgents']
__all__ = ['PraisonAIAgents', 'AutoAgents']
+203 -41
View File
@@ -13,6 +13,9 @@ from ..task.task import Task
from ..process.process import Process, LoopItems
import asyncio
# Set up logger
logger = logging.getLogger(__name__)
def encode_file_to_base64(file_path: str) -> str:
"""Base64-encode a file."""
import base64
@@ -41,7 +44,7 @@ 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):
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):
if not agents:
raise ValueError("At least one agent must be provided")
@@ -57,8 +60,21 @@ class PraisonAIAgents:
# Check for manager_llm in environment variable if not provided
self.manager_llm = manager_llm or os.getenv('OPENAI_MODEL_NAME', 'gpt-4o')
# Set logger level based on verbose
if verbose >= 5:
logger.setLevel(logging.INFO)
else:
logger.setLevel(logging.WARNING)
# Also set third-party loggers to WARNING
logging.getLogger('chromadb').setLevel(logging.WARNING)
logging.getLogger('openai').setLevel(logging.WARNING)
logging.getLogger('httpx').setLevel(logging.WARNING)
logging.getLogger('httpcore').setLevel(logging.WARNING)
if self.verbose:
logging.info(f"Using model {self.manager_llm} for manager")
logger.info(f"Using model {self.manager_llm} for manager")
# If no tasks provided, generate them from agents
if tasks is None:
@@ -66,12 +82,12 @@ class PraisonAIAgents:
for agent in self.agents:
task = agent.generate_task()
tasks.append(task)
logging.info(f"Auto-generated {len(tasks)} tasks from agents")
logger.info(f"Auto-generated {len(tasks)} tasks from agents")
else:
# Validate tasks for backward compatibility
if not tasks:
raise ValueError("If tasks are provided, at least one task must be present")
logging.info(f"Using {len(tasks)} provided tasks")
logger.info(f"Using {len(tasks)} provided tasks")
# Add tasks and set their status
for task in tasks:
@@ -87,9 +103,65 @@ class PraisonAIAgents:
if tasks[i + 1].context is None:
tasks[i + 1].context = []
tasks[i + 1].context.append(tasks[i])
logging.info("Set up sequential flow with automatic context passing")
logger.info("Set up sequential flow with automatic context passing")
self._state = {} # Add state storage at PraisonAIAgents level
# Initialize memory system
self.shared_memory = None
if memory:
try:
from ..memory.memory import Memory
# Get memory config from parameter or first task
mem_cfg = memory_config
if not mem_cfg:
mem_cfg = next((t.config.get('memory_config') for t in tasks if hasattr(t, 'config') and t.config), None)
# Set default memory config if none provided
if not mem_cfg:
mem_cfg = {
"provider": "rag",
"use_embedding": True,
"storage": {
"type": "sqlite",
"path": "./.praison/memory.db"
},
"rag_db_path": "./.praison/chroma_db"
}
# Add embedder config if provided
if embedder:
if isinstance(embedder, dict):
mem_cfg = mem_cfg or {}
mem_cfg["embedder"] = embedder
else:
# Handle direct embedder function
mem_cfg = mem_cfg or {}
mem_cfg["embedder_function"] = embedder
if mem_cfg:
# Pass verbose level to Memory
self.shared_memory = Memory(config=mem_cfg, verbose=verbose)
if verbose >= 5:
logger.info("Initialized shared memory for PraisonAIAgents")
# Distribute memory to tasks
for task in tasks:
if not task.memory:
task.memory = self.shared_memory
if verbose >= 5:
logger.info(f"Assigned shared memory to task {task.id}")
except Exception as e:
logger.error(f"Failed to initialize shared memory: {e}")
# Update tasks with shared memory
if self.shared_memory:
for task in tasks:
if not task.memory:
task.memory = self.shared_memory
logger.info(f"Assigned shared memory to task {task.id}")
def add_task(self, task):
task_id = self.task_id_counter
@@ -139,10 +211,15 @@ 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:
@@ -157,8 +234,8 @@ Here are the results of previous tasks that might be useful:\n
task_prompt += "Please provide only the final result of your work. Do not add any conversation or extra explanation."
if self.verbose >= 2:
logging.info(f"Executing task {task_id}: {task.description} using {executor_agent.name}")
logging.debug(f"Starting execution of task {task_id} with prompt:\n{task_prompt}")
logger.info(f"Executing task {task_id}: {task.description} using {executor_agent.name}")
logger.debug(f"Starting execution of task {task_id} with prompt:\n{task_prompt}")
if task.images:
def _get_multimodal_message(text_prompt, images):
@@ -195,14 +272,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
)
@@ -223,8 +300,8 @@ Here are the results of previous tasks that might be useful:\n
task_output.json_dict = parsed
task_output.output_format = "JSON"
except:
logging.warning(f"Warning: Could not parse output of task {task_id} as JSON")
logging.debug(f"Output that failed JSON parsing: {agent_output}")
logger.warning(f"Warning: Could not parse output of task {task_id} as JSON")
logger.debug(f"Output that failed JSON parsing: {agent_output}")
if task.output_pydantic:
cleaned = self.clean_json_output(agent_output)
@@ -234,8 +311,8 @@ Here are the results of previous tasks that might be useful:\n
task_output.pydantic = pyd_obj
task_output.output_format = "Pydantic"
except:
logging.warning(f"Warning: Could not parse output of task {task_id} as Pydantic Model")
logging.debug(f"Output that failed Pydantic parsing: {agent_output}")
logger.warning(f"Warning: Could not parse output of task {task_id} as Pydantic Model")
logger.debug(f"Output that failed Pydantic parsing: {agent_output}")
task.result = task_output
return task_output
@@ -250,37 +327,53 @@ Here are the results of previous tasks that might be useful:\n
return
task = self.tasks[task_id]
if task.status == "completed":
logging.info(f"Task with ID {task_id} is already completed")
logger.info(f"Task with ID {task_id} is already completed")
return
retries = 0
while task.status != "completed" and retries < self.max_retries:
logging.debug(f"Attempt {retries+1} for task {task_id}")
logger.debug(f"Attempt {retries+1} for task {task_id}")
if task.status in ["not started", "in progress"]:
task_output = await self.aexecute_task(task_id)
if task_output and self.completion_checker(task, task_output.raw):
task.status = "completed"
if task.callback:
# Run execute_callback for memory operations
try:
await task.execute_callback(task_output)
except Exception as e:
logger.error(f"Error executing memory callback for task {task_id}: {e}")
logger.exception(e)
# Run task callback if exists
if task.callback:
try:
if asyncio.iscoroutinefunction(task.callback):
await task.callback(task_output)
else:
task.callback(task_output)
except Exception as e:
logger.error(f"Error executing task callback for task {task_id}: {e}")
logger.exception(e)
self.save_output_to_file(task, task_output)
if self.verbose >= 1:
logging.info(f"Task {task_id} completed successfully.")
logger.info(f"Task {task_id} completed successfully.")
else:
task.status = "in progress"
if self.verbose >= 1:
logging.info(f"Task {task_id} not completed, retrying")
logger.info(f"Task {task_id} not completed, retrying")
await asyncio.sleep(1)
retries += 1
else:
if task.status == "failed":
logging.info("Task is failed, resetting to in-progress for another try...")
logger.info("Task is failed, resetting to in-progress for another try...")
task.status = "in progress"
else:
logging.info("Invalid Task status")
logger.info("Invalid Task status")
break
if retries == self.max_retries and task.status != "completed":
logging.info(f"Task {task_id} failed after {self.max_retries} retries.")
logger.info(f"Task {task_id} failed after {self.max_retries} retries.")
async def arun_all_tasks(self):
"""Async version of run_all_tasks method"""
@@ -292,11 +385,25 @@ Here are the results of previous tasks that might be useful:\n
)
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:
@@ -328,7 +435,7 @@ Here are the results of previous tasks that might be useful:\n
with open(task.output_file, "w") as f:
f.write(str(task_output))
if self.verbose >= 1:
logging.info(f"Task output saved to {task.output_file}")
logger.info(f"Task output saved to {task.output_file}")
except Exception as e:
display_error(f"Error saving task output to file: {e}")
@@ -339,6 +446,15 @@ Here are the results of previous tasks that might be useful:\n
return
task = self.tasks[task_id]
logger.info(f"Starting execution of task {task_id}")
logger.info(f"Task config: {task.config}")
# Initialize memory before task execution
if not task.memory:
task.memory = task.initialize_memory()
logger.info(f"Task memory status: {'Initialized' if task.memory else 'Not initialized'}")
# Only import multimodal dependencies if task has images
if task.images and task.status == "not started":
try:
@@ -371,11 +487,20 @@ Expected Output: {task.expected_output}.
Here are the results of previous tasks that might be useful:\n
{context_results}
"""
# Add memory context if available
if task.memory:
try:
memory_context = task.memory.build_context_for_task(task.description)
if memory_context:
task_prompt += f"\n\nRelevant memory context:\n{memory_context}"
except Exception as e:
logger.error(f"Error getting memory context: {e}")
task_prompt += "Please provide only the final result of your work. Do not add any conversation or extra explanation."
if self.verbose >= 2:
logging.info(f"Executing task {task_id}: {task.description} using {executor_agent.name}")
logging.debug(f"Starting execution of task {task_id} with prompt:\n{task_prompt}")
logger.info(f"Executing task {task_id}: {task.description} using {executor_agent.name}")
logger.debug(f"Starting execution of task {task_id} with prompt:\n{task_prompt}")
if task.images:
def _get_multimodal_message(text_prompt, images):
@@ -425,6 +550,17 @@ Here are the results of previous tasks that might be useful:\n
)
if agent_output:
# Store the response in memory
if task.memory:
try:
task.store_in_memory(
content=agent_output,
agent_name=executor_agent.name,
task_id=task_id
)
except Exception as e:
logger.error(f"Failed to store agent output in memory: {e}")
task_output = TaskOutput(
description=task.description,
summary=task.description[:10],
@@ -440,8 +576,8 @@ Here are the results of previous tasks that might be useful:\n
task_output.json_dict = parsed
task_output.output_format = "JSON"
except:
logging.warning(f"Warning: Could not parse output of task {task_id} as JSON")
logging.debug(f"Output that failed JSON parsing: {agent_output}")
logger.warning(f"Warning: Could not parse output of task {task_id} as JSON")
logger.debug(f"Output that failed JSON parsing: {agent_output}")
if task.output_pydantic:
cleaned = self.clean_json_output(agent_output)
@@ -451,8 +587,8 @@ Here are the results of previous tasks that might be useful:\n
task_output.pydantic = pyd_obj
task_output.output_format = "Pydantic"
except:
logging.warning(f"Warning: Could not parse output of task {task_id} as Pydantic Model")
logging.debug(f"Output that failed Pydantic parsing: {agent_output}")
logger.warning(f"Warning: Could not parse output of task {task_id} as Pydantic Model")
logger.debug(f"Output that failed Pydantic parsing: {agent_output}")
task.result = task_output
return task_output
@@ -467,37 +603,63 @@ Here are the results of previous tasks that might be useful:\n
return
task = self.tasks[task_id]
if task.status == "completed":
logging.info(f"Task with ID {task_id} is already completed")
logger.info(f"Task with ID {task_id} is already completed")
return
retries = 0
while task.status != "completed" and retries < self.max_retries:
logging.debug(f"Attempt {retries+1} for task {task_id}")
logger.debug(f"Attempt {retries+1} for task {task_id}")
if task.status in ["not started", "in progress"]:
task_output = self.execute_task(task_id)
if task_output and self.completion_checker(task, task_output.raw):
task.status = "completed"
# Run execute_callback for memory operations
try:
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)
# Run task callback if exists
if task.callback:
task.callback(task_output)
try:
if asyncio.iscoroutinefunction(task.callback):
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:
logger.error(f"Error executing task callback for task {task_id}: {e}")
logger.exception(e)
self.save_output_to_file(task, task_output)
if self.verbose >= 1:
logging.info(f"Task {task_id} completed successfully.")
logger.info(f"Task {task_id} completed successfully.")
else:
task.status = "in progress"
if self.verbose >= 1:
logging.info(f"Task {task_id} not completed, retrying")
logger.info(f"Task {task_id} not completed, retrying")
time.sleep(1)
retries += 1
else:
if task.status == "failed":
logging.info("Task is failed, resetting to in-progress for another try...")
logger.info("Task is failed, resetting to in-progress for another try...")
task.status = "in progress"
else:
logging.info("Invalid Task status")
logger.info("Invalid Task status")
break
if retries == self.max_retries and task.status != "completed":
logging.info(f"Task {task_id} failed after {self.max_retries} retries.")
logger.info(f"Task {task_id} failed after {self.max_retries} retries.")
def run_all_tasks(self):
"""Synchronous version of run_all_tasks method"""
+335
View File
@@ -0,0 +1,335 @@
"""
AutoAgents - A class for automatically creating and managing AI agents and tasks.
This class provides a simplified interface for creating and running AI agents with tasks.
It automatically handles agent creation, task setup, and execution flow.
"""
from .agents import PraisonAIAgents
from ..agent.agent import Agent
from ..task.task import Task
from typing import List, Any, Optional, Dict, Union
import logging
import os
from pydantic import BaseModel, Field
from ..main import display_instruction, display_tool_call, display_interaction, client
# Define Pydantic models for structured output
class TaskConfig(BaseModel):
name: str
description: str
expected_output: str
tools: List[str]
class AgentConfig(BaseModel):
name: str
role: str
goal: str
backstory: str
tools: List[str]
tasks: List[TaskConfig]
class AutoAgentsConfig(BaseModel):
main_instruction: str
process_type: str
agents: List[AgentConfig]
class AutoAgents(PraisonAIAgents):
def __init__(
self,
instructions: str,
tools: Optional[List[Any]] = None,
verbose: bool = False,
process: str = "sequential",
manager_llm: Optional[str] = None,
max_retries: int = 5,
completion_checker: Optional[Any] = None,
allow_code_execution: bool = False,
memory: bool = True,
markdown: bool = True,
self_reflect: bool = False,
max_reflect: int = 3,
min_reflect: int = 1,
llm: Optional[str] = None,
function_calling_llm: Optional[str] = None,
respect_context_window: bool = True,
code_execution_mode: str = "safe",
embedder_config: Optional[Dict[str, Any]] = None,
knowledge_sources: Optional[List[Any]] = None,
use_system_prompt: bool = True,
cache: bool = True,
allow_delegation: bool = False,
step_callback: Optional[Any] = None,
system_template: Optional[str] = None,
prompt_template: Optional[str] = None,
response_template: Optional[str] = None,
max_rpm: Optional[int] = None,
max_execution_time: Optional[int] = None,
max_iter: int = 20,
reflect_llm: Optional[str] = None,
base_url: Optional[str] = None,
api_key: Optional[str] = None,
max_agents: int = 3 # New parameter for maximum number of agents
):
"""Initialize AutoAgents with configuration for automatic agent and task creation."""
if max_agents < 1:
raise ValueError("max_agents must be at least 1")
if max_agents > 10:
raise ValueError("max_agents cannot exceed 10")
# Store all configuration parameters first
self.instructions = instructions
self.tools = tools or []
self.verbose = verbose # Store verbose parameter
self.max_agents = max_agents # Store max_agents parameter
self.allow_code_execution = allow_code_execution
self.memory = memory
self.markdown = markdown
self.self_reflect = self_reflect
self.max_reflect = max_reflect
self.min_reflect = min_reflect
self.llm = llm or os.getenv('OPENAI_MODEL_NAME', 'gpt-4o')
self.function_calling_llm = function_calling_llm
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.use_system_prompt = use_system_prompt
self.cache = cache
self.allow_delegation = allow_delegation
self.step_callback = step_callback
self.system_template = system_template
self.prompt_template = prompt_template
self.response_template = response_template
self.max_rpm = max_rpm
self.max_execution_time = max_execution_time
self.max_iter = max_iter
self.reflect_llm = reflect_llm
# Display initial instruction
if self.verbose:
display_instruction(f"🎯 Main Task: {self.instructions}")
display_instruction(f"📊 Maximum Agents: {self.max_agents}")
if self.tools:
tool_names = [t.__name__ if hasattr(t, '__name__') else str(t) for t in self.tools]
display_tool_call(f"🛠️ Available Tools: {', '.join(tool_names)}")
# Generate agents and tasks configuration
config = self._generate_config()
agents, tasks = self._create_agents_and_tasks(config)
# Display agents and their tasks
if self.verbose:
self._display_agents_and_tasks(agents, tasks)
# Initialize parent class with generated agents and tasks
super().__init__(
agents=agents,
tasks=tasks,
verbose=verbose,
completion_checker=completion_checker,
max_retries=max_retries,
process=process,
manager_llm=manager_llm
)
def _display_agents_and_tasks(self, agents: List[Agent], tasks: List[Task]):
"""Display the created agents and their assigned tasks"""
display_instruction("\n🤖 Generated Agents and Tasks:")
# Create a mapping of agents to their tasks
agent_tasks = {}
for task in tasks:
if task.agent not in agent_tasks:
agent_tasks[task.agent] = []
agent_tasks[task.agent].append(task)
# Display each agent and their tasks
for agent in agents:
agent_tools = [t.__name__ if hasattr(t, '__name__') else str(t) for t in agent.tools]
display_interaction(
f"\n👤 Agent: {agent.name}",
f"""Role: {agent.role}
Goal: {agent.goal}
Tools: {', '.join(agent_tools)}"""
)
# Display tasks for this agent
if agent in agent_tasks:
for i, task in enumerate(agent_tasks[agent], 1):
task_tools = [t.__name__ if hasattr(t, '__name__') else str(t) for t in task.tools]
display_instruction(
f""" 📋 Task {i}: {task.name}
Description: {task.description}
Expected Output: {task.expected_output}
Tools: {', '.join(task_tools)}"""
)
def _get_available_tools(self) -> List[str]:
"""Get list of available tools"""
if not self.tools:
return []
return [t.__name__ if hasattr(t, '__name__') else str(t) for t in self.tools]
def _get_tool_by_name(self, tool_name: str) -> Optional[Any]:
"""Get tool object by its name"""
for tool in self.tools:
if (hasattr(tool, '__name__') and tool.__name__ == tool_name) or str(tool) == tool_name:
return tool
return None
def _assign_tools_to_agent(self, agent_config: AgentConfig) -> List[Any]:
"""
Assign appropriate tools to an agent based on its role and tasks.
Args:
agent_config: The agent configuration containing role and required tools
Returns:
List of tool objects assigned to this agent
"""
assigned_tools = []
tool_names = set(agent_config.tools)
# Also look at task requirements
for task in agent_config.tasks:
tool_names.update(task.tools)
# Assign tools that match the requirements
for tool_name in tool_names:
tool = self._get_tool_by_name(tool_name)
if tool:
assigned_tools.append(tool)
# If no specific tools matched but we have tools available,
# assign all tools to ensure functionality
if not assigned_tools and self.tools:
assigned_tools = self.tools
return assigned_tools
def _generate_config(self) -> AutoAgentsConfig:
"""Generate the configuration for agents and tasks"""
prompt = f"""
Generate a configuration for AI agents to accomplish this task: "{self.instructions}"
The configuration should include:
1. A main instruction that clearly states the overall goal
2. A process type (sequential, workflow, or hierarchical)
3. A list of maximum {self.max_agents} agents (no more, no less), each with:
- Name, role, goal, and backstory
- List of required tools from: {self._get_available_tools()}
- Only add tools that are needed for the agent to perform its task
- Only one task per agent. Add more than one task if absolutely necessary.
- List of specific tasks they need to perform
- Whether they should self-reflect or allow delegation
Requirements:
1. Each agent should have clear, focused responsibilities
2. Tasks should be broken down into manageable steps
3. Tool selection should be appropriate for each task
4. The process type should match the task requirements
5. Generate maximum {self.max_agents} agents to handle this task efficiently
Return the configuration in a structured JSON format matching the AutoAgentsConfig schema.
"""
try:
response = client.beta.chat.completions.parse(
model=self.llm,
response_format=AutoAgentsConfig,
messages=[
{"role": "system", "content": "You are a helpful assistant designed to generate AI agent configurations."},
{"role": "user", "content": prompt}
]
)
# Ensure we have exactly max_agents number of agents
if len(response.choices[0].message.parsed.agents) > self.max_agents:
response.choices[0].message.parsed.agents = response.choices[0].message.parsed.agents[:self.max_agents]
elif len(response.choices[0].message.parsed.agents) < self.max_agents:
logging.warning(f"Generated {len(response.choices[0].message.parsed.agents)} agents, expected {self.max_agents}")
return response.choices[0].message.parsed
except Exception as e:
logging.error(f"Error generating configuration: {e}")
raise
def _create_agents_and_tasks(self, config: AutoAgentsConfig) -> tuple[List[Agent], List[Task]]:
"""Create agents and tasks from configuration"""
agents = []
tasks = []
for agent_config in config.agents:
# Get appropriate tools for this agent
agent_tools = self._assign_tools_to_agent(agent_config)
# Create the agent with all parameters
agent = Agent(
name=agent_config.name,
role=agent_config.role,
goal=agent_config.goal,
backstory=agent_config.backstory,
tools=agent_tools, # Use assigned tools
verbose=self.verbose >= 1,
allow_code_execution=self.allow_code_execution,
memory=self.memory,
markdown=self.markdown,
self_reflect=self.self_reflect,
max_reflect=self.max_reflect,
min_reflect=self.min_reflect,
llm=self.llm,
function_calling_llm=self.function_calling_llm,
respect_context_window=self.respect_context_window,
code_execution_mode=self.code_execution_mode,
embedder_config=self.embedder_config,
knowledge_sources=self.knowledge_sources,
use_system_prompt=self.use_system_prompt,
cache=self.cache,
allow_delegation=self.allow_delegation,
step_callback=self.step_callback,
system_template=self.system_template,
prompt_template=self.prompt_template,
response_template=self.response_template,
max_rpm=self.max_rpm,
max_execution_time=self.max_execution_time,
max_iter=self.max_iter,
reflect_llm=self.reflect_llm
)
agents.append(agent)
# Create tasks for this agent
for task_config in agent_config.tasks:
# Get task-specific tools
task_tools = [self._get_tool_by_name(t) for t in task_config.tools]
task_tools = [t for t in task_tools if t] # Remove None values
# If no specific tools matched, use agent's tools
if not task_tools:
task_tools = agent_tools
task = Task(
name=task_config.name,
description=task_config.description,
expected_output=task_config.expected_output,
agent=agent,
tools=task_tools # Use task-specific tools
)
tasks.append(task)
return agents, tasks
async def astart(self):
"""
Async version of start() method.
Creates tasks based on the instructions, then starts execution.
Returns the task status and results dictionary.
"""
return await super().astart()
def start(self):
"""
Creates tasks based on the instructions, then starts execution.
Returns the task status and results dictionary.
"""
return super().start()
+32 -8
View File
@@ -116,10 +116,10 @@ def display_interaction(message, response, markdown=True, generation_time=None,
console.print(Text(f"Response generated in {generation_time:.1f}s", style="dim"))
if markdown:
console.print(Panel.fit(Markdown(message), title="Message", border_style="cyan"))
console.print(Panel.fit(Markdown(message), title="Task", border_style="cyan"))
console.print(Panel.fit(Markdown(response), title="Response", border_style="cyan"))
else:
console.print(Panel.fit(Text(message, style="bold green"), title="Message", border_style="cyan"))
console.print(Panel.fit(Text(message, style="bold green"), title="Task", border_style="cyan"))
console.print(Panel.fit(Text(response, style="bold blue"), title="Response", border_style="cyan"))
def display_self_reflection(message: str, console=None):
@@ -135,7 +135,7 @@ def display_self_reflection(message: str, console=None):
console.print(Panel.fit(Text(message, style="bold yellow"), title="Self Reflection", border_style="magenta"))
def display_instruction(message: str, console=None):
def display_instruction(message: str, console=None, agent_name: str = None, agent_role: str = None, agent_tools: List[str] = None):
if not message or not message.strip():
return
if console is None:
@@ -146,7 +146,19 @@ def display_instruction(message: str, console=None):
if 'instruction' in sync_display_callbacks:
sync_display_callbacks['instruction'](message=message)
console.print(Panel.fit(Text(message, style="bold blue"), title="Instruction", border_style="cyan"))
# Display agent info if available
if agent_name:
agent_info = f"[bold #FF9B9B]👤 Agent:[/] [#FFE5E5]{agent_name}[/]"
if agent_role:
agent_info += f"\n[bold #B4B4B3]Role:[/] [#FFE5E5]{agent_role}[/]"
if agent_tools:
tools_str = ", ".join(f"[italic #B4D4FF]{tool}[/]" for tool in agent_tools)
agent_info += f"\n[bold #86A789]Tools:[/] {tools_str}"
console.print(Panel(agent_info, border_style="#D2E3C8", title="[bold]Agent Info[/]", title_align="left", padding=(1, 2)))
# Only print if log level is DEBUG
if logging.getLogger().getEffectiveLevel() == logging.DEBUG:
console.print(Panel.fit(Text(message, style="bold blue"), title="Instruction", border_style="cyan"))
def display_tool_call(message: str, console=None):
if not message or not message.strip():
@@ -222,10 +234,10 @@ async def adisplay_interaction(message, response, markdown=True, generation_time
console.print(Text(f"Response generated in {generation_time:.1f}s", style="dim"))
if markdown:
console.print(Panel.fit(Markdown(message), title="Message", border_style="cyan"))
console.print(Panel.fit(Markdown(message), title="Task", border_style="cyan"))
console.print(Panel.fit(Markdown(response), title="Response", border_style="cyan"))
else:
console.print(Panel.fit(Text(message, style="bold green"), title="Message", border_style="cyan"))
console.print(Panel.fit(Text(message, style="bold green"), title="Task", border_style="cyan"))
console.print(Panel.fit(Text(response, style="bold blue"), title="Response", border_style="cyan"))
async def adisplay_self_reflection(message: str, console=None):
@@ -241,7 +253,7 @@ async def adisplay_self_reflection(message: str, console=None):
console.print(Panel.fit(Text(message, style="bold yellow"), title="Self Reflection", border_style="magenta"))
async def adisplay_instruction(message: str, console=None):
async def adisplay_instruction(message: str, console=None, agent_name: str = None, agent_role: str = None, agent_tools: List[str] = None):
"""Async version of display_instruction."""
if not message or not message.strip():
return
@@ -252,7 +264,19 @@ async def adisplay_instruction(message: str, console=None):
if 'instruction' in async_display_callbacks:
await async_display_callbacks['instruction'](message=message)
console.print(Panel.fit(Text(message, style="bold blue"), title="Instruction", border_style="cyan"))
# Display agent info if available
if agent_name:
agent_info = f"[bold #FF9B9B]👤 Agent:[/] [#FFE5E5]{agent_name}[/]"
if agent_role:
agent_info += f"\n[bold #B4B4B3]Role:[/] [#FFE5E5]{agent_role}[/]"
if agent_tools:
tools_str = ", ".join(f"[italic #B4D4FF]{tool}[/]" for tool in agent_tools)
agent_info += f"\n[bold #86A789]Tools:[/] {tools_str}"
console.print(Panel(agent_info, border_style="#D2E3C8", title="[bold]Agent Info[/]", title_align="left", padding=(1, 2)))
# Only print if log level is DEBUG
if logging.getLogger().getEffectiveLevel() == logging.DEBUG:
console.print(Panel.fit(Text(message, style="bold blue"), title="Instruction", border_style="cyan"))
async def adisplay_tool_call(message: str, console=None):
"""Async version of display_tool_call."""
+931
View File
@@ -0,0 +1,931 @@
import os
import sqlite3
import json
import time
import shutil
from typing import Any, Dict, List, Optional, Union, Literal
import logging
# Set up logger
logger = logging.getLogger(__name__)
try:
import chromadb
from chromadb.config import Settings as ChromaSettings
CHROMADB_AVAILABLE = True
except ImportError:
CHROMADB_AVAILABLE = False
logger.warning("To use memory features, please run: pip install \"praisonaiagents[memory]\"")
try:
import mem0
MEM0_AVAILABLE = True
except ImportError:
MEM0_AVAILABLE = False
try:
import openai
OPENAI_AVAILABLE = True
except ImportError:
OPENAI_AVAILABLE = False
class Memory:
"""
A single-file memory manager covering:
- Short-term memory (STM) for ephemeral context
- Long-term memory (LTM) for persistent knowledge
- Entity memory (structured data about named entities)
- User memory (preferences/history for each user)
- Quality score logic for deciding which data to store in LTM
- Context building from multiple memory sources
Config example:
{
"provider": "rag" or "mem0" or "none",
"use_embedding": True,
"short_db": "short_term.db",
"long_db": "long_term.db",
"rag_db_path": "rag_db", # optional path for local embedding store
"config": {
"api_key": "...", # if mem0 usage
"org_id": "...",
"project_id": "...",
...
}
}
"""
def __init__(self, config: Dict[str, Any], verbose: int = 0):
self.cfg = config or {}
self.verbose = verbose
# Set logger level based on verbose
if verbose >= 5:
logger.setLevel(logging.INFO)
else:
logger.setLevel(logging.WARNING)
# Also set ChromaDB and OpenAI client loggers to WARNING
logging.getLogger('chromadb').setLevel(logging.WARNING)
logging.getLogger('openai').setLevel(logging.WARNING)
logging.getLogger('httpx').setLevel(logging.WARNING)
logging.getLogger('httpcore').setLevel(logging.WARNING)
logging.getLogger('chromadb.segment.impl.vector.local_persistent_hnsw').setLevel(logging.ERROR)
self.provider = self.cfg.get("provider", "rag")
self.use_mem0 = (self.provider.lower() == "mem0") and MEM0_AVAILABLE
self.use_rag = (self.provider.lower() == "rag") and CHROMADB_AVAILABLE and self.cfg.get("use_embedding", False)
# Create .praison directory if it doesn't exist
os.makedirs(".praison", exist_ok=True)
# Short-term DB
self.short_db = self.cfg.get("short_db", ".praison/short_term.db")
self._init_stm()
# Long-term DB
self.long_db = self.cfg.get("long_db", ".praison/long_term.db")
self._init_ltm()
# Conditionally init Mem0 or local RAG
if self.use_mem0:
self._init_mem0()
elif self.use_rag:
self._init_chroma()
def _log_verbose(self, msg: str, level: int = logging.INFO):
"""Only log if verbose >= 5"""
if self.verbose >= 5:
logger.log(level, msg)
# -------------------------------------------------------------------------
# Initialization
# -------------------------------------------------------------------------
def _init_stm(self):
"""Creates or verifies short-term memory table."""
os.makedirs(os.path.dirname(self.short_db) or ".", exist_ok=True)
conn = sqlite3.connect(self.short_db)
c = conn.cursor()
c.execute("""
CREATE TABLE IF NOT EXISTS short_mem (
id TEXT PRIMARY KEY,
content TEXT,
meta TEXT,
created_at REAL
)
""")
conn.commit()
conn.close()
def _init_ltm(self):
"""Creates or verifies long-term memory table."""
os.makedirs(os.path.dirname(self.long_db) or ".", exist_ok=True)
conn = sqlite3.connect(self.long_db)
c = conn.cursor()
c.execute("""
CREATE TABLE IF NOT EXISTS long_mem (
id TEXT PRIMARY KEY,
content TEXT,
meta TEXT,
created_at REAL
)
""")
conn.commit()
conn.close()
def _init_mem0(self):
"""Initialize Mem0 client for agent or user memory."""
from mem0 import MemoryClient
mem_cfg = self.cfg.get("config", {})
api_key = mem_cfg.get("api_key", os.getenv("MEM0_API_KEY"))
org_id = mem_cfg.get("org_id")
proj_id = mem_cfg.get("project_id")
if org_id and proj_id:
self.mem0_client = MemoryClient(api_key=api_key, org_id=org_id, project_id=proj_id)
else:
self.mem0_client = MemoryClient(api_key=api_key)
def _init_chroma(self):
"""Initialize a local Chroma client for embedding-based search."""
try:
# Create directory if it doesn't exist
rag_path = self.cfg.get("rag_db_path", "chroma_db")
os.makedirs(rag_path, exist_ok=True)
# Initialize ChromaDB with persistent storage
self.chroma_client = chromadb.PersistentClient(
path=rag_path,
settings=ChromaSettings(
anonymized_telemetry=False,
allow_reset=True
)
)
collection_name = "memory_store"
try:
self.chroma_col = self.chroma_client.get_collection(name=collection_name)
self._log_verbose("Using existing ChromaDB collection")
except Exception as e:
self._log_verbose(f"Collection '{collection_name}' not found. Creating new collection. Error: {e}")
self.chroma_col = self.chroma_client.create_collection(
name=collection_name,
metadata={"hnsw:space": "cosine"}
)
self._log_verbose("Created new ChromaDB collection")
except Exception as e:
self._log_verbose(f"Failed to initialize ChromaDB: {e}", logging.ERROR)
self.use_rag = False
# -------------------------------------------------------------------------
# Basic Quality Score Computation
# -------------------------------------------------------------------------
def compute_quality_score(
self,
completeness: float,
relevance: float,
clarity: float,
accuracy: float,
weights: Dict[str, float] = None
) -> float:
"""
Combine multiple sub-metrics into one final score, as an example.
Args:
completeness (float): 0-1
relevance (float): 0-1
clarity (float): 0-1
accuracy (float): 0-1
weights (Dict[str, float]): optional weighting like {"completeness": 0.25, "relevance": 0.3, ...}
Returns:
float: Weighted average 0-1
"""
if not weights:
weights = {
"completeness": 0.25,
"relevance": 0.25,
"clarity": 0.25,
"accuracy": 0.25
}
total = (completeness * weights["completeness"]
+ relevance * weights["relevance"]
+ clarity * weights["clarity"]
+ accuracy * weights["accuracy"]
)
return round(total, 3) # e.g. round to 3 decimal places
# -------------------------------------------------------------------------
# Short-Term Methods
# -------------------------------------------------------------------------
def store_short_term(
self,
text: str,
metadata: Dict[str, Any] = None,
completeness: float = None,
relevance: float = None,
clarity: float = None,
accuracy: float = None,
weights: Dict[str, float] = None,
evaluator_quality: float = None
):
"""Store in short-term memory with optional quality metrics"""
logger.info(f"Storing in short-term memory: {text[:100]}...")
logger.info(f"Metadata: {metadata}")
metadata = self._process_quality_metrics(
metadata, completeness, relevance, clarity,
accuracy, weights, evaluator_quality
)
logger.info(f"Processed metadata: {metadata}")
# Existing store logic
try:
conn = sqlite3.connect(self.short_db)
ident = str(time.time_ns())
conn.execute(
"INSERT INTO short_mem (id, content, meta, created_at) VALUES (?,?,?,?)",
(ident, text, json.dumps(metadata), time.time())
)
conn.commit()
conn.close()
logger.info(f"Successfully stored in short-term memory with ID: {ident}")
except Exception as e:
logger.error(f"Failed to store in short-term memory: {e}")
raise
def search_short_term(
self,
query: str,
limit: int = 5,
min_quality: float = 0.0,
relevance_cutoff: float = 0.0
) -> List[Dict[str, Any]]:
"""Search short-term memory with optional quality filter"""
self._log_verbose(f"Searching short memory for: {query}")
if self.use_mem0 and hasattr(self, "mem0_client"):
results = self.mem0_client.search(query=query, limit=limit)
filtered = [r for r in results if r.get("score", 1.0) >= relevance_cutoff]
return filtered
elif self.use_rag and hasattr(self, "chroma_col"):
try:
from openai import OpenAI
client = OpenAI()
response = client.embeddings.create(
input=query,
model="text-embedding-3-small"
)
query_embedding = response.data[0].embedding
resp = self.chroma_col.query(
query_embeddings=[query_embedding],
n_results=limit
)
results = []
if resp["ids"]:
for i in range(len(resp["ids"][0])):
metadata = resp["metadatas"][0][i] if "metadatas" in resp else {}
quality = metadata.get("quality", 0.0)
score = 1.0 - (resp["distances"][0][i] if "distances" in resp else 0.0)
if quality >= min_quality and score >= relevance_cutoff:
results.append({
"id": resp["ids"][0][i],
"text": resp["documents"][0][i],
"metadata": metadata,
"score": score
})
return results
except Exception as e:
self._log_verbose(f"Error searching ChromaDB: {e}", logging.ERROR)
return []
else:
# Local fallback
conn = sqlite3.connect(self.short_db)
c = conn.cursor()
rows = c.execute(
"SELECT id, content, meta FROM short_mem WHERE content LIKE ? LIMIT ?",
(f"%{query}%", limit)
).fetchall()
conn.close()
results = []
for row in rows:
meta = json.loads(row[2] or "{}")
quality = meta.get("quality", 0.0)
if quality >= min_quality:
results.append({
"id": row[0],
"text": row[1],
"metadata": meta
})
return results
def reset_short_term(self):
"""Completely clears short-term memory."""
conn = sqlite3.connect(self.short_db)
conn.execute("DELETE FROM short_mem")
conn.commit()
conn.close()
# -------------------------------------------------------------------------
# Long-Term Methods
# -------------------------------------------------------------------------
def _sanitize_metadata(self, metadata: Dict) -> Dict:
"""Sanitize metadata for ChromaDB - convert to acceptable types"""
sanitized = {}
for k, v in metadata.items():
if v is None:
continue
if isinstance(v, (str, int, float, bool)):
sanitized[k] = v
elif isinstance(v, dict):
# Convert dict to string representation
sanitized[k] = str(v)
else:
# Convert other types to string
sanitized[k] = str(v)
return sanitized
def store_long_term(
self,
text: str,
metadata: Dict[str, Any] = None,
completeness: float = None,
relevance: float = None,
clarity: float = None,
accuracy: float = None,
weights: Dict[str, float] = None,
evaluator_quality: float = None
):
"""Store in long-term memory with optional quality metrics"""
logger.info(f"Storing in long-term memory: {text[:100]}...")
logger.info(f"Initial metadata: {metadata}")
# Process metadata
metadata = metadata or {}
metadata = self._process_quality_metrics(
metadata, completeness, relevance, clarity,
accuracy, weights, evaluator_quality
)
logger.info(f"Processed metadata: {metadata}")
# Generate unique ID
ident = str(time.time_ns())
created = time.time()
# Store in SQLite
try:
conn = sqlite3.connect(self.long_db)
conn.execute(
"INSERT INTO long_mem (id, content, meta, created_at) VALUES (?,?,?,?)",
(ident, text, json.dumps(metadata), created)
)
conn.commit()
conn.close()
logger.info(f"Successfully stored in SQLite with ID: {ident}")
except Exception as e:
logger.error(f"Error storing in SQLite: {e}")
return
# Store in vector database if enabled
if self.use_rag and hasattr(self, "chroma_col"):
try:
from openai import OpenAI
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY")) # Ensure API key is correctly set
logger.info("Getting embeddings from OpenAI...")
logger.debug(f"Embedding input text: {text}") # Log the input text
response = client.embeddings.create(
input=text,
model="text-embedding-3-small"
)
embedding = response.data[0].embedding
logger.info("Successfully got embeddings")
logger.debug(f"Received embedding of length: {len(embedding)}") # Log embedding details
# Sanitize metadata for ChromaDB
sanitized_metadata = self._sanitize_metadata(metadata)
# Store in ChromaDB with embedding
self.chroma_col.add(
documents=[text],
metadatas=[sanitized_metadata],
ids=[ident],
embeddings=[embedding]
)
logger.info(f"Successfully stored in ChromaDB with ID: {ident}")
except Exception as e:
logger.error(f"Error storing in ChromaDB: {e}")
elif self.use_mem0 and hasattr(self, "mem0_client"):
try:
self.mem0_client.add(text, metadata=metadata)
logger.info("Successfully stored in Mem0")
except Exception as e:
logger.error(f"Error storing in Mem0: {e}")
def search_long_term(
self,
query: str,
limit: int = 5,
relevance_cutoff: float = 0.0,
min_quality: float = 0.0
) -> List[Dict[str, Any]]:
"""Search long-term memory with optional quality filter"""
self._log_verbose(f"Searching long memory for: {query}")
self._log_verbose(f"Min quality: {min_quality}")
found = []
if self.use_mem0 and hasattr(self, "mem0_client"):
results = self.mem0_client.search(query=query, limit=limit)
# Filter by quality
filtered = [r for r in results if r.get("metadata", {}).get("quality", 0.0) >= min_quality]
logger.info(f"Found {len(filtered)} results in Mem0")
return filtered
elif self.use_rag and hasattr(self, "chroma_col"):
try:
from openai import OpenAI
client = OpenAI()
# Get query embedding
response = client.embeddings.create(
input=query,
model="text-embedding-3-small" # Using consistent model
)
query_embedding = response.data[0].embedding
# Search ChromaDB with embedding
resp = self.chroma_col.query(
query_embeddings=[query_embedding],
n_results=limit,
include=["documents", "metadatas", "distances"]
)
results = []
if resp["ids"]:
for i in range(len(resp["ids"][0])):
metadata = resp["metadatas"][0][i] if "metadatas" in resp else {}
text = resp["documents"][0][i]
# Add memory record citation
text = f"{text} (Memory record: {text})"
found.append({
"id": resp["ids"][0][i],
"text": text,
"metadata": metadata,
"score": 1.0 - (resp["distances"][0][i] if "distances" in resp else 0.0)
})
logger.info(f"Found {len(found)} results in ChromaDB")
except Exception as e:
self._log_verbose(f"Error searching ChromaDB: {e}", logging.ERROR)
# Always try SQLite as fallback or additional source
conn = sqlite3.connect(self.long_db)
c = conn.cursor()
rows = c.execute(
"SELECT id, content, meta, created_at FROM long_mem WHERE content LIKE ? LIMIT ?",
(f"%{query}%", limit)
).fetchall()
conn.close()
for row in rows:
meta = json.loads(row[2] or "{}")
text = row[1]
# Add memory record citation if not already present
if "(Memory record:" not in text:
text = f"{text} (Memory record: {text})"
# Only add if not already found by ChromaDB/Mem0
if not any(f["id"] == row[0] for f in found):
found.append({
"id": row[0],
"text": text,
"metadata": meta,
"created_at": row[3]
})
logger.info(f"Found {len(found)} total results after SQLite")
results = found
# Filter by quality if needed
if min_quality > 0:
self._log_verbose(f"Found {len(results)} initial results")
results = [
r for r in results
if r.get("metadata", {}).get("quality", 0.0) >= min_quality
]
self._log_verbose(f"After quality filter: {len(results)} results")
# Apply relevance cutoff if specified
if relevance_cutoff > 0:
results = [r for r in results if r.get("score", 1.0) >= relevance_cutoff]
logger.info(f"After relevance filter: {len(results)} results")
return results[:limit]
def reset_long_term(self):
"""Clear local LTM DB, plus Chroma or mem0 if in use."""
conn = sqlite3.connect(self.long_db)
conn.execute("DELETE FROM long_mem")
conn.commit()
conn.close()
if self.use_mem0 and hasattr(self, "mem0_client"):
# Mem0 has no universal reset API. Could implement partial or no-op.
pass
if self.use_rag and hasattr(self, "chroma_client"):
self.chroma_client.reset() # entire DB
self._init_chroma() # re-init fresh
# -------------------------------------------------------------------------
# Entity Memory Methods
# -------------------------------------------------------------------------
def store_entity(self, name: str, type_: str, desc: str, relations: str):
"""
Save entity info in LTM (or mem0/rag).
We'll label the metadata type = entity for easy filtering.
"""
data = f"Entity {name}({type_}): {desc} | relationships: {relations}"
self.store_long_term(data, metadata={"category": "entity"})
def search_entity(self, query: str, limit: int = 5) -> List[Dict[str, Any]]:
"""
Filter to items that have metadata 'category=entity'.
"""
all_hits = self.search_long_term(query, limit=20) # gather more
ents = []
for h in all_hits:
meta = h.get("metadata") or {}
if meta.get("category") == "entity":
ents.append(h)
return ents[:limit]
def reset_entity_only(self):
"""
If you only want to drop entity items from LTM, you'd do a custom
delete from local DB where meta LIKE '%category=entity%'.
For brevity, we do a full LTM reset here.
"""
self.reset_long_term()
# -------------------------------------------------------------------------
# User Memory Methods
# -------------------------------------------------------------------------
def store_user_memory(self, user_id: str, text: str, extra: Dict[str, Any] = None):
"""
If mem0 is used, do user-based addition. Otherwise store in LTM with user in metadata.
"""
meta = {"user_id": user_id}
if extra:
meta.update(extra)
if self.use_mem0 and hasattr(self, "mem0_client"):
self.mem0_client.add(text, user_id=user_id, metadata=meta)
else:
self.store_long_term(text, metadata=meta)
def search_user_memory(self, user_id: str, query: str, limit: int = 5) -> List[Dict[str, Any]]:
"""
If mem0 is used, pass user_id in. Otherwise fallback to local filter on user in metadata.
"""
if self.use_mem0 and hasattr(self, "mem0_client"):
return self.mem0_client.search(query=query, limit=limit, user_id=user_id)
else:
hits = self.search_long_term(query, limit=20)
filtered = []
for h in hits:
meta = h.get("metadata", {})
if meta.get("user_id") == user_id:
filtered.append(h)
return filtered[:limit]
def reset_user_memory(self):
"""
Clear all user-based info. For simplicity, we do a full LTM reset.
Real usage might filter only metadata "user_id".
"""
self.reset_long_term()
# -------------------------------------------------------------------------
# Putting it all Together: Task Finalization
# -------------------------------------------------------------------------
def finalize_task_output(
self,
content: str,
agent_name: str,
quality_score: float,
threshold: float = 0.7,
metrics: Dict[str, Any] = None,
task_id: str = None
):
"""Store task output in memory with appropriate metadata"""
logger.info(f"Finalizing task output: {content[:100]}...")
logger.info(f"Agent: {agent_name}, Quality: {quality_score}, Threshold: {threshold}")
metadata = {
"task_id": task_id,
"agent": agent_name,
"quality": quality_score,
"metrics": metrics,
"task_type": "output",
"stored_at": time.time()
}
logger.info(f"Prepared metadata: {metadata}")
# Always store in short-term memory
try:
logger.info("Storing in short-term memory...")
self.store_short_term(
text=content,
metadata=metadata
)
logger.info("Successfully stored in short-term memory")
except Exception as e:
logger.error(f"Failed to store in short-term memory: {e}")
# Store in long-term memory if quality meets threshold
if quality_score >= threshold:
try:
logger.info(f"Quality score {quality_score} >= {threshold}, storing in long-term memory...")
self.store_long_term(
text=content,
metadata=metadata
)
logger.info("Successfully stored in long-term memory")
except Exception as e:
logger.error(f"Failed to store in long-term memory: {e}")
else:
logger.info(f"Quality score {quality_score} < {threshold}, skipping long-term storage")
# -------------------------------------------------------------------------
# Building Context (Short, Long, Entities, User)
# -------------------------------------------------------------------------
def build_context_for_task(
self,
task_descr: str,
user_id: Optional[str] = None,
additional: str = "",
max_items: int = 3
) -> str:
"""
Merges relevant short-term, long-term, entity, user memories
into a single text block with deduplication and clean formatting.
"""
q = (task_descr + " " + additional).strip()
lines = []
seen_contents = set() # Track unique contents
def normalize_content(content: str) -> str:
"""Normalize content for deduplication"""
# Extract just the main content without citations for comparison
normalized = content.split("(Memory record:")[0].strip()
# Keep more characters to reduce false duplicates
normalized = ''.join(c.lower() for c in normalized if not c.isspace())
return normalized
def format_content(content: str, max_len: int = 150) -> str:
"""Format content with clean truncation at word boundaries"""
if not content:
return ""
# Clean up content by removing extra whitespace and newlines
content = ' '.join(content.split())
# If content contains a memory citation, preserve it
if "(Memory record:" in content:
return content # Keep original citation format
# Regular content truncation
if len(content) <= max_len:
return content
truncate_at = content.rfind(' ', 0, max_len - 3)
if truncate_at == -1:
truncate_at = max_len - 3
return content[:truncate_at] + "..."
def add_section(title: str, hits: List[Any]) -> None:
"""Add a section of memory hits with deduplication"""
if not hits:
return
formatted_hits = []
for h in hits:
content = h.get('text', '') if isinstance(h, dict) else str(h)
if not content:
continue
# Keep original format if it has a citation
if "(Memory record:" in content:
formatted = content
else:
formatted = format_content(content)
# Only add if we haven't seen this normalized content before
normalized = normalize_content(formatted)
if normalized not in seen_contents:
seen_contents.add(normalized)
formatted_hits.append(formatted)
if formatted_hits:
# Add section header
if lines:
lines.append("") # Space before new section
lines.append(title)
lines.append("=" * len(title)) # Underline the title
lines.append("") # Space after title
# Add formatted content with bullet points
for content in formatted_hits:
lines.append(f" • {content}")
# Add each section
# First get all results
short_term = self.search_short_term(q, limit=max_items)
long_term = self.search_long_term(q, limit=max_items)
entities = self.search_entity(q, limit=max_items)
user_mem = self.search_user_memory(user_id, q, limit=max_items) if user_id else []
# Add sections in order of priority
add_section("Short-term Memory Context", short_term)
add_section("Long-term Memory Context", long_term)
add_section("Entity Context", entities)
if user_id:
add_section("User Context", user_mem)
return "\n".join(lines) if lines else ""
# -------------------------------------------------------------------------
# Master Reset (Everything)
# -------------------------------------------------------------------------
def reset_all(self):
"""
Fully wipes short-term, long-term, and any memory in mem0 or rag.
"""
self.reset_short_term()
self.reset_long_term()
# Entities & user memory are stored in LTM or mem0, so no separate step needed.
def _process_quality_metrics(
self,
metadata: Dict[str, Any],
completeness: float = None,
relevance: float = None,
clarity: float = None,
accuracy: float = None,
weights: Dict[str, float] = None,
evaluator_quality: float = None
) -> Dict[str, Any]:
"""Process and store quality metrics in metadata"""
metadata = metadata or {}
# Handle sub-metrics if provided
if None not in [completeness, relevance, clarity, accuracy]:
metadata.update({
"completeness": completeness,
"relevance": relevance,
"clarity": clarity,
"accuracy": accuracy,
"quality": self.compute_quality_score(
completeness, relevance, clarity, accuracy, weights
)
})
# Handle external evaluator quality if provided
elif evaluator_quality is not None:
metadata["quality"] = evaluator_quality
return metadata
def calculate_quality_metrics(
self,
output: str,
expected_output: str,
llm: Optional[str] = None,
custom_prompt: Optional[str] = None
) -> Dict[str, float]:
"""Calculate quality metrics using LLM"""
logger.info("Calculating quality metrics for output")
logger.info(f"Output: {output[:100]}...")
logger.info(f"Expected: {expected_output[:100]}...")
# Default evaluation prompt
default_prompt = f"""
Evaluate the following output against expected output.
Score each metric from 0.0 to 1.0:
- Completeness: Does it address all requirements?
- Relevance: Does it match expected output?
- Clarity: Is it clear and well-structured?
- Accuracy: Is it factually correct?
Expected: {expected_output}
Actual: {output}
Return ONLY a JSON with these keys: completeness, relevance, clarity, accuracy
Example: {{"completeness": 0.95, "relevance": 0.8, "clarity": 0.9, "accuracy": 0.85}}
"""
try:
# Use OpenAI client from main.py
from ..main import client
response = client.chat.completions.create(
model=llm or "gpt-4o",
messages=[{
"role": "user",
"content": custom_prompt or default_prompt
}],
response_format={"type": "json_object"},
temperature=0.3
)
metrics = json.loads(response.choices[0].message.content)
# Validate metrics
required = ["completeness", "relevance", "clarity", "accuracy"]
if not all(k in metrics for k in required):
raise ValueError("Missing required metrics in LLM response")
logger.info(f"Calculated metrics: {metrics}")
return metrics
except Exception as e:
logger.error(f"Error calculating metrics: {e}")
return {
"completeness": 0.0,
"relevance": 0.0,
"clarity": 0.0,
"accuracy": 0.0
}
def store_quality(
self,
text: str,
quality_score: float,
task_id: Optional[str] = None,
iteration: Optional[int] = None,
metrics: Optional[Dict[str, float]] = None,
memory_type: Literal["short", "long"] = "long"
) -> None:
"""Store quality metrics in memory"""
logger.info(f"Attempting to store in {memory_type} memory: {text[:100]}...")
metadata = {
"quality": quality_score,
"task_id": task_id,
"iteration": iteration
}
if metrics:
metadata.update({
k: v for k, v in metrics.items() # Remove metric_ prefix
})
logger.info(f"With metadata: {metadata}")
try:
if memory_type == "short":
self.store_short_term(text, metadata=metadata)
logger.info("Successfully stored in short-term memory")
else:
self.store_long_term(text, metadata=metadata)
logger.info("Successfully stored in long-term memory")
except Exception as e:
logger.error(f"Failed to store in memory: {e}")
def search_with_quality(
self,
query: str,
min_quality: float = 0.0,
memory_type: Literal["short", "long"] = "long",
limit: int = 5
) -> List[Dict[str, Any]]:
"""Search with quality filter"""
logger.info(f"Searching {memory_type} memory for: {query}")
logger.info(f"Min quality: {min_quality}")
search_func = (
self.search_short_term if memory_type == "short"
else self.search_long_term
)
results = search_func(query, limit=limit)
logger.info(f"Found {len(results)} initial results")
filtered = [
r for r in results
if r.get("metadata", {}).get("quality", 0.0) >= min_quality
]
logger.info(f"After quality filter: {len(filtered)} results")
return filtered
+50 -15
View File
@@ -10,14 +10,16 @@ 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 +43,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}")
@@ -111,6 +118,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 +142,28 @@ 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()
# 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() in result:
# 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": # If empty or explicit 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 +303,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:
@@ -308,7 +327,12 @@ Provide a JSON with the structure:
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}")
@@ -372,6 +396,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}"
@@ -391,22 +420,28 @@ 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()
# 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() in result:
# 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": # If empty or explicit 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:
+157 -9
View File
@@ -5,12 +5,17 @@ from pydantic import BaseModel
from ..main import TaskOutput
from ..agent.agent import Agent
import uuid
import os
import time
# Set up logger
logger = logging.getLogger(__name__)
class Task:
def __init__(
self,
description: str,
expected_output: str,
expected_output: Optional[str] = None,
agent: Optional[Agent] = None,
name: Optional[str] = None,
tools: Optional[List[Any]] = None,
@@ -30,12 +35,14 @@ class Task:
task_type: str = "task",
condition: Optional[Dict[str, List[str]]] = None,
is_start: bool = False,
loop_state: Optional[Dict[str, Union[str, int]]] = None
loop_state: Optional[Dict[str, Union[str, int]]] = None,
memory=None,
quality_check=True
):
self.id = str(uuid.uuid4()) if id is None else str(id)
self.name = name
self.description = description
self.expected_output = expected_output
self.expected_output = expected_output if expected_output is not None else "Complete the task successfully"
self.agent = agent
self.tools = tools if tools else []
self.context = context if context else []
@@ -54,6 +61,21 @@ class Task:
self.condition = condition if condition else {}
self.is_start = is_start
self.loop_state = loop_state if loop_state else {}
self.memory = memory
self.quality_check = quality_check
# Set logger level based on config verbose level
verbose = self.config.get("verbose", 0)
if verbose >= 5:
logger.setLevel(logging.INFO)
else:
logger.setLevel(logging.WARNING)
# Also set third-party loggers to WARNING
logging.getLogger('chromadb').setLevel(logging.WARNING)
logging.getLogger('openai').setLevel(logging.WARNING)
logging.getLogger('httpx').setLevel(logging.WARNING)
logging.getLogger('httpcore').setLevel(logging.WARNING)
if self.output_json and self.output_pydantic:
raise ValueError("Only one output type can be defined")
@@ -64,11 +86,137 @@ class Task:
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}')"
def initialize_memory(self):
"""Initialize memory if config exists but memory doesn't"""
if not self.memory and self.config.get('memory_config'):
try:
from ..memory.memory import Memory
logger.info(f"Task {self.id}: Initializing memory from config: {self.config['memory_config']}")
self.memory = Memory(config=self.config['memory_config'])
logger.info(f"Task {self.id}: Memory initialized successfully")
# Verify database was created
if os.path.exists(self.config['memory_config']['storage']['path']):
logger.info(f"Task {self.id}: Memory database exists after initialization")
else:
logger.error(f"Task {self.id}: Failed to create memory database!")
return self.memory
except Exception as e:
logger.error(f"Task {self.id}: Failed to initialize memory: {e}")
logger.exception(e)
return None
def store_in_memory(self, content: str, agent_name: str = None, task_id: str = None):
"""Store content in memory with metadata"""
if self.memory:
try:
logger.info(f"Task {self.id}: Storing content in memory...")
self.memory.store_long_term(
text=content,
metadata={
"agent_name": agent_name or "Agent",
"task_id": task_id or self.id,
"timestamp": time.time()
}
)
logger.info(f"Task {self.id}: Content stored in memory")
except Exception as e:
logger.error(f"Task {self.id}: Failed to store content in memory: {e}")
logger.exception(e)
async def execute_callback(self, task_output: TaskOutput) -> None:
"""Execute the callback function, handling both sync and async callbacks"""
"""Execute callback and store quality metrics if enabled"""
logger.info(f"Task {self.id}: execute_callback called")
logger.info(f"Quality check enabled: {self.quality_check}")
# Initialize memory if not already initialized
if not self.memory:
self.memory = self.initialize_memory()
logger.info(f"Memory object exists: {self.memory is not None}")
if self.memory:
logger.info(f"Memory config: {self.memory.cfg}")
# Store task output in memory
try:
logger.info(f"Task {self.id}: Storing task output in memory...")
self.store_in_memory(
content=task_output.raw,
agent_name=self.agent.name if self.agent else "Agent",
task_id=self.id
)
logger.info(f"Task {self.id}: Task output stored in memory")
except Exception as e:
logger.error(f"Task {self.id}: Failed to store task output in memory: {e}")
logger.exception(e)
logger.info(f"Task output: {task_output.raw[:100]}...")
if self.quality_check and self.memory:
try:
logger.info(f"Task {self.id}: Starting memory operations")
logger.info(f"Task {self.id}: Calculating quality metrics for output: {task_output.raw[:100]}...")
# Get quality metrics from LLM
metrics = self.memory.calculate_quality_metrics(
task_output.raw,
self.expected_output
)
logger.info(f"Task {self.id}: Quality metrics calculated: {metrics}")
quality_score = metrics.get("accuracy", 0.0)
logger.info(f"Task {self.id}: Quality score: {quality_score}")
# Store in both short and long-term memory with higher threshold
logger.info(f"Task {self.id}: Finalizing task output in memory...")
self.memory.finalize_task_output(
content=task_output.raw,
agent_name=self.agent.name if self.agent else "Agent",
quality_score=quality_score,
threshold=0.7, # Only high quality outputs in long-term memory
metrics=metrics,
task_id=self.id
)
logger.info(f"Task {self.id}: Finalized task output in memory")
# Store quality metrics separately
logger.info(f"Task {self.id}: Storing quality metrics...")
self.memory.store_quality(
text=task_output.raw,
quality_score=quality_score,
task_id=self.id,
metrics=metrics
)
# Store in both short and long-term memory with higher threshold
self.memory.finalize_task_output(
content=task_output.raw,
agent_name=self.agent.name if self.agent else "Agent",
quality_score=quality_score,
threshold=0.7 # Only high quality outputs in long-term memory
)
# Build context for next tasks
if self.next_tasks:
logger.info(f"Task {self.id}: Building context for next tasks...")
context = self.memory.build_context_for_task(
task_descr=task_output.raw,
max_items=5
)
logger.info(f"Task {self.id}: Built context for next tasks: {len(context)} items")
logger.info(f"Task {self.id}: Memory operations complete")
except Exception as e:
logger.error(f"Task {self.id}: Failed to process memory operations: {e}")
logger.exception(e) # Print full stack trace
# Continue execution even if memory operations fail
# Execute original callback
if self.callback:
if asyncio.iscoroutinefunction(self.callback):
await self.callback(task_output)
else:
loop = asyncio.get_event_loop()
await loop.run_in_executor(None, self.callback, task_output)
try:
if asyncio.iscoroutinefunction(self.callback):
await self.callback(task_output)
else:
self.callback(task_output)
except Exception as e:
logger.error(f"Task {self.id}: Failed to execute callback: {e}")
logger.exception(e)
@@ -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)
+19
View File
@@ -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"
)
+91
View File
@@ -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()
+78
View File
@@ -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}")
+6 -1
View File
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
[project]
name = "praisonaiagents"
version = "0.0.26"
version = "0.0.36"
description = "Praison AI agents for completing complex tasks with Self Reflection Agents"
authors = [
{ name="Mervin Praison" }
@@ -13,4 +13,9 @@ dependencies = [
"pydantic",
"rich",
"openai"
]
[project.optional-dependencies]
memory = [
"chromadb>=0.6.0"
]
+5
View File
@@ -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")
+5
View File
@@ -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")
+82
View File
@@ -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)
+83
View File
@@ -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)
+5
View File
@@ -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")
+4
View File
@@ -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")
+95
View File
@@ -0,0 +1,95 @@
from praisonaiagents import Agent
from pydantic import BaseModel
from typing import List, Optional
# Define structured output models
class SearchResult(BaseModel):
title: str
url: Optional[str]
snippet: str
class AnalysisReport(BaseModel):
topic: str
key_findings: List[str]
search_results: List[SearchResult]
summary: str
confidence_score: float
def get_structured_analysis(query: str, verbose: bool = True) -> AnalysisReport:
"""
Performs a search and returns a structured analysis using an AI agent.
Args:
query (str): The search query or topic to analyze
verbose (bool): Whether to show detailed output
Returns:
AnalysisReport: A structured report containing the analysis
"""
# Create an agent with search capabilities
agent = Agent(
name="StructuredAnalyst",
role="Research Analyst",
goal="Analyze topics and provide structured reports",
backstory="Expert at gathering information and providing structured analysis",
verbose=verbose,
self_reflect=True, # Enable self-reflection for better quality
markdown=True,
llm="gpt-4o-mini"
)
# Create the analysis prompt
prompt = f"""
Analyze the following topic: "{query}"
Provide a structured analysis in JSON format that matches this schema:
{{
"topic": "string",
"key_findings": ["string"],
"search_results": [
{{
"title": "string",
"url": "string",
"snippet": "string"
}}
],
"summary": "string",
"confidence_score": float (0-1)
}}
Requirements:
1. Include at least 3 key findings
2. Include at least 2 relevant search results
3. Provide a comprehensive summary
4. Set confidence score based on quality of sources (0-1)
Return ONLY the JSON object, no other text.
"""
# Get structured response from agent
response = agent.chat(
prompt=prompt,
output_json=AnalysisReport # This ensures response matches our model
)
return AnalysisReport.model_validate_json(response)
if __name__ == "__main__":
# Example usage
analysis = get_structured_analysis("Latest developments in AI agents and autonomous systems")
print(analysis)
# Print the structured results
print("\n=== Structured Analysis Report ===")
print(f"Topic: {analysis.topic}")
print("\nKey Findings:")
for i, finding in enumerate(analysis.key_findings, 1):
print(f"{i}. {finding}")
print("\nSearch Results:")
for result in analysis.search_results:
print(f"\nTitle: {result.title}")
print(f"URL: {result.url}")
print(f"Snippet: {result.snippet}")
print(f"\nSummary: {analysis.summary}")
print(f"Confidence Score: {analysis.confidence_score:.2f}")
+758
View File
@@ -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"
1 date close volume open high low
2 11:34 270.49 4,787,699 264.50 273.88 262.24
3 2018/10/15 259.5900 6189026.0000 259.0600 263.2800 254.5367
4 2018/10/12 258.7800 7189257.0000 261.0000 261.9900 252.0100
5 2018/10/11 252.2300 8128184.0000 257.5300 262.2500 249.0300
6 2018/10/10 256.8800 12781560.0000 264.6100 265.5100 247.7700
7 2018/10/09 262.8000 12037780.0000 255.2500 266.7700 253.3000
8 2018/10/08 250.5600 13371180.0000 264.5200 267.7599 249.0000
9 2018/10/05 261.9500 17900710.0000 274.6500 274.8800 260.0000
10 2018/10/04 281.8300 9638885.0000 293.9500 294.0000 277.6700
11 2018/10/03 294.8000 7982272.0000 303.3300 304.6000 291.5700
12 2018/10/02 301.0200 11699690.0000 313.9500 316.8400 299.1500
13 2018/10/01 310.7000 21714210.0000 305.7700 311.4400 301.0500
14 2018/09/28 264.7700 33597290.0000 270.2600 278.0000 260.5550
15 2018/09/27 307.5200 7337760.0000 312.9000 314.9600 306.9100
16 2018/09/26 309.5800 7835863.0000 301.9100 313.8900 301.1093
17 2018/09/25 300.9900 4472287.0000 300.0000 304.6000 296.5000
18 2018/09/24 299.6800 4834384.0000 298.4800 302.9993 293.5800
19 2018/09/21 299.1000 5038497.0000 297.7000 300.5800 295.3700
20 2018/09/20 298.3300 7332477.0000 303.5600 305.9800 293.3300
21 2018/09/19 299.0200 8264353.0000 280.5100 300.0000 280.5000
22 2018/09/18 284.9600 16494280.0000 296.6900 302.6400 275.5000
23 2018/09/17 294.8400 6866208.0000 290.0400 300.8700 288.1300
24 2018/09/14 295.2000 6757652.0000 288.7600 297.3256 286.5200
25 2018/09/13 289.4600 6333281.0000 288.0200 295.0000 285.1800
26 2018/09/12 290.5400 10002150.0000 281.4400 292.5000 278.6463
27 2018/09/11 279.4400 9161061.0000 279.4700 282.0000 273.5500
28 2018/09/10 285.5000 14232250.0000 273.2600 286.0300 271.0000
29 2018/09/07 263.2400 22442310.0000 260.1000 268.3500 252.2548
30 2018/09/06 280.9500 7472756.0000 284.8000 291.1700 278.8800
31 2018/09/05 280.7400 7707342.0000 285.0500 286.7800 277.1800
32 2018/09/04 288.9500 8304571.0000 296.9400 298.1900 288.0000
33 2018/08/31 301.6600 5367048.0000 302.0000 305.3082 298.6000
34 2018/08/30 303.1500 7210625.0000 302.2600 304.6000 297.7200
35 2018/08/29 305.0100 7410538.0000 310.2700 311.8500 303.6900
36 2018/08/28 311.8600 7639453.0000 318.4100 318.8800 311.1900
37 2018/08/27 319.2700 13062650.0000 318.0000 322.4350 308.8100
38 2018/08/24 322.8200 3592734.0000 320.7000 323.8500 319.4000
39 2018/08/23 320.1000 5138685.0000 319.1400 327.3200 318.1000
40 2018/08/22 321.6400 5935853.0000 320.8700 323.8800 314.6700
41 2018/08/21 321.9000 13147770.0000 310.6100 324.7900 309.0000
42 2018/08/20 308.4400 17380430.0000 291.7040 308.5000 288.2000
43 2018/08/17 305.5000 18895880.0000 323.5000 326.7700 303.5300
44 2018/08/16 335.4500 6045392.0000 339.9100 342.2800 333.8200
45 2018/08/15 338.6900 9073033.0000 341.9060 344.4900 332.1400
46 2018/08/14 347.6400 6948511.0000 358.4500 359.1995 347.1000
47 2018/08/13 356.4100 10444920.0000 361.1300 363.1900 349.0200
48 2018/08/10 355.4900 11530510.0000 354.0000 360.0000 346.0000
49 2018/08/09 352.4500 16951800.0000 365.5500 367.0100 345.7300
50 2018/08/08 370.3400 24535420.0000 369.0900 382.6400 367.1200
51 2018/08/07 379.5700 30596400.0000 343.8400 387.4600 339.1501
52 2018/08/06 341.9900 8536766.0000 345.4600 354.9800 341.8200
53 2018/08/03 348.1700 13646640.0000 347.8100 355.0000 342.5300
54 2018/08/02 349.5400 23159160.0000 328.4400 349.9900 323.1600
55 2018/08/01 300.8400 8768099.0000 297.9900 303.0000 293.0000
56 2018/07/31 298.1400 5055094.0000 292.2500 298.3200 289.0700
57 2018/07/30 290.1700 6799581.0000 295.9000 296.1000 286.1300
58 2018/07/27 297.1800 5694690.0000 307.2500 307.6933 295.3404
59 2018/07/26 306.6500 4619567.0000 304.8500 310.7000 303.6411
60 2018/07/25 308.7400 7031382.0000 296.7400 309.6200 294.5025
61 2018/07/24 297.4300 9586186.0000 304.4209 307.7171 292.5452
62 2018/07/23 303.2000 10974820.0000 301.8400 305.5000 292.8601
63 2018/07/20 313.5800 5159831.0000 321.2300 323.2400 311.7093
64 2018/07/19 320.2300 5907116.0000 316.3300 323.5400 314.0100
65 2018/07/18 323.8500 5610085.0000 325.0000 325.5000 316.2500
66 2018/07/17 322.6900 6987782.0000 308.8100 324.7400 308.5000
67 2018/07/16 310.1000 7800454.0000 311.7100 315.1600 306.2500
68 2018/07/13 318.8700 5866776.0000 315.5800 319.5849 309.2500
69 2018/07/12 316.7100 5711851.0000 321.4300 323.2300 312.7700
70 2018/07/11 318.9600 4878595.0000 315.8000 321.9400 315.0700
71 2018/07/10 322.4700 9437557.0000 324.5600 327.6771 319.2000
72 2018/07/09 318.5100 7579541.0000 311.9900 318.5200 308.0000
73 2018/07/06 308.9000 8860198.0000 304.9550 312.0700 302.0000
74 2018/07/05 309.1600 17457570.0000 313.7600 314.3900 296.2200
75 2018/07/03 310.8600 12282640.0000 331.7500 332.4900 309.6900
76 2018/07/02 335.0700 18732710.0000 360.0700 364.7800 329.8500
77 2018/06/29 342.9500 6475903.0000 353.3300 353.8600 342.4100
78 2018/06/28 349.9300 8388172.0000 348.6600 357.0200 346.1100
79 2018/06/27 344.5000 8313817.0000 345.0000 350.7900 339.5000
80 2018/06/26 342.0000 7434749.0000 336.0540 343.5500 325.7990
81 2018/06/25 333.0100 6925089.0000 330.1200 338.4700 327.5000
82 2018/06/22 333.6300 10253770.0000 351.5400 352.2500 332.0000
83 2018/06/21 347.5100 7949846.0000 362.0000 366.2139 346.2700
84 2018/06/20 362.2200 8370268.0000 358.0400 364.3800 352.0000
85 2018/06/19 352.5500 12734840.0000 365.1600 370.0000 346.2500
86 2018/06/18 370.8300 12025450.0000 355.4000 373.7300 354.5000
87 2018/06/15 358.1700 10827560.0000 353.8400 364.6700 351.2500
88 2018/06/14 357.7200 10961150.0000 347.6300 358.7500 346.6000
89 2018/06/13 344.7800 9401467.0000 346.7060 347.2000 339.8000
90 2018/06/12 342.7700 22256430.0000 344.7000 354.9700 338.0000
91 2018/06/11 332.1000 13166050.0000 322.5100 334.6600 322.5000
92 2018/06/08 317.6600 8192175.0000 319.0000 324.4800 317.1500
93 2018/06/07 316.0900 14336110.0000 316.1500 330.0000 313.5800
94 2018/06/06 319.5000 18742400.0000 300.5000 322.1700 297.4800
95 2018/06/05 291.1300 5877873.0000 297.7000 297.8000 286.7400
96 2018/06/04 296.7400 4793787.0000 294.3400 299.0000 293.5480
97 2018/06/01 291.8200 5417984.0000 285.8600 291.9500 283.8390
98 2018/05/31 284.7300 5912825.0000 287.2100 290.3700 282.9300
99 2018/05/30 291.7200 7473590.0000 283.2900 295.0050 281.6000
100 2018/05/29 283.7600 5657153.0000 278.5100 286.5000 276.1500
101 2018/05/25 278.8500 3872621.0000 277.6250 279.6400 275.6100
102 2018/05/24 277.8500 4170789.0000 278.4000 281.1100 274.8900
103 2018/05/23 279.0700 5972237.0000 277.7600 279.9099 274.0000
104 2018/05/22 275.0100 8938501.0000 287.7620 288.0000 273.4220
105 2018/05/21 284.4900 9167844.0000 281.3300 291.4900 281.3000
106 2018/05/18 276.8200 7243699.0000 284.6500 284.6500 274.0000
107 2018/05/17 284.5400 4418258.0000 285.9000 289.1873 283.9700
108 2018/05/16 286.4800 5669644.0000 283.8300 288.8100 281.5600
109 2018/05/15 284.1800 9509753.0000 285.0100 286.9600 280.5000
110 2018/05/14 291.9700 7265501.0000 303.3200 304.9400 291.6200
111 2018/05/11 301.0600 4665321.0000 307.7000 308.8800 299.0800
112 2018/05/10 305.0200 5642771.0000 307.4997 312.9900 304.1119
113 2018/05/09 306.8500 5712255.0000 300.4100 307.0100 300.0500
114 2018/05/08 301.9700 5927447.0000 300.7950 307.7500 299.0000
115 2018/05/07 302.7700 8673090.0000 297.5000 305.9588 295.1700
116 2018/05/04 294.0900 8565506.0000 283.0000 296.8600 279.5200
117 2018/05/03 284.4500 17339090.0000 278.7900 288.0400 275.2300
118 2018/05/02 301.1500 8346176.0000 298.5700 306.8500 297.7844
119 2018/05/01 299.9200 4614946.0000 293.5100 300.8200 293.2200
120 2018/04/30 293.9000 4224068.0000 293.6100 298.7300 292.5000
121 2018/04/27 294.0750 4346854.0000 285.3700 294.4700 283.8300
122 2018/04/26 285.4800 4348108.0000 278.7500 285.7900 276.5000
123 2018/04/25 280.6900 4000421.0000 283.5000 285.1600 277.2500
124 2018/04/24 283.4600 5678242.0000 285.0000 287.0900 278.4600
125 2018/04/23 283.3700 4880743.0000 291.2900 291.6200 282.3300
126 2018/04/20 290.2400 5622630.0000 295.1700 299.9800 289.7500
127 2018/04/19 300.0800 6083800.0000 291.0800 301.0100 288.5500
128 2018/04/18 293.3500 6531563.0000 291.0800 300.2400 288.1600
129 2018/04/17 287.6900 6931152.0000 288.8700 292.1700 282.5100
130 2018/04/16 291.2100 6289497.0000 299.0000 299.6600 289.0100
131 2018/04/13 300.3400 7319225.0000 303.6000 303.9499 295.9800
132 2018/04/12 294.0800 7595525.0000 302.3200 303.9500 293.6800
133 2018/04/11 300.9300 7470204.0000 300.7400 308.9800 299.6600
134 2018/04/10 304.7000 11017010.0000 298.9700 307.1000 293.6800
135 2018/04/09 289.6600 10241410.0000 300.3700 309.5000 289.2100
136 2018/04/06 299.3000 13516530.0000 301.0000 309.2800 295.5000
137 2018/04/05 305.7200 19025860.0000 289.3400 306.2600 288.2000
138 2018/04/04 286.9400 19880180.0000 252.7800 288.3700 252.0000
139 2018/04/03 267.5300 18829650.0000 269.8200 273.3500 254.4900
140 2018/04/02 252.4800 16093290.0000 256.2600 260.3318 244.5901
141 2018/03/29 266.1300 15014440.0000 256.4900 270.9599 248.2100
142 2018/03/28 257.7800 20962280.0000 264.5800 268.6800 252.1000
143 2018/03/27 279.1800 13787060.0000 304.0000 304.2700 277.1800
144 2018/03/26 304.1800 8364937.0000 307.3400 307.5900 291.3600
145 2018/03/23 301.5400 6639960.0000 311.2500 311.6100 300.4500
146 2018/03/22 309.1000 4924928.0000 313.8900 318.8200 308.1800
147 2018/03/21 316.5300 5954247.0000 310.2500 322.4400 310.1900
148 2018/03/20 310.5500 4761031.0000 314.8700 316.2500 308.7600
149 2018/03/19 313.5600 7467890.0000 316.5000 320.7500 309.6700
150 2018/03/16 321.3500 6113365.0000 325.9600 327.4000 319.0700
151 2018/03/15 325.6000 6554568.0000 329.3800 332.8500 321.1000
152 2018/03/14 326.6300 7952152.0000 336.7600 339.8100 323.9300
153 2018/03/13 341.8400 5960636.0000 344.9200 345.1200 336.2635
154 2018/03/12 345.5100 8252919.0000 328.6100 347.2100 326.5000
155 2018/03/09 327.1700 5502779.0000 324.1000 328.4900 322.3700
156 2018/03/08 329.1000 3514367.0000 332.8600 333.3000 326.2740
157 2018/03/07 332.3000 5001940.0000 325.4400 332.5000 321.7400
158 2018/03/06 328.2000 4236483.0000 333.7500 336.3700 327.0300
159 2018/03/05 333.3500 3820702.0000 332.3900 337.7500 329.2929
160 2018/03/02 335.1200 5088789.0000 326.9800 335.2200 322.9700
161 2018/03/01 330.9300 6872552.0000 345.0100 348.6700 330.0700
162 2018/02/28 343.0600 6066044.0000 352.5700 355.2400 342.2200
163 2018/02/27 350.9900 4785022.0000 356.2500 359.9900 350.0100
164 2018/02/26 357.4200 4334500.0000 353.5000 359.0000 352.3550
165 2018/02/23 352.0500 5814177.0000 347.8300 354.9900 347.1000
166 2018/02/22 346.1700 6961880.0000 335.5300 347.4400 334.7501
167 2018/02/21 333.3000 3207250.0000 336.0300 339.6929 333.1700
168 2018/02/20 334.7700 4005962.0000 334.4700 340.8400 331.5000
169 2018/02/16 335.4900 5640184.0000 332.5000 343.1200 331.6400
170 2018/02/15 334.0650 5909823.0000 324.5000 334.1200 322.4000
171 2018/02/14 322.3100 3948077.0000 320.8400 326.1700 318.5200
172 2018/02/13 323.6600 4554631.0000 315.0200 324.1900 312.5105
173 2018/02/12 315.7300 6224479.0000 316.1300 318.0800 306.2500
174 2018/02/09 310.4200 12924430.0000 319.9300 320.9845 294.7600
175 2018/02/08 315.2300 10296420.0000 343.3100 348.6200 314.6000
176 2018/02/07 345.0000 6729682.0000 338.9900 346.0000 335.6600
177 2018/02/06 333.9700 5080032.0000 325.2100 336.2200 323.5000
178 2018/02/05 333.1300 4441166.0000 337.9700 344.4700 333.0000
179 2018/02/02 343.7500 3696157.0000 348.4400 351.9500 340.5100
180 2018/02/01 349.2500 4187440.0000 351.0000 359.6600 348.6300
181 2018/01/31 354.3100 6199373.0000 347.5100 356.1900 345.1900
182 2018/01/30 345.8200 4710684.0000 345.1400 348.2700 342.1700
183 2018/01/29 349.5300 4738208.0000 339.8500 350.8500 338.2800
184 2018/01/26 342.8500 4535457.0000 341.5000 344.0000 335.7100
185 2018/01/25 337.6400 6725208.0000 348.2700 349.2000 336.4000
186 2018/01/24 345.8900 5277386.0000 354.5800 354.7500 343.5200
187 2018/01/23 352.7900 5447622.0000 360.0000 360.5000 351.0000
188 2018/01/22 351.5600 6199777.0000 349.4000 357.8300 349.2000
189 2018/01/19 350.0200 4871181.0000 345.0000 350.5899 342.6000
190 2018/01/18 344.5700 5679629.0000 345.6700 352.3000 343.7400
191 2018/01/17 347.1600 7092554.0000 340.4700 349.0000 339.7500
192 2018/01/16 340.0600 6429234.0000 337.5400 345.0000 334.8000
193 2018/01/12 336.2200 4822509.0000 338.6300 340.4100 333.6700
194 2018/01/11 337.9500 6640863.0000 335.2400 344.8099 333.2600
195 2018/01/10 334.8000 4303053.0000 332.2000 337.0000 330.0000
196 2018/01/09 333.6900 7134525.0000 335.1600 338.8000 327.4050
197 2018/01/08 336.4100 9832610.0000 316.0000 337.0199 315.5000
198 2018/01/05 316.5800 4588728.0000 316.6200 317.2400 312.0000
199 2018/01/04 314.6200 9944593.0000 312.8700 318.5500 305.6800
200 2018/01/03 317.2500 4438520.0000 321.0000 325.2500 315.5500
201 2018/01/02 320.5300 4345615.0000 312.0000 322.1099 311.0000
202 2017/12/29 311.3500 3769504.0000 316.1800 316.4100 310.0000
203 2017/12/28 315.3600 4306746.0000 311.7500 315.8200 309.5400
204 2017/12/27 311.6400 4705084.0000 316.0000 317.6800 310.7500
205 2017/12/26 317.2900 4368699.0000 323.8300 323.9400 316.5800
206 2017/12/22 325.2000 4207602.0000 329.5100 330.9214 324.8200
207 2017/12/21 331.6600 4369994.0000 329.5900 333.7400 327.2100
208 2017/12/20 328.9800 5907378.0000 332.6900 333.1000 325.0400
209 2017/12/19 331.1000 6820868.0000 340.2600 341.4925 330.3000
210 2017/12/18 338.8700 5466546.0000 344.9000 346.7300 337.5800
211 2017/12/15 343.4500 6921246.0000 342.0400 343.9000 335.7600
212 2017/12/14 337.8900 5792024.0000 341.0100 347.4400 336.9000
213 2017/12/13 339.0300 6217701.0000 340.9300 344.2200 336.5000
214 2017/12/12 341.0300 8715570.0000 330.4500 341.4400 330.0300
215 2017/12/11 328.9100 7926090.0000 314.6300 329.0100 313.7500
216 2017/12/08 315.1300 3466088.0000 314.6000 316.9800 311.2600
217 2017/12/07 311.2400 4779590.0000 312.0000 318.6341 311.0500
218 2017/12/06 313.2600 7184477.0000 300.1000 313.3900 300.0000
219 2017/12/05 303.7000 4643708.0000 302.0000 308.0000 301.0000
220 2017/12/04 305.2000 5834227.0000 306.5000 308.2650 300.6100
221 2017/12/01 306.5300 4286082.0000 305.4400 310.3200 305.0500
222 2017/11/30 308.8500 4345434.0000 308.5600 310.7000 304.5400
223 2017/11/29 307.5400 8757463.0000 317.3000 318.0000 301.2300
224 2017/11/28 317.5500 4941703.0000 316.3600 320.0000 313.9200
225 2017/11/27 316.8100 4537779.0000 313.2500 317.3400 309.5100
226 2017/11/24 315.5500 3244065.0000 313.7900 316.4100 311.0000
227 2017/11/22 312.6000 4913283.0000 316.7700 317.4200 311.8400
228 2017/11/21 317.8100 7256381.0000 310.8600 318.2300 308.7100
229 2017/11/20 308.7400 8241821.0000 313.7900 315.5000 304.7500
230 2017/11/17 315.0500 13720830.0000 325.6700 326.6700 313.1500
231 2017/11/16 312.5000 5794409.0000 313.9900 318.1400 311.3000
232 2017/11/15 311.3000 5951835.0000 306.0100 312.4900 301.5000
233 2017/11/14 308.7000 5661904.0000 315.0000 316.3500 306.9000
234 2017/11/13 315.4000 7565242.0000 300.1300 316.8000 299.1100
235 2017/11/10 302.9900 4621080.0000 302.5000 308.3600 301.8500
236 2017/11/09 302.9900 5440173.0000 302.5000 304.4600 296.3000
237 2017/11/08 304.3900 4725355.0000 305.5000 306.8900 301.3001
238 2017/11/07 306.0500 5284844.0000 301.0200 306.5000 300.0300
239 2017/11/06 302.7800 6480689.0000 307.0000 307.5000 299.0100
240 2017/11/03 306.0900 8885933.0000 299.5000 306.2500 295.1300
241 2017/11/02 299.2600 19771280.0000 300.1300 308.6900 292.6300
242 2017/11/01 321.0800 8242487.0000 332.2500 332.6089 320.2600
243 2017/10/31 331.5300 5650062.0000 320.2300 331.9500 320.1800
244 2017/10/30 320.0800 4247619.0000 319.1800 323.7800 317.2500
245 2017/10/27 320.8700 6968365.0000 319.7500 324.5900 316.6600
246 2017/10/26 326.1700 5010087.0000 327.7800 330.2300 323.2000
247 2017/10/25 325.8400 8583619.0000 336.7000 337.5000 323.5600
248 2017/10/24 337.3400 4485692.0000 338.8000 342.8000 336.1600
249 2017/10/23 337.0200 5739598.0000 349.8800 349.9500 336.2500
250 2017/10/20 345.1000 4925657.0000 352.6900 354.5500 344.3400
251 2017/10/19 351.8100 5055715.0000 355.5600 357.1465 348.2000
252 2017/10/18 359.6500 4936024.0000 355.9700 363.0000 354.1300
253 2017/10/17 355.7500 3290290.0000 350.9100 356.2200 350.0700
254 2017/10/16 350.6000 5373090.0000 353.7600 354.4800 347.1600
255 2017/10/13 355.5700 3538807.0000 356.9800 358.4900 353.6800
256 2017/10/12 355.6800 4073552.0000 352.9500 359.7800 352.6400
257 2017/10/11 354.6000 4494733.0000 353.8900 357.6000 351.1500
258 2017/10/10 355.5900 6972263.0000 346.8000 355.6300 345.5305
259 2017/10/09 342.9400 7461461.0000 349.6500 351.7500 342.6700
260 2017/10/06 356.8800 4272866.0000 353.1000 360.0992 352.2500
261 2017/10/05 355.3300 4167913.0000 356.0000 357.4350 351.3500
262 2017/10/04 355.0100 8147995.0000 351.2500 358.6200 349.6000
263 2017/10/03 348.1400 10122550.0000 335.9000 348.5500 331.2800
264 2017/10/02 341.5300 5227547.0000 342.5200 343.7000 335.5100
265 2017/09/29 341.1000 5099051.0000 341.8600 344.6800 338.6010
266 2017/09/28 339.6000 5309779.0000 339.8800 342.7500 335.4000
267 2017/09/27 340.9700 6027375.0000 349.9000 351.4890 340.5000
268 2017/09/26 345.2500 7149649.0000 350.9300 351.2400 340.9000
269 2017/09/25 344.9900 7587158.0000 353.1500 357.4690 342.8800
270 2017/09/22 351.0900 8142895.0000 366.4900 369.8999 350.8800
271 2017/09/21 366.4800 4610872.0000 374.9000 376.8300 364.5100
272 2017/09/20 373.9100 4909958.0000 373.0000 378.2490 371.0700
273 2017/09/19 375.1000 6435208.0000 380.0000 382.3900 373.5700
274 2017/09/18 385.0000 7177773.0000 380.2500 389.6100 377.6800
275 2017/09/15 379.8100 5407227.0000 374.5100 380.0000 372.7000
276 2017/09/14 377.6400 7170263.0000 364.3300 377.9600 362.6300
277 2017/09/13 366.2300 4171185.0000 363.8200 368.0700 359.5900
278 2017/09/12 362.7500 5966204.0000 364.4900 368.7600 360.4000
279 2017/09/11 363.6900 7651000.0000 351.3500 363.7100 350.0000
280 2017/09/08 343.4000 3261333.0000 348.9900 349.7800 342.3000
281 2017/09/07 350.6100 4235045.0000 345.9800 352.4800 343.4500
282 2017/09/06 344.5300 4082001.0000 349.5000 350.9790 341.5600
283 2017/09/05 349.5900 3836402.0000 353.8000 355.4900 345.8900
284 2017/09/01 355.4000 3048550.0000 356.1200 357.5900 353.6902
285 2017/08/31 355.9000 4063330.0000 353.5500 358.4400 352.8200
286 2017/08/30 353.1800 3404165.0000 349.6700 353.4700 347.0000
287 2017/08/29 347.3600 4069303.0000 339.4800 349.0500 338.7500
288 2017/08/28 345.6600 3746240.0000 347.2800 347.3500 339.7200
289 2017/08/25 348.0500 3475186.0000 354.2400 355.6900 347.3000
290 2017/08/24 352.9300 4571574.0000 352.5200 356.6600 349.7400
291 2017/08/23 352.7700 4941947.0000 338.9900 353.4900 338.3041
292 2017/08/22 341.3500 4314268.0000 341.1300 342.2400 337.3725
293 2017/08/21 337.8600 6489850.0000 345.8200 345.8200 331.8500
294 2017/08/18 347.4600 5390805.0000 352.9100 354.0000 345.8000
295 2017/08/17 351.9200 5010825.0000 361.2100 363.3000 351.5900
296 2017/08/16 362.9100 3406173.0000 363.0000 366.5000 362.5200
297 2017/08/15 362.3300 3084601.0000 365.2000 365.4900 359.3700
298 2017/08/14 363.8000 4507969.0000 364.6300 367.6600 362.6000
299 2017/08/11 357.8700 4357562.0000 356.9700 361.2600 353.6200
300 2017/08/10 355.4000 7063054.0000 361.6000 366.6504 354.6600
301 2017/08/09 363.5300 6881182.0000 361.0000 370.0000 358.9500
302 2017/08/08 365.2200 7431838.0000 357.5300 368.5800 357.4000
303 2017/08/07 355.1700 6309331.0000 357.3500 359.4800 352.7500
304 2017/08/04 356.9100 9233295.0000 347.0000 357.2700 343.3000
305 2017/08/03 347.0900 13524270.0000 345.3300 350.0000 343.1500
306 2017/08/02 325.8900 11942350.0000 318.9400 327.1200 311.2200
307 2017/08/01 319.5700 8284997.0000 323.0000 324.4500 316.1300
308 2017/07/31 323.4700 8525454.0000 335.5000 341.4900 321.0400
309 2017/07/28 335.0700 4869891.0000 336.8900 339.6000 332.5100
310 2017/07/27 334.4600 8285879.0000 346.0000 347.5000 326.2900
311 2017/07/26 343.8500 4809514.0000 340.3600 345.5000 338.1200
312 2017/07/25 339.6000 6977932.0000 345.0000 345.6000 334.1500
313 2017/07/24 342.5200 8598292.0000 330.2400 343.3990 330.0100
314 2017/07/21 328.4000 4871708.0000 329.4600 331.2575 325.8000
315 2017/07/20 329.9200 5142516.0000 326.9000 330.2200 324.2000
316 2017/07/19 325.2600 6345884.0000 328.2300 331.6500 323.2193
317 2017/07/18 328.2400 6360710.0000 317.5000 329.1300 315.6600
318 2017/07/17 319.5700 9827506.0000 325.5400 327.1000 313.4500
319 2017/07/14 327.7800 5607924.0000 323.1900 328.4200 321.2200
320 2017/07/13 323.4100 8582315.0000 330.1100 331.6000 319.9700
321 2017/07/12 329.5200 10317240.0000 330.4000 333.1000 324.5000
322 2017/07/11 327.2200 11526760.0000 316.0000 327.2800 314.3000
323 2017/07/10 316.0500 13760290.0000 312.9000 317.9400 303.1300
324 2017/07/07 313.2200 14129950.0000 313.5000 317.0000 307.3800
325 2017/07/06 308.8300 19258040.0000 317.2600 320.7899 306.3000
326 2017/07/05 327.0900 16998300.0000 347.2000 347.2400 326.3300
327 2017/07/03 352.6200 6305401.0000 370.2400 371.3500 351.5000
328 2017/06/30 361.6100 5823046.0000 363.7100 366.7674 359.6187
329 2017/06/29 360.7500 8202463.0000 370.6100 371.0000 354.1000
330 2017/06/28 371.2400 6290323.0000 366.6800 371.7400 362.5200
331 2017/06/27 362.3700 6977494.0000 376.4000 376.4000 362.0200
332 2017/06/26 377.4900 6596854.0000 386.6900 386.9500 373.1000
333 2017/06/23 383.4500 6425180.0000 382.4500 386.9900 379.3450
334 2017/06/22 382.6100 7510406.0000 377.9900 385.0000 373.5700
335 2017/06/21 376.4000 4916770.0000 374.3500 376.9900 368.0200
336 2017/06/20 372.2400 7419110.0000 376.6700 378.8800 369.7300
337 2017/06/19 369.8000 6433434.0000 375.0000 376.7000 367.8000
338 2017/06/16 371.4000 6347450.0000 377.9750 378.0100 370.1000
339 2017/06/15 375.3400 10412650.0000 372.5000 375.4600 366.4900
340 2017/06/14 380.6600 12778480.0000 381.0850 384.2500 376.3100
341 2017/06/13 375.9500 11773370.0000 367.6200 376.0000 366.6100
342 2017/06/12 359.0100 10507860.0000 357.9900 364.5000 350.6200
343 2017/06/09 357.3200 17250060.0000 374.4200 376.8700 354.8000
344 2017/06/08 370.0000 9028677.0000 363.7500 371.9000 360.2200
345 2017/06/07 359.6500 9348692.0000 356.3400 360.5000 355.1400
346 2017/06/06 352.8500 11031920.0000 344.7000 359.4929 339.9700
347 2017/06/05 347.3200 6769174.0000 338.5000 348.4400 334.2100
348 2017/06/02 339.8500 5583952.0000 339.7700 342.8800 335.9300
349 2017/06/01 340.3700 7601764.0000 344.0000 344.8800 337.2900
350 2017/05/31 341.0100 9937556.0000 337.6900 342.8900 335.1600
351 2017/05/30 335.1000 7771536.0000 326.0000 336.2800 325.7600
352 2017/05/26 325.1400 7793009.0000 317.2800 325.4900 316.3100
353 2017/05/25 316.8300 5000432.0000 311.0200 316.9700 307.8100
354 2017/05/24 310.2200 5035192.0000 306.5100 311.0000 305.4000
355 2017/05/23 303.8600 4314267.0000 310.4600 310.7300 303.4800
356 2017/05/22 310.3500 4324305.0000 312.8000 314.3700 306.8000
357 2017/05/19 310.8300 4654580.0000 315.5000 316.5000 310.2000
358 2017/05/18 313.0600 5609153.0000 307.0000 313.9400 305.3100
359 2017/05/17 306.1100 6695657.0000 314.3900 314.6300 305.5000
360 2017/05/16 317.0100 4141066.0000 317.5900 320.0600 315.1400
361 2017/05/15 315.8800 7606854.0000 318.3800 320.2000 312.5300
362 2017/05/12 324.8100 4118613.0000 325.4800 327.0000 321.5300
363 2017/05/11 323.1000 4747172.0000 323.4000 326.0000 319.6000
364 2017/05/10 325.2200 5734524.0000 321.5600 325.5000 318.1200
365 2017/05/09 321.2600 9663374.0000 309.3800 321.9900 309.1000
366 2017/05/08 307.1900 7002907.0000 310.9000 313.7900 305.8200
367 2017/05/05 308.3500 8117449.0000 298.0000 308.5500 296.8000
368 2017/05/04 295.4600 14135990.0000 307.4350 307.7700 290.7601
369 2017/05/03 311.0200 6879259.0000 317.6700 321.5300 310.4500
370 2017/05/02 318.8900 5316551.0000 324.0000 327.6599 316.5601
371 2017/05/01 322.8300 8819888.0000 314.8800 327.2500 314.8100
372 2017/04/28 314.0700 4496659.0000 309.8300 314.8000 308.0000
373 2017/04/27 308.6300 3462663.0000 311.6900 313.0900 307.5000
374 2017/04/26 310.1700 4683131.0000 312.3700 314.5000 309.0000
375 2017/04/25 313.7900 6734162.0000 308.0000 313.9800 305.8600
376 2017/04/24 308.0300 5077771.0000 309.2200 310.5500 306.0215
377 2017/04/21 305.6000 4501958.0000 302.0000 306.4000 300.4200
378 2017/04/20 302.5100 6145961.0000 306.5100 309.1500 300.2300
379 2017/04/19 305.5200 3891145.0000 302.4600 306.6200 302.1100
380 2017/04/18 300.2500 3034225.0000 299.7000 300.8399 297.9000
381 2017/04/17 301.4400 4128067.0000 302.7000 304.0000 298.6800
382 2017/04/13 304.0000 9275682.0000 296.7000 307.3900 295.3000
383 2017/04/12 296.8400 6043648.0000 306.3400 308.4481 296.3200
384 2017/04/11 308.7100 5718053.0000 313.3800 313.4700 305.5000
385 2017/04/10 312.3900 7653623.0000 309.1500 313.7299 308.7100
386 2017/04/07 302.5400 4566632.0000 297.5000 302.6900 297.1500
387 2017/04/06 298.7000 5517731.0000 296.8800 301.9400 294.1000
388 2017/04/05 295.0000 7858565.0000 302.0400 304.8800 294.2000
389 2017/04/04 303.7000 10108230.0000 296.8900 304.8100 294.5300
390 2017/04/03 298.5200 13864850.0000 286.9000 299.0000 284.5800
391 2017/03/31 278.3000 3293698.0000 278.7300 279.6800 276.3197
392 2017/03/30 277.9200 4141437.0000 278.0400 282.0000 277.2100
393 2017/03/29 277.3800 3672526.0000 278.3400 279.6000 275.5400
394 2017/03/28 277.4500 7978665.0000 277.0200 280.6800 275.0000
395 2017/03/27 270.2200 6221361.0000 260.6000 270.5700 259.7500
396 2017/03/24 263.1600 5637668.0000 255.7000 263.8900 255.0100
397 2017/03/23 254.7800 3309844.0000 255.3900 257.6720 253.3000
398 2017/03/22 255.0100 4056735.0000 251.5600 255.0700 250.5100
399 2017/03/21 250.6800 6901555.0000 262.8300 264.8000 250.2400
400 2017/03/20 261.9200 3601616.0000 260.6000 264.5500 258.8210
401 2017/03/17 261.5000 6491018.0000 264.0000 265.3300 261.2000
402 2017/03/16 262.0500 7127180.0000 262.4000 265.7500 259.0600
403 2017/03/15 255.7300 5233365.0000 257.0000 261.0000 254.2700
404 2017/03/14 258.0000 7581719.0000 246.1100 258.1200 246.0200
405 2017/03/13 246.1700 3011280.0000 244.8200 246.8500 242.7810
406 2017/03/10 243.6900 3062785.0000 246.2100 246.5000 243.0000
407 2017/03/09 244.9000 3876494.0000 247.6300 248.6600 243.0000
408 2017/03/08 246.8700 3726746.0000 247.0000 250.0700 245.3200
409 2017/03/07 248.5900 3452587.0000 251.9200 253.8900 248.3200
410 2017/03/06 251.2100 3353601.0000 247.9100 251.7000 247.5100
411 2017/03/03 251.5700 2925481.0000 250.7400 251.9000 249.0000
412 2017/03/02 250.4800 3345751.0000 249.7100 253.2800 248.2700
413 2017/03/01 250.0200 4804963.0000 254.1800 254.8500 249.1100
414 2017/02/28 249.9900 6073890.0000 244.1900 251.0000 243.9000
415 2017/02/27 246.2300 11450160.0000 248.1700 248.3600 242.0100
416 2017/02/24 257.0000 8166869.0000 252.6600 258.2500 250.2000
417 2017/02/23 255.9900 14877090.0000 264.0000 264.6600 255.5600
418 2017/02/22 273.5100 8537811.0000 280.3100 283.4500 272.6000
419 2017/02/21 277.3900 5647575.0000 275.4500 281.4000 274.0100
420 2017/02/17 272.2300 6251469.0000 265.8000 272.8900 264.1500
421 2017/02/16 268.9500 7063860.0000 277.6000 280.0000 268.5000
422 2017/02/15 279.7600 4943879.0000 280.0000 282.2400 276.4400
423 2017/02/14 280.9800 7341450.0000 279.0300 287.3900 278.6100
424 2017/02/13 280.6000 7023072.0000 270.7400 280.7899 270.5100
425 2017/02/10 269.2300 3618336.0000 269.7900 270.9500 266.1100
426 2017/02/09 269.2000 7812600.0000 266.2500 271.1800 266.1500
427 2017/02/08 262.0800 3912428.0000 257.3500 263.3600 256.2000
428 2017/02/07 257.4800 4244063.0000 258.1900 260.0000 256.4200
429 2017/02/06 257.7700 3557600.0000 251.0000 257.8200 250.6300
430 2017/02/03 251.3300 2185230.0000 251.9100 252.1790 249.6800
431 2017/02/02 251.5500 2498799.0000 248.3400 252.4200 247.7100
432 2017/02/01 249.2400 3953105.0000 253.0500 253.2000 249.0500
433 2017/01/31 251.9300 4112013.0000 249.2400 255.8900 247.7000
434 2017/01/30 250.6300 3798638.0000 252.5300 255.2899 247.1000
435 2017/01/27 252.9500 3161774.0000 251.3800 253.0000 248.5200
436 2017/01/26 252.5100 3143717.0000 254.2900 255.7400 250.7500
437 2017/01/25 254.4700 5145301.0000 257.3100 258.4600 251.8000
438 2017/01/24 254.6100 4958144.0000 250.0000 254.8000 249.6500
439 2017/01/23 248.9200 6262097.0000 245.8500 250.8899 245.5000
440 2017/01/20 244.7300 4199720.0000 245.4600 246.0000 243.0100
441 2017/01/19 243.7600 7717244.0000 247.2500 248.6800 240.7500
442 2017/01/18 238.3600 3767272.0000 236.6500 239.7100 235.5800
443 2017/01/17 235.5800 4614731.0000 236.7000 239.9600 234.3700
444 2017/01/13 237.7500 6085610.0000 230.0000 237.8500 229.5900
445 2017/01/12 229.5900 3787547.0000 229.0600 230.7000 225.5800
446 2017/01/11 229.7300 3649910.0000 229.0700 229.9800 226.6800
447 2017/01/10 229.8700 3658981.0000 232.0000 232.0000 226.8900
448 2017/01/09 231.2800 3972716.0000 228.9700 231.9200 228.0000
449 2017/01/06 229.0100 5524153.0000 226.9300 230.3100 225.4500
450 2017/01/05 226.7500 5908927.0000 226.4200 227.4800 221.9500
451 2017/01/04 226.9900 11204560.0000 214.7500 228.0000 214.3100
452 2017/01/03 216.9900 5901494.0000 214.8600 220.3300 210.9600
453 2016/12/30 213.6900 4641288.0000 216.3000 217.5000 211.6800
454 2016/12/29 214.6800 4043086.0000 218.5600 219.2000 214.1225
455 2016/12/28 219.7400 3778544.0000 221.5300 223.8000 217.2000
456 2016/12/27 219.5300 5913335.0000 214.8800 222.2500 214.4200
457 2016/12/23 213.3400 4668263.0000 208.0000 213.4500 207.7100
458 2016/12/22 208.4500 3108427.0000 208.2200 209.9900 206.5000
459 2016/12/21 207.7000 5206143.0000 208.4500 212.2300 207.4100
460 2016/12/20 208.7900 4684269.0000 203.0500 209.0000 202.5000
461 2016/12/19 202.7300 3486937.0000 202.4900 204.4500 199.8400
462 2016/12/16 202.4900 3795444.0000 198.0800 202.5900 197.6000
463 2016/12/15 197.5800 3218653.0000 198.4100 200.7400 197.3900
464 2016/12/14 198.6900 4147314.0000 198.7400 203.0000 196.7600
465 2016/12/13 198.1500 6819322.0000 193.1800 201.2800 193.0000
466 2016/12/12 192.4300 2436428.0000 192.8000 194.4200 191.0400
467 2016/12/09 192.1800 2720937.0000 190.8700 193.8360 190.8100
468 2016/12/08 192.2900 3193684.0000 192.0500 192.5000 189.5400
469 2016/12/07 193.1500 5457071.0000 186.1500 193.4000 185.0000
470 2016/12/06 185.8500 3389365.0000 185.5200 186.5800 182.6825
471 2016/12/05 186.8000 4069480.0000 182.5100 188.8900 182.5100
472 2016/12/02 181.4700 4040201.0000 182.8800 184.8800 180.0000
473 2016/12/01 181.8800 5119105.0000 188.2500 188.5300 181.0000
474 2016/11/30 189.4000 3544891.0000 191.0000 191.8900 187.5000
475 2016/11/29 189.5700 4435312.0000 195.5600 196.7300 189.5000
476 2016/11/28 196.1200 4521082.0000 195.4800 199.3500 194.5500
477 2016/11/25 196.6500 2366098.0000 193.6400 197.2372 193.6400
478 2016/11/23 193.1400 4890285.0000 190.6100 195.6440 189.0000
479 2016/11/22 191.1700 5601238.0000 185.8400 191.4700 183.7100
480 2016/11/21 184.5200 4355872.0000 185.0400 188.8900 184.4100
481 2016/11/18 185.0200 5206473.0000 190.6500 193.0000 185.0000
482 2016/11/17 188.6600 4880969.0000 183.4900 189.4900 182.1101
483 2016/11/16 183.9300 3432668.0000 182.6500 184.7300 181.2100
484 2016/11/15 183.7700 3899743.0000 182.7800 186.4300 182.0500
485 2016/11/14 181.4500 6547913.0000 188.0000 188.2500 178.1900
486 2016/11/11 188.5600 3987091.0000 184.2400 188.8800 183.0000
487 2016/11/10 185.3500 6746290.0000 191.0500 191.6100 180.4200
488 2016/11/09 190.0600 8166447.0000 186.8750 192.0000 183.9500
489 2016/11/08 194.9400 3252927.0000 193.7900 197.4900 191.2600
490 2016/11/07 193.2100 3857682.0000 193.5900 194.2900 190.0500
491 2016/11/04 190.5600 5143915.0000 189.0000 193.4600 185.9600
492 2016/11/03 187.4200 2644550.0000 189.0000 191.4700 187.0401
493 2016/11/02 188.0200 4242250.0000 190.0500 192.6951 187.5050
494 2016/11/01 190.7900 7023674.0000 198.0400 198.5000 188.1050
495 2016/10/31 197.7300 4691320.0000 202.4900 202.4900 195.8100
496 2016/10/28 199.9700 4273456.0000 204.0000 205.3200 199.8300
497 2016/10/27 204.0100 13070990.0000 211.3400 213.7000 201.6500
498 2016/10/26 202.2400 5346893.0000 201.0000 203.1900 200.1000
499 2016/10/25 202.3400 2442118.0000 202.9000 204.6900 201.2000
500 2016/10/24 202.7600 2747344.0000 201.0000 203.9452 200.2500
501 2016/10/21 200.0900 2936908.0000 198.6000 201.5700 197.4100
502 2016/10/20 199.1000 5069410.0000 202.1200 203.0000 197.0500
503 2016/10/19 203.5600 6966185.0000 199.7400 206.6600 198.0600
504 2016/10/18 199.1000 5676046.0000 195.9900 199.4700 193.2600
505 2016/10/17 193.9600 4518331.0000 197.0500 198.3900 192.0000
506 2016/10/14 196.5100 4265471.0000 200.6600 201.4300 196.3000
507 2016/10/13 200.2400 2495140.0000 200.5000 200.8950 197.0500
508 2016/10/12 201.5100 1969099.0000 200.9500 203.8800 200.4200
509 2016/10/11 200.1000 2326754.0000 201.8500 202.2000 198.3100
510 2016/10/10 200.9500 3311340.0000 201.3500 204.1400 199.6600
511 2016/10/07 196.6100 3489480.0000 201.0000 201.3200 195.8000
512 2016/10/06 201.0000 4697937.0000 202.4600 204.2099 200.2100
513 2016/10/05 208.4600 1872456.0000 212.2400 213.1500 208.1200
514 2016/10/04 211.4100 3537953.0000 213.1000 213.3200 208.8200
515 2016/10/03 213.7000 5989342.0000 212.3000 215.6688 208.2500
516 2016/09/30 204.0300 2581730.0000 202.2100 204.9800 199.5500
517 2016/09/29 200.7000 2714040.0000 205.6000 207.3300 200.5800
518 2016/09/28 206.2700 2079324.0000 207.5100 208.2500 205.2600
519 2016/09/27 205.8100 3367907.0000 209.6500 209.9818 204.6093
520 2016/09/26 208.9900 2393373.0000 206.5000 211.0000 206.5000
521 2016/09/23 207.4500 2904125.0000 205.9900 210.1800 205.6700
522 2016/09/22 206.4300 2381600.0000 206.4000 207.2800 203.0000
523 2016/09/21 205.2200 2631285.0000 206.3700 207.0000 201.5600
524 2016/09/20 204.6400 2408556.0000 206.8500 207.7500 203.9100
525 2016/09/19 206.3400 2298318.0000 207.0000 209.4300 205.0000
526 2016/09/16 205.4000 3104266.0000 200.4200 205.7000 199.0000
527 2016/09/15 200.4200 3082942.0000 196.4900 202.5193 196.4000
528 2016/09/14 196.4100 2256143.0000 195.7500 197.9248 194.8562
529 2016/09/13 196.0500 3583140.0000 197.0600 198.4900 193.4500
530 2016/09/12 198.3000 3714049.0000 195.0000 201.3690 194.1000
531 2016/09/09 194.4700 3753734.0000 199.0900 199.9200 193.7000
532 2016/09/08 197.3600 3372293.0000 199.5500 199.8900 196.3600
533 2016/09/07 201.7100 3637918.0000 205.5000 206.4968 200.7100
534 2016/09/06 202.8300 4386193.0000 199.0200 203.2500 199.0000
535 2016/09/02 197.7800 5970154.0000 202.3300 203.2000 196.2000
536 2016/09/01 200.7700 7932444.0000 209.0100 211.0999 200.5000
537 2016/08/31 212.0100 3274854.0000 210.4300 212.6000 208.6500
538 2016/08/30 211.3400 3164222.0000 216.1100 216.1100 210.5200
539 2016/08/29 215.2000 3261381.0000 220.1500 220.4000 215.0000
540 2016/08/26 219.9900 2238087.0000 222.1400 222.8550 218.8200
541 2016/08/25 220.9600 1760212.0000 223.1100 223.8000 220.7700
542 2016/08/24 222.6200 2566947.0000 227.0500 227.1500 222.2200
543 2016/08/23 224.8400 4747745.0000 224.3200 228.4900 222.8000
544 2016/08/22 222.9300 2061692.0000 224.1700 225.1100 222.6800
545 2016/08/19 225.0000 1658616.0000 223.5400 225.1690 222.5300
546 2016/08/18 223.5100 1699300.0000 223.8200 225.6600 222.2900
547 2016/08/17 223.2400 1786408.0000 224.3300 224.8300 222.8000
548 2016/08/16 223.6100 2251115.0000 225.4900 227.1900 223.4101
549 2016/08/15 225.5900 2017964.0000 226.0200 229.5000 224.9300
550 2016/08/12 225.6100 1811850.0000 225.4100 226.6500 224.0400
551 2016/08/11 224.9100 1876959.0000 226.1700 227.5700 223.4100
552 2016/08/10 225.6500 2336496.0000 228.2400 229.8700 224.6200
553 2016/08/09 229.0800 2199766.0000 226.8200 231.5375 226.6500
554 2016/08/08 226.1600 2259465.0000 228.0000 229.6000 226.0900
555 2016/08/05 230.0300 3190342.0000 230.0000 232.0000 227.4000
556 2016/08/04 230.6100 4142155.0000 225.6900 230.8600 222.0500
557 2016/08/03 225.7900 3808747.0000 227.3700 229.6990 224.2100
558 2016/08/02 227.2000 3928706.0000 229.3700 229.8700 221.4000
559 2016/08/01 230.0100 4014048.0000 235.5000 236.6300 229.3800
560 2016/07/29 234.7900 3061574.0000 230.7000 235.2800 230.2400
561 2016/07/28 230.6100 2415462.0000 227.9500 230.7600 226.6000
562 2016/07/27 228.4900 2887028.0000 229.3400 233.3600 226.9200
563 2016/07/26 229.5100 3427251.0000 227.6900 230.0000 225.3000
564 2016/07/25 230.0100 4479483.0000 222.2700 231.3900 221.3715
565 2016/07/22 222.2700 2570462.0000 221.9900 224.5000 218.8800
566 2016/07/21 220.5000 4425756.0000 226.0000 227.8470 219.1000
567 2016/07/20 228.3600 2556119.0000 226.4700 229.8000 225.0000
568 2016/07/19 225.2600 3047535.0000 225.0000 229.1000 224.7500
569 2016/07/18 226.2500 3394588.0000 219.6400 227.0900 218.3000
570 2016/07/15 220.4000 2230821.0000 222.5200 222.7499 219.6400
571 2016/07/14 221.5300 2657899.0000 223.1200 224.9400 221.0500
572 2016/07/13 222.5300 3540699.0000 225.5000 225.5900 220.2900
573 2016/07/12 224.6500 4573875.0000 224.1000 227.5000 223.2200
574 2016/07/11 224.7800 5369066.0000 219.9600 226.7800 219.5100
575 2016/07/08 216.7800 4067131.0000 217.8000 219.8100 214.5000
576 2016/07/07 215.9400 3603385.0000 213.1000 218.1200 213.0100
577 2016/07/06 214.4400 4910285.0000 210.0000 215.2300 209.0000
578 2016/07/05 213.9800 5169832.0000 209.7300 214.5441 208.0000
579 2016/07/01 216.5000 5396030.0000 206.1400 218.2400 206.0000
580 2016/06/30 212.2800 4794440.0000 212.9700 213.4999 209.0200
581 2016/06/29 210.1900 5987120.0000 205.1300 211.7800 203.0000
582 2016/06/28 201.7900 6158996.0000 201.8900 204.0500 199.4100
583 2016/06/27 198.5500 7211823.0000 190.8600 198.8100 187.8700
584 2016/06/24 193.1500 6988949.0000 190.0500 195.1200 189.7300
585 2016/06/23 196.4000 10098190.0000 195.6900 197.5500 192.1300
586 2016/06/22 196.6600 23706100.0000 199.4700 205.9500 195.7500
587 2016/06/21 219.6100 2855619.0000 220.6800 222.5690 218.8100
588 2016/06/20 219.7000 3549768.0000 219.5000 223.7500 218.2300
589 2016/06/17 215.4700 3107734.0000 217.8100 219.9900 214.5000
590 2016/06/16 217.9300 2438692.0000 217.4200 218.0400 213.5000
591 2016/06/15 217.7000 2905002.0000 216.9500 221.9000 215.1300
592 2016/06/14 214.9600 3575822.0000 218.8800 222.2000 212.5300
593 2016/06/13 217.8700 4187833.0000 219.5000 225.7700 217.6600
594 2016/06/10 218.7900 5994548.0000 227.3900 227.9700 218.4217
595 2016/06/09 229.3600 4454222.0000 234.9800 235.3300 227.0600
596 2016/06/08 235.5200 5965110.0000 233.8000 240.8450 232.6050
597 2016/06/07 232.3400 6194154.0000 222.2400 234.4400 221.5200
598 2016/06/06 220.6800 2242634.0000 218.0000 220.9000 215.4500
599 2016/06/03 218.9900 2226110.0000 220.0000 221.9400 218.0100
600 2016/06/02 218.9600 2017279.0000 219.5900 219.9090 217.1100
601 2016/06/01 219.5600 2982270.0000 221.4800 222.4000 216.8900
602 2016/05/31 223.2300 2786682.0000 223.0400 224.7497 221.5001
603 2016/05/27 223.0400 3645792.0000 224.9900 225.9300 220.7500
604 2016/05/26 225.1200 4066512.0000 220.5000 225.2600 219.0500
605 2016/05/25 219.5800 3131279.0000 217.9100 221.3600 216.5100
606 2016/05/24 217.9100 3009327.0000 216.6000 218.7400 215.1800
607 2016/05/23 216.2200 5096751.0000 219.8700 222.6000 215.8600
608 2016/05/20 220.2800 8996546.0000 216.9900 220.5500 216.3500
609 2016/05/19 215.2100 6817922.0000 213.6200 216.7900 207.3000
610 2016/05/18 211.1700 5552692.0000 209.1500 215.3100 207.7500
611 2016/05/17 204.6600 2842028.0000 209.0500 209.8199 204.0200
612 2016/05/16 208.2900 2945754.0000 208.1500 213.1500 207.9200
613 2016/05/13 207.6100 2820616.0000 207.7800 211.2000 206.7000
614 2016/05/12 207.2800 3650075.0000 211.4400 211.6700 203.6572
615 2016/05/11 208.9600 5159640.0000 207.5900 215.4800 206.0500
616 2016/05/10 208.6900 4068053.0000 207.5500 209.4700 205.0000
617 2016/05/09 208.9200 4772992.0000 215.7200 216.1500 206.8000
618 2016/05/06 214.9300 5683675.0000 210.8700 216.3700 208.1100
619 2016/05/05 211.5300 11248340.0000 228.4600 228.6400 209.7900
620 2016/05/04 222.5600 8550004.0000 230.2900 234.4600 220.4000
621 2016/05/03 232.3200 4296325.0000 237.3600 238.9100 231.6200
622 2016/05/02 241.8000 3838958.0000 241.5000 243.1900 234.8200
623 2016/04/29 240.7600 5405164.0000 248.1400 248.4300 237.8100
624 2016/04/28 247.7100 2515595.0000 249.8500 253.4300 247.4400
625 2016/04/27 251.4700 3198105.0000 252.7500 255.0000 249.4000
626 2016/04/26 253.7400 3217779.0000 252.0500 255.7300 249.3900
627 2016/04/25 251.8200 3665088.0000 253.0100 257.3800 250.7600
628 2016/04/22 253.7500 3783126.0000 248.8900 254.0000 245.7100
629 2016/04/21 248.2900 2777079.0000 248.9900 250.9000 246.9100
630 2016/04/20 249.9700 5192343.0000 246.2600 253.6600 241.5000
631 2016/04/19 247.3700 6351360.0000 253.1200 254.3699 241.2510
632 2016/04/18 253.8800 4263246.0000 252.2300 258.3100 251.6600
633 2016/04/15 254.5100 3748593.0000 251.3100 254.6000 249.1200
634 2016/04/14 251.8600 4129258.0000 253.0000 256.8390 251.0501
635 2016/04/13 254.5300 4921554.0000 248.5100 255.5000 247.3300
636 2016/04/12 247.8200 5755351.0000 249.5000 251.8000 243.6300
637 2016/04/11 249.9200 9156404.0000 251.0000 258.9900 245.3000
638 2016/04/08 250.0700 7352707.0000 260.5000 260.8200 248.0201
639 2016/04/07 257.2000 8845567.0000 266.4500 269.3400 254.5100
640 2016/04/06 265.4200 11695760.0000 253.9700 267.7400 253.4500
641 2016/04/05 255.4700 9931470.0000 240.5000 256.5600 240.0000
642 2016/04/04 246.9900 13381160.0000 249.1200 252.1200 243.6400
643 2016/04/01 237.5900 15979910.0000 244.8250 247.9000 233.2500
644 2016/03/31 229.7700 7975638.0000 229.3400 237.4200 225.0100
645 2016/03/30 226.8900 4025670.0000 235.0900 235.5000 226.5000
646 2016/03/29 230.1300 4006037.0000 229.8900 232.3800 225.3300
647 2016/03/28 230.2600 3878599.0000 231.6100 234.8100 225.0000
648 2016/03/24 227.7500 4956604.0000 215.7800 228.8877 215.0000
649 2016/03/23 222.5800 4936203.0000 232.3700 234.7300 222.0300
650 2016/03/22 234.2400 4303052.0000 237.2100 238.9900 232.5580
651 2016/03/21 238.3200 5289014.0000 235.3400 239.8800 235.0000
652 2016/03/18 232.7400 4704761.0000 229.1000 234.4800 228.0600
653 2016/03/17 226.3800 3769083.0000 221.4700 228.5000 220.0000
654 2016/03/16 221.9300 3511873.0000 218.0000 222.5800 217.0200
655 2016/03/15 218.3400 3133230.0000 214.2700 218.9700 211.5000
656 2016/03/14 215.1500 4062304.0000 212.6500 216.7200 210.6400
657 2016/03/11 207.5000 3339148.0000 207.9300 209.4200 205.3300
658 2016/03/10 205.1800 5191602.0000 210.0000 213.2900 200.6710
659 2016/03/09 208.7200 3207597.0000 204.5200 209.3726 202.7900
660 2016/03/08 202.6000 4175498.0000 203.5000 207.5000 202.2000
661 2016/03/07 205.2900 5331097.0000 197.6800 209.7000 197.4000
662 2016/03/04 201.0400 6479858.0000 198.0000 204.0300 197.5001
663 2016/03/03 195.7400 4822993.0000 188.2800 197.4200 184.2200
664 2016/03/02 188.3400 4858631.0000 183.7300 188.5200 181.5000
665 2016/03/01 186.3500 6695704.0000 194.2500 195.9484 182.7000
666 2016/02/29 191.9300 4495402.0000 192.4000 196.3500 189.2220
667 2016/02/26 190.3400 6054061.0000 188.7000 192.0000 185.0000
668 2016/02/25 187.4300 5727008.0000 178.6500 188.5192 175.2000
669 2016/02/24 179.0000 5385369.0000 172.7500 179.5000 167.8400
670 2016/02/23 177.2100 5982993.0000 176.1600 181.7300 173.6800
671 2016/02/22 177.7400 5055340.0000 170.1200 178.9100 169.8500
672 2016/02/19 166.5800 2955832.0000 163.6600 167.4900 162.5000
673 2016/02/18 166.7700 3883107.0000 172.4200 172.9500 164.7700
674 2016/02/17 168.6800 5820264.0000 159.0000 169.3400 156.6800
675 2016/02/16 155.1700 5561638.0000 158.7000 162.9500 154.1100
676 2016/02/12 151.0400 7233264.0000 155.0000 157.0100 143.7000
677 2016/02/11 150.4700 14236900.0000 152.0000 163.2600 147.0000
678 2016/02/10 143.6700 10104690.0000 150.5000 154.9700 141.7400
679 2016/02/09 148.2500 8639661.0000 142.3200 159.7900 141.0500
680 2016/02/08 147.9900 9306754.0000 157.1050 157.1500 146.0000
681 2016/02/05 162.6000 9434495.0000 171.3000 173.0000 157.7442
682 2016/02/04 175.3300 4379442.0000 170.7000 175.9800 166.9900
683 2016/02/03 173.4800 7927640.0000 183.5900 183.9400 170.1800
684 2016/02/02 182.7800 5764817.0000 192.4200 193.1200 180.2300
685 2016/02/01 196.9400 5295685.0000 188.7600 199.5200 182.7500
686 2016/01/29 191.2000 2848929.0000 189.9500 193.7400 188.0800
687 2016/01/28 189.7000 4586328.0000 190.7900 191.2800 182.4100
688 2016/01/27 188.0700 3577353.0000 192.3800 193.2600 185.7700
689 2016/01/26 193.5600 4956918.0000 196.7000 197.8200 188.8800
690 2016/01/25 196.3800 2695408.0000 200.0600 203.5700 195.8800
691 2016/01/22 202.5500 3122066.0000 204.8010 205.5000 199.0300
692 2016/01/21 199.9700 3164424.0000 201.5500 203.2300 195.0200
693 2016/01/20 198.7000 5826110.0000 199.4000 201.2800 191.2500
694 2016/01/19 204.7200 4031271.0000 208.7100 210.4700 200.7800
695 2016/01/15 204.9900 5325773.0000 198.9700 205.0700 197.2500
696 2016/01/14 206.1800 6490579.0000 202.2100 210.0000 193.3800
697 2016/01/13 200.3100 4120993.0000 212.0100 212.6500 200.0000
698 2016/01/12 209.9700 3079051.0000 211.6000 213.7395 205.3100
699 2016/01/11 207.8500 4090843.0000 214.0100 214.4500 203.0000
700 2016/01/08 211.0000 3572360.0000 217.8600 220.4400 210.7700
701 2016/01/07 215.6500 3550704.0000 214.1900 218.4400 213.6700
702 2016/01/06 219.0400 3774353.0000 220.0000 220.0500 215.9800
703 2016/01/05 223.4300 3185525.0000 226.3600 226.8900 220.0000
704 2016/01/04 223.4100 6823510.0000 230.7200 231.3800 219.0000
705 2015/12/31 240.0100 2713817.0000 238.5100 243.4500 238.3700
706 2015/12/30 238.0900 3694448.0000 236.6000 243.6340 235.6707
707 2015/12/29 237.1900 2402438.0000 230.0600 237.7200 229.5470
708 2015/12/28 228.9500 1900171.0000 231.4900 231.9800 225.5400
709 2015/12/24 230.5700 710277.0000 230.5600 231.8800 228.2800
710 2015/12/23 229.7000 1551031.0000 232.1800 233.4500 228.1300
711 2015/12/22 229.9500 1958836.0000 234.9900 236.5500 229.6300
712 2015/12/21 232.5600 1951581.0000 231.6900 235.8300 231.0800
713 2015/12/18 230.4600 3008057.0000 232.8900 235.9000 229.2900
714 2015/12/17 233.3900 3294460.0000 233.9400 237.7600 229.8149
715 2015/12/16 234.5100 5100443.0000 222.1000 234.8800 220.7300
716 2015/12/15 221.0900 2241686.0000 221.8200 222.2200 218.0000
717 2015/12/14 218.5800 2827797.0000 217.5100 220.9200 214.8700
718 2015/12/11 217.0200 3259114.0000 225.2400 225.7500 216.6400
719 2015/12/10 227.0700 2070088.0000 224.7100 228.4900 223.6400
720 2015/12/09 224.5200 3057036.0000 226.7000 227.5000 220.7200
721 2015/12/08 226.7200 2682259.0000 227.5200 228.8000 224.2000
722 2015/12/07 231.1300 3140864.0000 227.7000 235.6300 226.1500
723 2015/12/04 230.3800 2572014.0000 232.4600 233.2700 227.6600
724 2015/12/03 232.7100 2937233.0000 235.4800 237.4500 230.0000
725 2015/12/02 231.9900 2980644.0000 237.0000 238.6000 231.2300
726 2015/12/01 237.1900 3728562.0000 231.0600 238.0000 231.0500
727 2015/11/30 230.2600 2591205.0000 231.7900 234.2800 229.0800
728 2015/11/27 231.6100 1949353.0000 231.0600 232.2500 227.0100
729 2015/11/25 229.6400 3986945.0000 221.3400 230.8250 220.3750
730 2015/11/24 218.2500 2478389.0000 215.3700 221.0000 215.0000
731 2015/11/23 217.7500 2525196.0000 217.3500 219.1800 214.6798
732 2015/11/20 220.0100 4394199.0000 223.4900 225.0000 213.5800
733 2015/11/19 221.8000 2499593.0000 220.5400 226.1900 220.3000
734 2015/11/18 221.0700 2810200.0000 214.5000 221.3800 212.5200
735 2015/11/17 214.0000 2148326.0000 215.2000 216.0000 211.4000
736 2015/11/16 214.3100 2920362.0000 206.0900 214.9800 205.8000
737 2015/11/13 207.1900 3423139.0000 212.9500 212.9900 206.5200
738 2015/11/12 212.9400 2913511.0000 217.8500 219.0000 212.6600
739 2015/11/11 219.0800 3337501.0000 217.7700 219.4800 213.6300
740 2015/11/10 216.5000 4612408.0000 223.4800 223.7000 216.0800
741 2015/11/09 225.3300 3846179.0000 232.9900 232.9900 224.3100
742 2015/11/06 232.3600 2444264.0000 230.7000 233.3590 229.5000
743 2015/11/05 231.7700 4494944.0000 230.5800 234.5843 229.1900
744 2015/11/04 231.6300 12713530.0000 227.0000 232.7400 225.2000
745 2015/11/03 208.3500 8065091.0000 213.8500 214.4400 207.7500
746 2015/11/02 213.7900 3924514.0000 208.9200 215.8000 207.2200
747 2015/10/30 206.9300 4432433.0000 210.4000 211.6300 203.8900
748 2015/10/29 211.6300 1794743.0000 211.7500 213.7481 210.6400
749 2015/10/28 212.9600 2726880.0000 211.3100 213.4500 208.3000
750 2015/10/27 210.3500 3512832.0000 214.8400 217.1000 207.5100
751 2015/10/26 215.2600 3388227.0000 211.3800 215.8800 210.0000
752 2015/10/23 209.0900 4226411.0000 215.0000 215.3500 207.6900
753 2015/10/22 211.7200 2818801.0000 211.5600 215.7500 209.4000
754 2015/10/21 210.0900 4177956.0000 211.9900 214.8100 208.8000
755 2015/10/20 213.0300 14877020.0000 227.7200 228.6000 202.0000
756 2015/10/19 228.1000 2506836.0000 226.5000 231.1500 224.9400
757 2015/10/16 227.0100 4327574.0000 223.0400 230.4805 222.8700
758 2015/10/15 221.3100 2835920.0000 216.4300 221.7300 213.7000
+115
View File
@@ -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()
+1270 -1
View File
File diff suppressed because it is too large. Load diff
+36
View File
@@ -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()
+5
View File
@@ -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")
+16
View File
@@ -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"
)
+120
View File
@@ -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
+97
View File
@@ -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
+140
View File
@@ -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: "image-to-text"
---
```mermaid
flowchart LR
In[Image Input] --> OCR[Text Extractor]
OCR --> Analyzer[Content Analyzer]
Analyzer --> Generator[Description Generator]
Generator --> Out[Text Output]
style In fill:#8B0000,color:#fff
style OCR fill:#2E8B57,color:#fff
style Analyzer fill:#2E8B57,color:#fff
style Generator fill:#2E8B57,color:#fff
style Out fill:#8B0000,color:#fff
```
A workflow demonstrating how the Image-to-Text Agent can extract text from images and generate comprehensive descriptions.
## Quick Start
<Steps>
<Step title="Install Package">
First, install the PraisonAI Agents package:
```bash
pip install praisonaiagents
```
</Step>
<Step title="Set API Key">
Set your OpenAI API key as an environment variable:
```bash
export OPENAI_API_KEY=your_api_key_here
```
</Step>
<Step title="Create Script">
Create a new file `image_to_text.py`:
```python
from praisonaiagents import Agent, Task, PraisonAIAgents
# Create Image-to-Text Agent
image_text_agent = Agent(
name="ImageTextConverter",
role="Image Text Extraction Specialist",
goal="Convert image content to textual descriptions and extract text",
backstory="""You are an expert in OCR and image understanding.
You excel at extracting text from images and generating detailed descriptions.""",
llm="gpt-4o-mini",
self_reflect=False
)
# Create text extraction task
extraction_task = Task(
name="extract_text",
description="Extract all text from this image and describe its layout.",
expected_output="Extracted text and layout description",
agent=image_text_agent,
images=["document.jpg"]
)
# Create description task
description_task = Task(
name="generate_description",
description="Generate a detailed description of the image content.",
expected_output="Comprehensive description of visual elements",
agent=image_text_agent,
images=["scene.jpg"]
)
# Create PraisonAIAgents instance
agents = PraisonAIAgents(
agents=[image_text_agent],
tasks=[extraction_task, description_task],
process="sequential",
verbose=1
)
# Run analysis
agents.start()
```
</Step>
</Steps>
## Understanding Image-to-Text Conversion
The Image-to-Text Agent combines multiple capabilities to convert visual content into textual form:
1. **OCR Processing**: Extracts text from images using optical character recognition
2. **Layout Analysis**: Understands the spatial arrangement of text and visual elements
3. **Content Description**: Generates natural language descriptions of image content
4. **Text Formatting**: Preserves text formatting and structure where possible
## Features
<CardGroup cols={2}>
<Card title="Text Extraction" icon="text">
Advanced OCR capabilities for text extraction.
</Card>
<Card title="Layout Understanding" icon="table-layout">
Analysis of text and content layout.
</Card>
<Card title="Content Description" icon="pen-to-square">
Detailed descriptions of visual content.
</Card>
<Card title="Format Preservation" icon="paragraph">
Maintains text formatting and structure.
</Card>
</CardGroup>
## Example Usage
```python
# Example: Processing a document image
document_task = Task(
name="process_document",
description="Extract text and analyze document layout",
expected_output="Extracted text with layout information",
agent=image_text_agent,
images=["business_document.jpg"]
)
# Run single task
agents = PraisonAIAgents(
agents=[image_text_agent],
tasks=[document_task],
process="sequential"
)
agents.start()
```
## Next Steps
- Learn about [Prompt Chaining](/features/promptchaining) for complex document processing
- Explore [Evaluator Optimizer](/features/evaluator-optimiser) for improving text extraction accuracy
- Check out the [Image Agent](/agents/image) for pure image analysis capabilities
+139
View File
@@ -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
+120
View File
@@ -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
+109
View File
@@ -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
+125
View File
@@ -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
+109
View File
@@ -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
+108
View File
@@ -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
+109
View File
@@ -0,0 +1,109 @@
---
title: "Shopping Agent"
sidebarTitle: "Shopping"
description: "Learn how to create AI agents for price comparison and shopping assistance."
icon: "shopping-cart"
---
```mermaid
flowchart LR
In[Product Query] --> Search[Store Search]
Search --> Analyzer[Price Analyzer]
Analyzer --> Comparator[Price Comparator]
Comparator --> Out[Price Report]
style In fill:#8B0000,color:#fff
style Search fill:#2E8B57,color:#fff
style Analyzer fill:#2E8B57,color:#fff
style Comparator fill:#2E8B57,color:#fff
style Out fill:#8B0000,color:#fff
```
A workflow demonstrating how the Shopping Agent can search for products, compare prices, and provide shopping recommendations.
## Quick Start
<Steps>
<Step title="Install Package">
First, install the PraisonAI Agents package:
```bash
pip install praisonaiagents
```
</Step>
<Step title="Set API Key">
Set your OpenAI API key as an environment variable:
```bash
export OPENAI_API_KEY=your_api_key_here
```
</Step>
<Step title="Create Script">
Create a new file `shopping_assistant.py`:
```python
from praisonaiagents import Agent, Tools
from praisonaiagents.tools import duckduckgo
# Create Shopping Agent
shopping_agent = Agent(
name="ShoppingAssistant",
role="Shopping Specialist",
goal="Find the best prices and deals across stores",
instructions="You are a Shopping Agent",
tools=[duckduckgo]
)
# Search for product prices
response = shopping_agent.start(
"I want to buy iPhone 16 Pro Max, check 5 stores and give me price in table"
)
# Save price comparison
with open('price_comparison.md', 'w') as f:
f.write(response)
```
</Step>
</Steps>
## Understanding Shopping Assistant
The Shopping Agent combines multiple capabilities for effective price comparison:
1. **Store Search**: Uses DuckDuckGo to find retailers
2. **Price Analysis**: Gathers pricing information
3. **Price Comparison**: Compares prices across stores
4. **Deal Finding**: Identifies special offers and discounts
## Features
<CardGroup cols={2}>
<Card title="Price Comparison" icon="scale-balanced">
Compare prices across multiple stores.
</Card>
<Card title="Deal Detection" icon="tag">
Find special offers and discounts.
</Card>
<Card title="Store Analysis" icon="store">
Evaluate retailer reliability.
</Card>
<Card title="Price Tracking" icon="chart-line">
Monitor price changes over time.
</Card>
</CardGroup>
## Example Usage
```python
# Example: Compare product prices
from praisonaiagents import Agent, Tools
from praisonaiagents.tools import duckduckgo
agent = Agent(instructions="You are a Shopping Agent", tools=[duckduckgo])
agent.start("I want to buy iPhone 16 Pro Max, check 5 stores and give me price in table")
```
## Next Steps
- Learn about [Prompt Chaining](/features/promptchaining) for complex shopping research
- Explore [Evaluator Optimizer](/features/evaluator-optimiser) for improving price accuracy
- Check out the [Research Agent](/agents/research) for detailed product research
+102
View File
@@ -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
+149
View File
@@ -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
+124
View File
@@ -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
+139
View File
@@ -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
+1 -1
View File
@@ -110,7 +110,7 @@ Loads environment variables from .env file or system and sets them.</p>
file.write(&#34;FROM python:3.11-slim\n&#34;)
file.write(&#34;WORKDIR /app\n&#34;)
file.write(&#34;COPY . .\n&#34;)
file.write(&#34;RUN pip install flask praisonai==2.0.35 gunicorn markdown\n&#34;)
file.write(&#34;RUN pip install flask praisonai==2.0.46 gunicorn markdown\n&#34;)
file.write(&#34;EXPOSE 8080\n&#34;)
file.write(&#39;CMD [&#34;gunicorn&#34;, &#34;-b&#34;, &#34;0.0.0.0:8080&#34;, &#34;api:app&#34;]\n&#39;)
@@ -0,0 +1,187 @@
---
title: "AutoAgents Module"
description: "Documentation for the praisonaiagents.agents.autoagents module"
icon: "robot"
---
# Module praisonaiagents.agents.autoagents
The AutoAgents module provides automatic creation and management of AI agents and tasks based on high-level instructions.
## Classes
### AutoAgents
The main class for automatically creating and managing AI agents and tasks.
#### Parameters
- `instructions: str` - High-level task description for the agents
- `tools: Optional[List[Any]] = None` - List of tools available to the agents
- `verbose: bool = False` - Enable detailed logging
- `process: str = "sequential"` - Process type (sequential or hierarchical)
- `manager_llm: Optional[str] = None` - Language model for manager agent
- `max_retries: int = 5` - Maximum retry attempts
- `completion_checker: Optional[Any] = None` - Custom completion checker
- `allow_code_execution: bool = False` - Allow code execution
- `memory: bool = True` - Enable agent memory
- `markdown: bool = True` - Enable markdown formatting
- `self_reflect: bool = False` - Enable agent self-reflection
- `max_reflect: int = 3` - Maximum reflection iterations
- `min_reflect: int = 1` - Minimum reflection iterations
- `llm: Optional[str] = None` - Language model for agents
- `function_calling_llm: Optional[str] = None` - Language model for tool calling
- `respect_context_window: bool = True` - Respect model context window
- `code_execution_mode: str = "safe"` - Code execution mode (safe/unsafe)
- `embedder_config: Optional[Dict[str, Any]] = None` - Embedder configuration
- `knowledge_sources: Optional[List[Any]] = None` - Knowledge sources
- `use_system_prompt: bool = True` - Use system prompts
- `cache: bool = True` - Enable caching
- `allow_delegation: bool = False` - Allow task delegation
- `step_callback: Optional[Any] = None` - Callback for each step
- `system_template: Optional[str] = None` - Custom system template
- `prompt_template: Optional[str] = None` - Custom prompt template
- `response_template: Optional[str] = None` - Custom response template
- `max_rpm: Optional[int] = None` - Maximum requests per minute
- `max_execution_time: Optional[int] = None` - Maximum execution time
- `max_iter: int = 20` - Maximum iterations
- `reflect_llm: Optional[str] = None` - Language model for reflection
- `max_agents: int = 3` - Maximum number of agents to create
#### Methods
##### start()
Start the agents synchronously.
```python
def start(self):
"""
Creates tasks based on the instructions, then starts execution.
Returns the task status and results dictionary.
"""
return super().start()
```
##### astart()
Start the agents asynchronously.
```python
async def astart(self):
"""
Async version of start() method.
Creates tasks based on the instructions, then starts execution.
Returns the task status and results dictionary.
"""
return await super().astart()
```
#### Internal Methods
##### _generate_config()
Generate the configuration for agents and tasks.
```python
def _generate_config(self) -> AutoAgentsConfig:
"""
Generate the configuration for agents and tasks based on instructions.
Returns AutoAgentsConfig object containing agent and task configurations.
"""
```
##### _create_agents_and_tasks()
Create agents and tasks from configuration.
```python
def _create_agents_and_tasks(self, config: AutoAgentsConfig) -> tuple[List[Agent], List[Task]]:
"""
Create agents and tasks based on the generated configuration.
Returns tuple of (agents, tasks).
"""
```
##### _assign_tools_to_agent()
Assign appropriate tools to an agent.
```python
def _assign_tools_to_agent(self, agent_config: AgentConfig) -> List[Any]:
"""
Assign tools to an agent based on its role and tasks.
Returns list of assigned tools.
"""
```
## Pydantic Models
### TaskConfig
Configuration for a task.
#### Attributes
- `name: str` - Task name
- `description: str` - Task description
- `expected_output: str` - Expected output description
- `tools: List[str]` - Required tools for the task
### AgentConfig
Configuration for an agent.
#### Attributes
- `name: str` - Agent name
- `role: str` - Agent role
- `goal: str` - Agent goal
- `backstory: str` - Agent backstory
- `tools: List[str]` - Required tools
- `tasks: List[TaskConfig]` - Tasks assigned to the agent
### AutoAgentsConfig
Overall configuration for AutoAgents.
#### Attributes
- `main_instruction: str` - Main instruction for the agents
- `process_type: str` - Process type (sequential/hierarchical)
- `agents: List[AgentConfig]` - List of agent configurations
## Example Usage
### Basic Usage
```python
from praisonaiagents import AutoAgents
from praisonaiagents.tools import SerperDevTool
agents = AutoAgents(
instructions="Research recent AI developments",
tools=[SerperDevTool()],
verbose=True
)
result = agents.start()
```
### Async Usage
```python
async def main():
agents = AutoAgents(
instructions="Research recent AI developments",
tools=[SerperDevTool()],
process="hierarchical"
)
result = await agents.astart()
import asyncio
asyncio.run(main())
```
### Advanced Configuration
```python
agents = AutoAgents(
instructions="Complex research task",
tools=[SerperDevTool()],
max_agents=5,
process="hierarchical",
manager_llm="gpt-4o",
memory=True,
allow_delegation=True,
max_execution_time=600,
self_reflect=True
)
```
<Note>
For optimal results, provide clear instructions and appropriate tools for your use case.
</Note>
-69
View File
@@ -1,69 +0,0 @@
---
title: Installation
description: Set up PraisonAI in your development environment
icon: download
---
<Note>
**Requirements**
- Python 3.10 or higher
- pip package manager
- Virtual environment (recommended)
</Note>
# Installing PraisonAI
Follow these steps to set up PraisonAI in your development environment.
<Steps>
<Step title="Create Virtual Environment (Optional)">
First, create and activate a virtual environment:
<CodeGroup>
```bash Mac/Linux
python -m venv praisonai-env
source praisonai-env/bin/activate
```
```bash Windows
python -m venv praisonai-env
.\praisonai-env\Scripts\activate
```
</CodeGroup>
</Step>
<Step title="Install PraisonAI">
Install the core package and tools:
```bash Terminal
pip install praisonaiagents
```
</Step>
<Step title="Configure Environment">
```bash Terminal
export OPENAI_API_KEY=your_openai_key
```
Generate your OpenAI API key from [OpenAI](https://platform.openai.com/api-keys)
You can also use other LLM providers like Anthropic, Google, etc. Please refer to the [Models](/models) for more information.
</Step>
</Steps>
## Next Steps
<CardGroup cols={2}>
<Card
title="Quick Start Guide"
icon="bolt"
href="/code/quickstart"
>
Build your first AI agent
</Card>
<Card
title="API Reference"
icon="code"
href="/api/praisonaiagents/index"
>
Explore the API documentation
</Card>
</CardGroup>
-188
View File
@@ -1,188 +0,0 @@
---
title: "Introduction"
description: "Welcome to PraisonAI - The Next Generation AI Agent Framework"
icon: "book-open"
---
<Note>
PraisonAI is a powerful framework for building and deploying AI agents that can understand, reason, and execute complex tasks autonomously.
</Note>
# What is PraisonAI?
```mermaid
graph LR
%% Define the main flow
Start([▶ Start]) --> Agent1
Agent1 --> Process[⚙ Process]
Process --> Agent2
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[" "]
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[" "]
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
```
## Core Components
<CardGroup cols={2}>
<Card title="Agents" icon="user-robot">
Autonomous AI entities that can understand context and execute tasks
</Card>
<Card title="Tasks" icon="list-check">
Units of work that agents can execute independently or collaboratively
</Card>
<Card title="Process" icon="diagram-project">
Workflow management for coordinating agent activities
</Card>
<Card title="Tools" icon="toolbox">
Extensible capabilities that agents can leverage
</Card>
</CardGroup>
## Key Features
<Steps>
<Step title="Autonomous Agents">
Create intelligent agents that can:
- Understand natural language instructions
- Make decisions based on context
- Execute complex tasks autonomously
</Step>
<Step title="Flexible Architecture">
Build with:
- Modular components
- Extensible tools
- Customizable workflows
</Step>
<Step title="Advanced Capabilities">
Leverage:
- Multi-agent collaboration
- Memory and context management
- Tool integration
</Step>
</Steps>
## Use Cases
<CardGroup cols={2}>
<Card title="Customer Service" icon="headset">
Build intelligent support agents that can handle customer inquiries and resolve issues autonomously.
</Card>
<Card title="Data Analysis" icon="chart-line">
Create agents that can process, analyze, and derive insights from complex datasets.
</Card>
<Card title="Content Creation" icon="pen-nib">
Deploy agents that can generate, edit, and optimize content across various formats.
</Card>
<Card title="Process Automation" icon="gears">
Automate complex workflows with intelligent agents that can coordinate and execute tasks.
</Card>
</CardGroup>
## Getting Started
<Warning>
Before proceeding, ensure you have Python 3.9+ installed on your system.
</Warning>
### Quick Setup
<CodeGroup>
```bash pip
pip install praisonai
```
</CodeGroup>
### Basic Example
```python
from praisonaiagents import Agent, Task, PraisonAIAgents
# Create an agent
researcher = Agent(
name="Researcher",
role="Senior Research Analyst",
goal="Uncover cutting-edge developments in AI",
backstory="You are an expert at a technology research group",
verbose=True,
llm="gpt-4o"
)
# Define a task
task = Task(
name="research_task",
description="Analyze 2024's AI advancements",
expected_output="A detailed report",
agent=researcher
)
# Run the agents
agents = PraisonAIAgents(
agents=[researcher],
tasks=[task],
verbose=False
)
result = agents.start()
```
## Next Steps
<CardGroup cols={2}>
<Card
title="Installation"
icon="download"
href="/code/installation"
>
Complete installation guide and setup instructions
</Card>
<Card
title="Quick Start"
icon="play"
href="/code/quickstart"
>
Build your first AI agent in minutes
</Card>
</CardGroup>
<Tip>
Join our community on [Discord](https://www.youtube.com/redirect?event=channel_description&redir_token=QUFFLUhqbUpiZE00YlF1MjB1LVNIeTFxTnV6MWRRc18wZ3xBQ3Jtc0ttQVZ0aFJ4RXRDanlBQU1Vd3lHU3BBcml3bzhoek1pTmlkZkFkWjlNVDBpRkxZd1dTOWhPc20xbHJOb1NibmNYeTEydklJT0pZOVJFQW93MmJOQXU0WkJNVzNsd29SZ3FBNFVwMTFGNThNSHBWVUhjSQ&q=https%3A%2F%2Fdiscord.gg%2FnNZu5gGT59) to connect with other developers and get help!
</Tip>
-195
View File
@@ -1,195 +0,0 @@
---
title: Quick Start
description: Build your first AI agent with PraisonAI
icon: bolt
---
<Steps>
<Step title="Install PraisonAI">
Install the core package:
```bash Terminal
pip install praisonaiagents
```
</Step>
<Step title="Configure Environment">
```bash Terminal
export OPENAI_API_KEY=your_openai_key
```
Generate your OpenAI API key from [OpenAI](https://platform.openai.com/api-keys)
You can also use other LLM providers like Anthropic, Google, etc. Please refer to the [Models](/models) for more information.
</Step>
<Step title="Create Agent">
Create `app.py`:
## Code Example
<CodeGroup>
```python Basic
from praisonaiagents import Agent, Task, PraisonAIAgents
# Create an agent
researcher = Agent(
name="Researcher",
role="Senior Research Analyst",
goal="Uncover cutting-edge developments in AI",
backstory="You are an expert at a technology research group",
verbose=True,
llm="gpt-4o"
)
# Define a task
task = Task(
name="research_task",
description="Analyze 2024's AI advancements",
expected_output="A detailed report",
agent=researcher
)
# Run the agents
agents = PraisonAIAgents(
agents=[researcher],
tasks=[task],
verbose=False
)
result = agents.start()
```
```python Advanced
from praisonaiagents import Agent, Task, PraisonAIAgents
# Create multiple agents
researcher = Agent(
name="Researcher",
role="Senior Research Analyst",
goal="Uncover cutting-edge developments in AI",
backstory="You are an expert at a technology research group",
verbose=True,
llm="gpt-4o",
markdown=True
)
writer = Agent(
name="Writer",
role="Tech Content Strategist",
goal="Craft compelling content on tech advancements",
backstory="You are a content strategist",
llm="gpt-4o",
markdown=True
)
# Define multiple tasks
task1 = Task(
name="research_task",
description="Analyze 2024's AI advancements",
expected_output="A detailed report",
agent=researcher
)
task2 = Task(
name="writing_task",
description="Create a blog post about AI advancements",
expected_output="A blog post",
agent=writer
)
# Run with hierarchical process
agents = PraisonAIAgents(
agents=[researcher, writer],
tasks=[task1, task2],
verbose=False,
process="hierarchical",
manager_llm="gpt-4o"
)
result = agents.start()
```
</CodeGroup>
</Step>
<Step title="Run the Program">
Execute your script:
```bash Terminal
python app.py
```
You should see:
- Agent initialization
- Agents progress
- Final results
- Generated report
</Step>
</Steps>
## Advanced Usage
### Creating Custom Tool
```python
from praisonaiagents import Agent, Task, PraisonAIAgents
from duckduckgo_search import DDGS
from typing import List, Dict
# 1. Tool
def internet_search_tool(query: str) -> List[Dict]:
"""
Perform Internet Search
"""
results = []
ddgs = DDGS()
for result in ddgs.text(keywords=query, max_results=5):
results.append({
"title": result.get("title", ""),
"url": result.get("href", ""),
"snippet": result.get("body", "")
})
return results
# 2. Agent
data_agent = Agent(
name="DataCollector",
role="Search Specialist",
goal="Perform internet searches to collect relevant information.",
backstory="Expert in finding and organising internet data.",
tools=[internet_search_tool],
self_reflect=False
)
# 3. Tasks
collect_task = Task(
description="Perform an internet search using the query: 'AI job trends in 2024'. Return results as a list of title, URL, and snippet.",
expected_output="List of search results with titles, URLs, and snippets.",
agent=data_agent,
name="collect_data",
)
# 4. Start Agents
agents = PraisonAIAgents(
agents=[data_agent],
tasks=[collect_task],
process="sequential"
)
agents.start()
```
## Next Steps
<CardGroup cols={2}>
<Card
title="Core Concepts"
icon="book"
href="/concepts/agents"
>
Learn about agents, tasks, and processes
</Card>
<Card
title="API Reference"
icon="code"
href="/api/praisonaiagents/index"
>
Explore detailed API documentation
</Card>
</CardGroup>
+237 -26
View File
@@ -105,43 +105,254 @@ graph LR
```
</CodeGroup>
## Agent Types
<Steps>
<Step title="Basic Agent">
- Single-purpose focus
- Direct user interaction
- Limited tool set
<Step title="Install PraisonAI">
Install the core package:
```bash Terminal
pip install praisonaiagents
```
</Step>
<Step title="Specialized Agent">
- Domain expertise
- Advanced capabilities
- Custom tools
<Step title="Configure Environment">
```bash Terminal
export OPENAI_API_KEY=your_openai_key
```
Generate your OpenAI API key from [OpenAI](https://platform.openai.com/api-keys)
Use other LLM providers like Ollama, Anthropic, Groq, Google, etc. Please refer to the [Models](/models) for more information.
</Step>
<Step title="Collaborative Agent">
- Team interaction
- Task delegation
- Shared context
<Step title="Create Agent">
Create `app.py`:
<CodeGroup>
```python Single Agent
from praisonaiagents import Agent, Task, PraisonAIAgents
# Create an agent
researcher = Agent(
name="Researcher",
role="Senior Research Analyst",
goal="Uncover cutting-edge developments in AI",
backstory="You are an expert at a technology research group",
verbose=True,
llm="gpt-4o"
)
# Define a task
task = Task(
name="research_task",
description="Analyze 2024's AI advancements",
expected_output="A detailed report",
agent=researcher
)
# Run the agents
agents = PraisonAIAgents(
agents=[researcher],
tasks=[task],
verbose=False
)
result = agents.start()
```
```python Multiple Agents
from praisonaiagents import Agent, Task, PraisonAIAgents
# Create multiple agents
researcher = Agent(
name="Researcher",
role="Senior Research Analyst",
goal="Uncover cutting-edge developments in AI",
backstory="You are an expert at a technology research group",
verbose=True,
llm="gpt-4o",
markdown=True
)
writer = Agent(
name="Writer",
role="Tech Content Strategist",
goal="Craft compelling content on tech advancements",
backstory="You are a content strategist",
llm="gpt-4o",
markdown=True
)
# Define multiple tasks
task1 = Task(
name="research_task",
description="Analyze 2024's AI advancements",
expected_output="A detailed report",
agent=researcher
)
task2 = Task(
name="writing_task",
description="Create a blog post about AI advancements",
expected_output="A blog post",
agent=writer
)
# Run with hierarchical process
agents = PraisonAIAgents(
agents=[researcher, writer],
tasks=[task1, task2],
verbose=False,
process="hierarchical",
manager_llm="gpt-4o"
)
result = agents.start()
```
</CodeGroup>
</Step>
<Step title="Start Agents">
Execute your script:
```bash Terminal
python app.py
```
You should see:
- Agent initialization
- Agents progress
- Final results
- Generated report
</Step>
</Steps>
## Agent Types
<CardGroup cols={3}>
<Card title="Basic Agent" icon="user" iconType="solid">
<AccordionGroup>
<Accordion title="Overview">
Perfect for straightforward tasks and direct interactions
</Accordion>
<Accordion title="Features">
- Single-purpose focus
- Direct user interaction
- Limited tool set
- Ideal for simple tasks
</Accordion>
</AccordionGroup>
</Card>
<Card title="Specialized Agent" icon="user-gear" iconType="solid">
<AccordionGroup>
<Accordion title="Overview">
Experts in specific domains with advanced capabilities
</Accordion>
<Accordion title="Features">
- Domain expertise
- Advanced capabilities
- Custom tools
- Deep knowledge base
</Accordion>
</AccordionGroup>
</Card>
<Card title="Collaborative Agent" icon="users" iconType="solid">
<AccordionGroup>
<Accordion title="Overview">
Designed for team-based operations and complex workflows
</Accordion>
<Accordion title="Features">
- Team interaction
- Task delegation
- Shared context
- Coordinated actions
</Accordion>
</AccordionGroup>
</Card>
</CardGroup>
## Best Practices
<Warning>
Always implement proper error handling and resource management in your agent configurations.
</Warning>
<Note>
Always implement proper error handling and resource management in your agent configurations.
</Note>
### Agent Design
1. Clear role definition
2. Specific, measurable goals
3. Relevant tool selection
4. Appropriate memory configuration
<CardGroup cols={2}>
<Card title="Agent Design" icon="compass-drafting" iconType="solid">
<Steps>
<Step title="Role Definition">
Define clear, specific roles for each agent
</Step>
<Step title="Goal Setting">
Set specific, measurable goals
</Step>
<Step title="Tool Selection">
Choose relevant tools for the task
</Step>
<Step title="Memory Setup">
Configure appropriate memory settings
</Step>
</Steps>
</Card>
### Agent Interaction
1. Clear communication protocols
2. Defined delegation rules
3. Error handling mechanisms
4. Resource management
<Card title="Agent Interaction" icon="network-wired" iconType="solid">
<Steps>
<Step title="Communication">
Establish clear communication protocols
</Step>
<Step title="Delegation">
Define explicit delegation rules
</Step>
<Step title="Error Handling">
Implement robust error handling
</Step>
<Step title="Resource Management">
Set up efficient resource allocation
</Step>
</Steps>
</Card>
</CardGroup>
## Async Capabilities
<CardGroup cols={1}>
<Card title="Key Features" icon="bolt" iconType="solid">
<Tabs>
<Tab title="Async Support">
```python
async def main():
agent = Agent(name="AsyncAgent")
result = await agent.aprocess_task()
```
- Full async/await support
- Non-blocking operations
- Enhanced performance
</Tab>
<Tab title="Parallel Execution">
```python
async def parallel_tasks():
tasks = [agent1.task(), agent2.task()]
results = await asyncio.gather(*tasks)
```
- Parallel task execution
- Efficient resource usage
- Improved throughput
</Tab>
<Tab title="Integration">
```python
@agent.async_tool
async def custom_tool():
async with aiohttp.ClientSession() as session:
# Async operations
pass
```
- Async tool integration
- Callback support
- Mixed sync/async operations
</Tab>
</Tabs>
</Card>
</CardGroup>
## Advanced Features
+441
View File
@@ -0,0 +1,441 @@
---
title: "AI Agents with Memory"
sidebarTitle: "Memory"
description: "Learn how to create AI agents with memory capabilities for maintaining context and information across tasks."
icon: "brain"
---
## Quick Start
<Tabs>
<Tab title="Code">
<Steps>
<Step title="Install Package">
First, install the PraisonAI Agents package:
```bash
pip install "praisonaiagents[memory]" duckduckgo_search
```
duckduckgo_search is a tool that allows agents to search the web.
It is required for the multiple agents example shown below.
</Step>
<Step title="Set API Key">
Set your OpenAI API key as an environment variable in your terminal:
```bash
export OPENAI_API_KEY=your_api_key_here
```
</Step>
<Step title="Create a file">
Create a new file `app.py` with the basic setup:
<CodeGroup>
```python Single Agent
from praisonaiagents.agents.agents import Agent, Task, PraisonAIAgents
# Create blog writer agent
blog_agent = Agent(
role="Blog Writer",
goal="Write a blog post about AI",
backstory="Expert at writing blog posts",
llm="gpt-4o-mini"
)
# Create blog writing task
blog_task = Task(
description="Write a blog post about AI trends",
expected_output="Well-written blog post about AI trends",
agent=blog_agent
)
# Create and start the agents with memory enabled
agents = PraisonAIAgents(
agents=[blog_agent],
tasks=[blog_task],
memory=True
)
# Start execution
result = agents.start()
print(result)
```
```python Multiple Agents
from praisonaiagents.agents.agents import Agent, Task, PraisonAIAgents
from praisonaiagents.tools import duckduckgo
# Create research agent with memory
research_agent = Agent(
role="Research Analyst",
goal="Research and document key information about topics",
backstory="Expert at analyzing and storing information in memory",
llm="gpt-4o-mini",
tools=[duckduckgo]
)
# Create blog writer agent
blog_agent = Agent(
role="Blog Writer",
goal="Write a blog post about the research",
backstory="Expert at writing blog posts",
llm="gpt-4o-mini"
)
# Create research task
research_task = Task(
description="Research and document key information about AI trends",
expected_output="Detailed research findings about AI trends",
agent=research_agent
)
# Create blog writing task
blog_task = Task(
description="Write a blog post about the research findings",
expected_output="Well-written blog post based on research",
agent=blog_agent
)
# Create and start the agents with advanced memory configuration
agents = PraisonAIAgents(
agents=[research_agent, blog_agent],
tasks=[research_task, blog_task],
memory=True
)
# Start execution
result = agents.start()
print(result)
```
</CodeGroup>
</Step>
<Step title="Start Agents">
Type this in your terminal to run your agents:
```bash
python app.py
```
</Step>
</Steps>
</Tab>
<Tab title="No Code">
<Steps>
<Step title="Install Package">
Install the PraisonAI package:
```bash
pip install praisonai
```
</Step>
<Step title="Set API Key">
Set your OpenAI API key as an environment variable in your terminal:
```bash
export OPENAI_API_KEY=your_api_key_here
```
</Step>
<Step title="Create a file">
Create a new file `agents.yaml` with the basic setup:
```yaml
framework: praisonai
process: sequential
memory: true
roles:
researcher:
backstory: Expert at analyzing and storing information in memory.
goal: Research and document key information about topics
role: Research Analyst
llm: gpt-4o-mini
tools:
- duckduckgo
tasks:
research_task:
description: Research and document key information about topics.
expected_output: Detailed research findings.
writer:
backstory: Expert at writing blog posts.
goal: Write a blog post about the research
role: Blog Writer
llm: gpt-4o-mini
tasks:
blog_task:
description: Write a blog post about the research.
expected_output: Well-written blog post based on research.
```
</Step>
<Step title="Start Agents">
Type this in your terminal to run your agents:
```bash
praisonai agents.yaml
```
</Step>
</Steps>
</Tab>
</Tabs>
<Note>
**Requirements**
- Python 3.10 or higher
- OpenAI API key. Generate OpenAI API key [here](https://platform.openai.com/api-keys). Use Other models using [this guide](/models).
- Basic understanding of Python
</Note>
## Understanding Memory
<Card title="What is Agent Memory?" icon="question">
Memory in AI agents enables them to:
- Maintain context across multiple tasks
- Remember previous interactions and findings
- Build upon past knowledge
- Share information between agents
- Create more coherent and contextual responses
</Card>
## Features
<CardGroup cols={2}>
<Card title="Context Retention" icon="brain">
Maintain information across multiple interactions.
</Card>
<Card title="Information Sharing" icon="share-nodes">
Share knowledge between multiple agents.
</Card>
<Card title="Long-term Storage" icon="database">
Store and retrieve information over extended periods.
</Card>
<Card title="Memory Types" icon="layer-group">
Support for different memory types (short-term, long-term).
</Card>
</CardGroup>
## Multi-Agent Memory
<Tabs>
<Tab title="Code">
```python
from praisonaiagents import Agent, Task, PraisonAIAgents
from praisonaiagents.tools import duckduckgo
# Create first agent for research
researcher = Agent(
role="Research Analyst",
goal="Research and analyze market trends",
backstory="Expert in market research and data analysis",
tools=[duckduckgo],
verbose=True
)
# Create second agent for report writing
writer = Agent(
role="Report Writer",
goal="Create comprehensive market reports",
backstory="Expert in technical writing and report creation",
verbose=True
)
# Create research task
research_task = Task(
description="Research current market trends",
expected_output="Detailed market analysis",
agent=researcher
)
# Create writing task
report_task = Task(
description="Create a market report based on research",
expected_output="Comprehensive market report",
agent=writer
)
# Create and start the agents with memory
agents = PraisonAIAgents(
agents=[researcher, writer],
tasks=[research_task, report_task],
memory=True,
process="sequential"
)
# Start execution
result = agents.start()
```
</Tab>
<Tab title="No Code">
```yaml
framework: praisonai
process: sequential
memory: true
roles:
researcher:
backstory: Expert in market research and data analysis.
goal: Research and analyze market trends
role: Research Analyst
tools:
- duckduckgo
tasks:
research_task:
description: Research current market trends.
expected_output: Detailed market analysis.
writer:
backstory: Expert in technical writing and report creation.
goal: Create comprehensive market reports
role: Report Writer
tasks:
report_task:
description: Create a market report based on research.
expected_output: Comprehensive market report.
```
</Tab>
</Tabs>
### Configuration Options
```python
# Create an agent with memory configuration
agent = Agent(
role="Research Analyst",
goal="Research and retain information",
backstory="Expert in research and analysis",
tools=[duckduckgo],
verbose=True, # Enable detailed logging
llm="gpt-4o" # Language model to use
)
# Create agents with memory options
agents = PraisonAIAgents(
agents=[agent],
tasks=[task],
memory=True, # Enable memory
memory_config={
"provider": "rag", # Use RAG for semantic search
"use_embedding": True, # Enable embeddings for better search
"short_db": ".praison/short_term.db", # Path for short-term memory
"long_db": ".praison/long_term.db", # Path for long-term memory
"rag_db_path": ".praison/chroma_db" # Path for vector database
}
)
```
## Troubleshooting
<CardGroup cols={2}>
<Card title="Memory Issues" icon="triangle-exclamation">
If memory isn't working as expected:
- Check memory configuration
- Enable verbose mode for debugging
- Verify memory provider settings
</Card>
<Card title="Context Flow" icon="code">
If context isn't being maintained:
- Review task dependencies
- Check memory configuration
- Verify agent communication
</Card>
</CardGroup>
## Next Steps
<CardGroup cols={2}>
<Card title="AutoAgents" icon="robot" href="../features/autoagents">
Learn about automatically created and managed AI agents
</Card>
<Card title="Mini Agents" icon="microchip" href="../features/mini">
Explore lightweight, focused AI agents
</Card>
</CardGroup>
<Note>
For optimal results, configure memory settings based on your specific use case requirements and expected interaction patterns.
</Note>
### Memory Configuration Options
The memory system in PraisonAI supports various configuration options to customize how agents store and retrieve information:
```python
memory_config = {
# Memory Provider
"provider": "rag", # Options: "rag", "mem0", "none"
"use_embedding": True, # Enable semantic search with embeddings
# Storage Paths
"short_db": ".praison/short_term.db", # Short-term memory SQLite DB
"long_db": ".praison/long_term.db", # Long-term memory SQLite DB
"rag_db_path": ".praison/chroma_db", # Vector database path
# Memory Settings
"ttl": 3600, # Time to live for memory items (in seconds)
# Optional Mem0 Config (if using mem0 provider)
"config": {
"api_key": "...", # Mem0 API key
"org_id": "...", # Organization ID
"project_id": "..." # Project ID
}
}
# Create agents with memory configuration
agents = PraisonAIAgents(
agents=[agent],
tasks=[task],
memory=True,
memory_config=memory_config
)
```
### Memory Types
PraisonAI's memory system includes several types of memory:
<CardGroup cols={2}>
<Card title="Short-term Memory" icon="bolt">
- Temporary storage for current context
- Automatically cleared between sessions
- Fast access for immediate task context
</Card>
<Card title="Long-term Memory" icon="database">
- Persistent storage for important information
- Semantic search capabilities with RAG
- Quality-based storage decisions
</Card>
<Card title="Entity Memory" icon="diagram-project">
- Store information about specific entities
- Track relationships and attributes
- Specialized search for entity information
</Card>
<Card title="User Memory" icon="user">
- Store user-specific information
- Personalized context for each user
- Persistent across sessions
</Card>
</CardGroup>
### Memory Quality Control
PraisonAI includes built-in quality control for memory storage:
```python
# Example of storing with quality metrics
agents.memory.store_long_term(
text="Important information to remember",
metadata={
"task_id": "task_123",
"agent": "research_agent"
},
completeness=0.9, # How complete is the information
relevance=0.85, # How relevant to the task
clarity=0.95, # How clear and well-structured
accuracy=0.9, # How accurate is the information
weights={ # Custom weights for quality score
"completeness": 0.3,
"relevance": 0.3,
"clarity": 0.2,
"accuracy": 0.2
}
)
# Search with quality filter
results = agents.memory.search_long_term(
query="search query",
min_quality=0.8, # Only return high-quality matches
limit=5 # Maximum number of results
)
```
+327 -172
View File
@@ -10,96 +10,209 @@ Process types in PraisonAI define how tasks are executed and how agents collabor
## Process Types Overview
Three types of processes are implemented in PraisonAI:
<CardGroup cols={3}>
<Card
title="Sequential Process"
icon="arrow-right"
href="/sequential-process"
>
Linear task execution in a predefined order
</Card>
<Card
title="Hierarchical Process"
icon="sitemap"
href="/hierarchical-process"
>
Manager-coordinated task execution with dynamic assignment
</Card>
<Card
title="Workflow Process"
icon="diagram-project"
href="/workflow-process"
>
Complex task flows with conditional execution and state management
</Card>
</CardGroup>
<Frame>
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
<div className="p-4 border rounded-lg bg-white dark:bg-gray-800">
<div className="flex items-center mb-4">
<div className="p-2 bg-blue-100 dark:bg-blue-900 rounded-lg">
<svg className="w-6 h-6 text-blue-600 dark:text-blue-300" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M4 6h16M4 12h16m-7 6h7" />
</svg>
</div>
<h3 className="ml-3 text-lg font-semibold">Sequential Process</h3>
</div>
<p>Linear task execution in a predefined order</p>
</div>
## Sequential Process
<div className="p-4 border rounded-lg bg-white dark:bg-gray-800">
<div className="flex items-center mb-4">
<div className="p-2 bg-green-100 dark:bg-green-900 rounded-lg">
<svg className="w-6 h-6 text-green-600 dark:text-green-300" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 6V4m0 2a2 2 0 100 4m0-4a2 2 0 110 4m-6 8a2 2 0 100-4m0 4a2 2 0 110-4m0 4v2m0-6V4m6 6v10m6-2a2 2 0 100-4m0 4a2 2 0 110-4m0 4v2m0-6V4" />
</svg>
</div>
<h3 className="ml-3 text-lg font-semibold">Hierarchical Process</h3>
</div>
<p>Manager-coordinated task execution with dynamic assignment</p>
</div>
<div className="p-4 border rounded-lg bg-white dark:bg-gray-800">
<div className="flex items-center mb-4">
<div className="p-2 bg-purple-100 dark:bg-purple-900 rounded-lg">
<svg className="w-6 h-6 text-purple-600 dark:text-purple-300" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z" />
</svg>
</div>
<h3 className="ml-3 text-lg font-semibold">Workflow Process</h3>
</div>
<p>Complex task flows with conditional execution and state management</p>
</div>
</div>
</Frame>
### Sequential Process
The simplest form of task execution where tasks are performed one after another.
<Frame>
<div className="p-4 bg-white dark:bg-gray-800 rounded-lg">
#### Characteristics
- Linear execution flow
- Predictable order
- Simple dependency management
- Direct task progression
<Card>
### Characteristics
- Linear execution flow
- Predictable order
- Simple dependency management
- Direct task progression
#### Usage
```python
agents = PraisonAIAgents(
agents=[agent1, agent2],
tasks=[task1, task2, task3],
process="sequential"
)
```
</div>
</Frame>
### Usage
```python
agents = PraisonAIAgents(
agents=[agent1, agent2],
tasks=[task1, task2, task3],
process="sequential"
)
```
</Card>
## Hierarchical Process
### Hierarchical Process
Uses a manager agent to coordinate task execution and agent assignments.
<Frame>
<div className="p-4 bg-white dark:bg-gray-800 rounded-lg">
#### Characteristics
- Manager-driven coordination
- Dynamic task assignment
- Flexible execution order
- Intelligent resource allocation
<Card>
### Characteristics
- Manager-driven coordination
- Dynamic task assignment
- Flexible execution order
- Intelligent resource allocation
#### Configuration
```python
agents = PraisonAIAgents(
agents=[manager_agent, worker_agent1, worker_agent2],
tasks=[task1, task2],
process="hierarchical",
manager_llm="gpt-4o"
)
```
</div>
</Frame>
### Configuration
```python
agents = PraisonAIAgents(
agents=[manager_agent, worker_agent1, worker_agent2],
tasks=[task1, task2],
process="hierarchical",
manager_llm="gpt-4o"
)
```
</Card>
## Workflow Process
### Workflow Process
Advanced process type supporting complex task relationships and conditional execution.
<Card>
### Features
- Task dependencies
- Conditional branching
- Loop handling
- Context sharing
- State management
### Implementation
```python
task_workflow = {
"start_task": {
"next": ["decision_task"],
"type": "task"
},
"decision_task": {
"type": "decision",
"conditions": {
"success": ["process_task"],
"failure": ["error_task"]
}
}
}
```
</Card>
## Getting Started
<Steps>
<Step title="Install PraisonAI">
Install the core package:
```bash Terminal
pip install praisonaiagents
```
</Step>
<Step title="Configure Environment">
```bash Terminal
export OPENAI_API_KEY=your_openai_key
```
Generate your OpenAI API key from [OpenAI](https://platform.openai.com/api-keys)
Use other LLM providers like Ollama, Anthropic, Groq, Google, etc. Please refer to the [Models](/models) for more information.
</Step>
<Step title="Create Agent">
Create `app.py`:
<CodeGroup>
```python Single Agent Sequential Process
from praisonaiagents import Agent, Task, PraisonAIAgents
# Create an agent
researcher = Agent(
name="Researcher",
role="Senior Research Analyst",
goal="Uncover cutting-edge developments in AI",
backstory="You are an expert at a technology research group",
verbose=True,
llm="gpt-4o"
)
# Define a task
task = Task(
name="research_task",
description="Analyze 2024's AI advancements",
expected_output="A detailed report",
agent=researcher
)
# Run the agents
agents = PraisonAIAgents(
agents=[researcher],
tasks=[task],
verbose=False,
process="sequential"
)
result = agents.start()
```
```python Multiple Agents Hierarchical Process
from praisonaiagents import Agent, Task, PraisonAIAgents
# Create multiple agents
researcher = Agent(
name="Researcher",
role="Senior Research Analyst",
goal="Uncover cutting-edge developments in AI",
backstory="You are an expert at a technology research group",
verbose=True,
llm="gpt-4o",
markdown=True
)
writer = Agent(
name="Writer",
role="Tech Content Strategist",
goal="Craft compelling content on tech advancements",
backstory="You are a content strategist",
llm="gpt-4o",
markdown=True
)
# Define multiple tasks
task1 = Task(
name="research_task",
description="Analyze 2024's AI advancements",
expected_output="A detailed report",
agent=researcher
)
task2 = Task(
name="writing_task",
description="Create a blog post about AI advancements",
expected_output="A blog post",
agent=writer
)
# Run with hierarchical process
agents = PraisonAIAgents(
agents=[researcher, writer],
tasks=[task1, task2],
verbose=False,
process="hierarchical",
manager_llm="gpt-4o"
)
result = agents.start()
```
</CodeGroup>
</Step>
</Steps>
<br /><br />
<div className="relative w-full aspect-video">
<iframe
className="absolute top-0 left-0 w-full h-full"
@@ -111,110 +224,152 @@ Advanced process type supporting complex task relationships and conditional exec
</div>
<br />
<Frame>
<div className="p-4 bg-white dark:bg-gray-800 rounded-lg">
#### Features
- Task dependencies
- Conditional branching
- Loop handling
- Context sharing
- State management
#### Implementation
```python
task_workflow = {
"start_task": {
"next": ["decision_task"],
"type": "task"
},
"decision_task": {
"type": "decision",
"conditions": {
"success": ["process_task"],
"failure": ["error_task"]
}
}
}
```
</div>
</Frame>
## Advanced Features
### State Management
- Task state tracking
- Context preservation
- Data flow control
<CardGroup cols={2}>
<Card title="State Management" icon="database" iconType="solid">
<AccordionGroup>
<Accordion title="Task State Tracking">
Monitor and manage the progress of each task in real-time
</Accordion>
<Accordion title="Context Preservation">
Maintain important information across different stages of execution
</Accordion>
<Accordion title="Data Flow Control">
Manage how data moves between tasks and agents efficiently
</Accordion>
</AccordionGroup>
</Card>
### Error Handling
- Graceful failure recovery
- Alternative path execution
- Error reporting
<Card title="Error Handling" icon="shield-check" iconType="solid">
<AccordionGroup>
<Accordion title="Graceful Recovery">
Automatically handle failures and continue execution
</Accordion>
<Accordion title="Alternative Paths">
Switch to backup plans when primary execution fails
</Accordion>
<Accordion title="Error Reporting">
Detailed error logs and diagnostic information
</Accordion>
</AccordionGroup>
</Card>
### Monitoring
- Progress tracking
- Performance metrics
- Resource utilization
<Card title="Monitoring" icon="chart-line" iconType="solid">
<AccordionGroup>
<Accordion title="Progress Tracking">
Real-time visibility into task completion status
</Accordion>
<Accordion title="Performance Metrics">
Measure execution time and resource efficiency
</Accordion>
<Accordion title="Resource Usage">
Monitor system resource utilization
</Accordion>
</AccordionGroup>
</Card>
### Integration
- External system coordination
- API synchronization
- Event handling
<Card title="Integration" icon="plug" iconType="solid">
<AccordionGroup>
<Accordion title="External Systems">
Connect with other services and platforms
</Accordion>
<Accordion title="API Sync">
Maintain data consistency across systems
</Accordion>
<Accordion title="Event Handling">
React to system and external events
</Accordion>
</AccordionGroup>
</Card>
</CardGroup>
## Async Process Execution
All process types (sequential, workflow, hierarchical) support async execution through async generators. This enables efficient handling of async tasks and parallel processing.
## Async Processing
### Async Process Methods
- `asequential`: Async version of sequential process
- `aworkflow`: Async version of workflow process
- `ahierarchical`: Async version of hierarchical process
<Note>
All process types support asynchronous execution through async generators, enabling efficient parallel processing and non-blocking operations.
</Note>
### Example Usage:
### Core Async Methods
```python
import asyncio
from praisonaiagents import Agent, Task, PraisonAIAgents
<CardGroup cols={3}>
<Card title="asequential" icon="arrow-right">
Async version of sequential process for non-blocking linear execution
</Card>
<Card title="aworkflow" icon="diagram-project">
Async workflow process for complex parallel task execution
</Card>
<Card title="ahierarchical" icon="sitemap">
Async hierarchical process for distributed task management
</Card>
</CardGroup>
async def main():
# Create agents and tasks
agents = [async_agent1, async_agent2]
tasks = [async_task1, async_task2]
### Process-Specific Features
# Initialize PraisonAIAgents with async workflow
agents = PraisonAIAgents(
agents=agents,
tasks=tasks,
process="workflow" # or "sequential" or "hierarchical"
)
<Tabs>
<Tab title="Sequential Process">
<Card>
- Tasks execute in order but don't block
- Maintains sequence while allowing async operations
- Perfect for I/O-heavy tasks
```python
async def main():
agents = PraisonAIAgents(
process="sequential",
async_mode=True
)
await agents.astart()
```
</Card>
</Tab>
<Tab title="Workflow Process">
<Card>
- Parallel execution of independent tasks
- Async branching and merging
- Dynamic task scheduling based on conditions
```python
async def main():
agents = PraisonAIAgents(
process="workflow",
async_mode=True,
parallel_tasks=True
)
await agents.astart()
```
</Card>
</Tab>
<Tab title="Hierarchical Process">
<Card>
- Async manager delegation
- Parallel subtask execution
- Dynamic worker assignment
```python
async def main():
agents = PraisonAIAgents(
process="hierarchical",
async_mode=True,
dynamic_assignment=True
)
await agents.astart()
```
</Card>
</Tab>
</Tabs>
# Start async execution
result = await agents.astart()
print(result)
### Key Benefits
# Run the async workflow
asyncio.run(main())
```
### Async Process Features:
- Parallel task execution in workflow
- Async task delegation in hierarchical process
- Non-blocking task execution
- Efficient resource utilization
- Mixed sync/async task support
### Process-Specific Async Behavior:
1. **Sequential Process**:
- Tasks are executed in order
- Async tasks don't block other tasks
- Maintains sequential order while allowing async execution
2. **Workflow Process**:
- Parallel execution of independent tasks
- Async branching and merging
- Dynamic task scheduling
3. **Hierarchical Process**:
- Async manager delegation
- Parallel subtask execution
- Dynamic task assignment
<CardGroup cols={2}>
<Card title="Performance" icon="bolt">
- Efficient resource utilization
- Reduced waiting time
- Better throughput
</Card>
<Card title="Flexibility" icon="puzzle-piece">
- Mix sync and async tasks
- Adaptable execution patterns
- Easy scaling
</Card>
</CardGroup>
+365 -179
View File
@@ -8,114 +8,6 @@ icon: "list-check"
Tasks are the fundamental units of work in PraisonAI, defining what needs to be done, how it should be done, and who should do it.
</Note>
# Understanding Tasks
<Frame>
<div className="p-6 bg-white dark:bg-gray-800 rounded-lg">
<div className="grid grid-cols-1 gap-6">
{/* Task Flow Steps */}
<div className="flex justify-between items-center">
{/* Task Definition */}
<div className="flex-1 p-4 border-2 border-blue-500 rounded-lg text-center">
<div className="flex items-center justify-center mb-2">
<div className="p-2 bg-blue-100 dark:bg-blue-900 rounded-full">
<svg className="w-6 h-6 text-blue-600 dark:text-blue-300" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2" />
</svg>
</div>
</div>
<h4 className="font-semibold">Task Definition</h4>
<p className="text-sm mt-1">Description & Requirements</p>
</div>
{/* Arrow 1 */}
<div className="flex-none px-4">
<svg className="w-6 h-6 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M17 8l4 4m0 0l-4 4m4-4H3" />
</svg>
</div>
{/* Agent Assignment */}
<div className="flex-1 p-4 border-2 border-green-500 rounded-lg text-center">
<div className="flex items-center justify-center mb-2">
<div className="p-2 bg-green-100 dark:bg-green-900 rounded-full">
<svg className="w-6 h-6 text-green-600 dark:text-green-300" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z" />
</svg>
</div>
</div>
<h4 className="font-semibold">Agent Assignment</h4>
<p className="text-sm mt-1">Matching & Delegation</p>
</div>
{/* Arrow 2 */}
<div className="flex-none px-4">
<svg className="w-6 h-6 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M17 8l4 4m0 0l-4 4m4-4H3" />
</svg>
</div>
{/* Execution */}
<div className="flex-1 p-4 border-2 border-purple-500 rounded-lg text-center">
<div className="flex items-center justify-center mb-2">
<div className="p-2 bg-purple-100 dark:bg-purple-900 rounded-full">
<svg className="w-6 h-6 text-purple-600 dark:text-purple-300" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M13 10V3L4 14h7v7l9-11h-7z" />
</svg>
</div>
</div>
<h4 className="font-semibold">Execution</h4>
<p className="text-sm mt-1">Processing & Tools</p>
</div>
{/* Arrow 3 */}
<div className="flex-none px-4">
<svg className="w-6 h-6 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M17 8l4 4m0 0l-4 4m4-4H3" />
</svg>
</div>
{/* Output */}
<div className="flex-1 p-4 border-2 border-yellow-500 rounded-lg text-center">
<div className="flex items-center justify-center mb-2">
<div className="p-2 bg-yellow-100 dark:bg-yellow-900 rounded-full">
<svg className="w-6 h-6 text-yellow-600 dark:text-yellow-300" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M8 9l3 3-3 3m5 0h3M5 20h14a2 2 0 002-2V6a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z" />
</svg>
</div>
</div>
<h4 className="font-semibold">Output</h4>
<p className="text-sm mt-1">Results & Validation</p>
</div>
</div>
{/* Task States */}
<div className="grid grid-cols-4 gap-4 mt-4">
<div className="p-3 border border-gray-200 rounded-lg bg-blue-50 dark:bg-blue-900">
<div className="flex items-center justify-center">
<span className="font-semibold">Pending</span>
</div>
</div>
<div className="p-3 border border-gray-200 rounded-lg bg-yellow-50 dark:bg-yellow-900">
<div className="flex items-center justify-center">
<span className="font-semibold">In Progress</span>
</div>
</div>
<div className="p-3 border border-gray-200 rounded-lg bg-green-50 dark:bg-green-900">
<div className="flex items-center justify-center">
<span className="font-semibold">Completed</span>
</div>
</div>
<div className="p-3 border border-gray-200 rounded-lg bg-red-50 dark:bg-red-900">
<div className="flex items-center justify-center">
<span className="font-semibold">Failed</span>
</div>
</div>
</div>
</div>
</div>
</Frame>
## Core Components
<CardGroup cols={2}>
@@ -155,6 +47,79 @@ icon: "list-check"
```
</CodeGroup>
# Understanding Tasks
<br />
```mermaid
graph LR
%% Task Flow Steps
Start([▶ Start]) --> TaskDef
TaskDef --> AgentAssign
AgentAssign --> Exec
Exec --> Output([✓ Output])
%% Define subgraphs for each step
subgraph TaskDef[" "]
TD_Icon[📋 Task Definition]
TD_Desc[Description & Requirements]
TD_Icon --- TD_Desc
style TD_Icon fill:#2D3047,stroke:#7C90A0,color:#fff
style TD_Desc fill:#5C80BC,stroke:#7C90A0,color:#fff
end
subgraph AgentAssign[" "]
AA_Icon[🤖 Agent Assignment]
AA_Desc[Matching & Delegation]
AA_Icon --- AA_Desc
style AA_Icon fill:#2D3047,stroke:#7C90A0,color:#fff
style AA_Desc fill:#5C80BC,stroke:#7C90A0,color:#fff
end
subgraph Exec[" "]
E_Icon[⚙️ Execution]
E_Desc[Processing & Tools]
E_Icon --- E_Desc
style E_Icon fill:#2D3047,stroke:#7C90A0,color:#fff
style E_Desc fill:#5C80BC,stroke:#7C90A0,color:#fff
end
%% Styling for main elements
style Start fill:#2D3047,stroke:#7C90A0,color:#fff
style Output fill:#2D3047,stroke:#7C90A0,color:#fff
%% Style for containers
style TaskDef fill:#1B1F3B,stroke:#7C90A0,color:#fff
style AgentAssign fill:#1B1F3B,stroke:#7C90A0,color:#fff
style Exec fill:#1B1F3B,stroke:#7C90A0,color:#fff
%% Global styles
classDef default fill:#2D3047,stroke:#7C90A0,color:#fff
linkStyle default stroke:#7C90A0,stroke-width:2px
```
<br /><br />
```mermaid
graph LR
%% Task States
Pending([📥 Pending]) --> InProgress([⚡ In Progress])
InProgress --> Completed([✅ Completed])
InProgress --> Failed([❌ Failed])
%% Styling
style Pending fill:#2D3047,stroke:#7C90A0,color:#fff
style InProgress fill:#5C80BC,stroke:#7C90A0,color:#fff
style Completed fill:#2D3047,stroke:#7C90A0,color:#fff
style Failed fill:#2D3047,stroke:#7C90A0,color:#fff
%% Global styles
classDef default fill:#2D3047,stroke:#7C90A0,color:#fff
linkStyle default stroke:#7C90A0,stroke-width:2px
```
## Task Types
<Steps>
@@ -223,17 +188,300 @@ task_b = Task(
</Card>
</CardGroup>
## Getting Started
<Steps>
<Step title="Install PraisonAI">
Install the core package:
```bash Terminal
pip install praisonaiagents
```
</Step>
<Step title="Configure Environment">
```bash Terminal
export OPENAI_API_KEY=your_openai_key
```
Generate your OpenAI API key from [OpenAI](https://platform.openai.com/api-keys)
Use other LLM providers like Ollama, Anthropic, Groq, Google, etc. Please refer to the [Models](/models) for more information.
</Step>
<Step title="Create Agent">
Create `app.py`:
<CodeGroup>
```python Single Agent
from praisonaiagents import Agent, Task, PraisonAIAgents
# Create an agent
researcher = Agent(
name="Researcher",
role="Senior Research Analyst",
goal="Uncover cutting-edge developments in AI",
backstory="You are an expert at a technology research group",
verbose=True,
llm="gpt-4o"
)
# Define a task
task = Task(
name="research_task",
description="Analyze 2024's AI advancements",
expected_output="A detailed report",
agent=researcher
)
# Run the agents
agents = PraisonAIAgents(
agents=[researcher],
tasks=[task],
verbose=False
)
result = agents.start()
```
```python Multiple Agents
from praisonaiagents import Agent, Task, PraisonAIAgents
# Create multiple agents
researcher = Agent(
name="Researcher",
role="Senior Research Analyst",
goal="Uncover cutting-edge developments in AI",
backstory="You are an expert at a technology research group",
verbose=True,
llm="gpt-4o",
markdown=True
)
writer = Agent(
name="Writer",
role="Tech Content Strategist",
goal="Craft compelling content on tech advancements",
backstory="You are a content strategist",
llm="gpt-4o",
markdown=True
)
# Define multiple tasks
task1 = Task(
name="research_task",
description="Analyze 2024's AI advancements",
expected_output="A detailed report",
agent=researcher
)
task2 = Task(
name="writing_task",
description="Create a blog post about AI advancements",
expected_output="A blog post",
agent=writer
)
# Run with hierarchical process
agents = PraisonAIAgents(
agents=[researcher, writer],
tasks=[task1, task2],
verbose=False,
process="hierarchical",
manager_llm="gpt-4o"
)
result = agents.start()
```
</CodeGroup>
</Step>
</Steps>
## Best Practices
<Tip>
Design tasks to be atomic and focused. Each task should have a single, clear responsibility.
</Tip>
<Note>
Design tasks to be atomic and focused. Each task should have a single, clear responsibility.
</Note>
1. Clear task descriptions
2. Well-defined success criteria
3. Appropriate tool selection
4. Error handling consideration
5. Resource management
<CardGroup cols={2}>
<Card title="Task Design Principles" icon="compass-drafting" iconType="solid">
<AccordionGroup>
<Accordion title="Clear Task Descriptions">
Write precise, unambiguous task descriptions that clearly state the task's purpose and requirements.
```python
task = Task(
description=(
"Analyze Q4 2024 sales data "
"and generate growth metrics"
),
expected_output="Sales growth report"
)
```
</Accordion>
<Accordion title="Success Criteria">
Define measurable success criteria to ensure task completion can be properly evaluated.
```python
task = Task(
success_criteria={
"format": "markdown",
"metrics": [
"growth_rate",
"revenue_change"
],
"min_confidence": 0.95
}
)
```
</Accordion>
<Accordion title="Task Dependencies">
Specify any dependencies or prerequisites for the task.
```python
task = Task(
description="Generate final report",
dependencies=[
data_collection_task,
analysis_task
],
wait_for_dependencies=True
)
```
</Accordion>
</AccordionGroup>
</Card>
<Card title="Resource Management" icon="server" iconType="solid">
<AccordionGroup>
<Accordion title="Tool Selection">
Choose appropriate tools that match your task's requirements.
```python
task = Task(
tools=[
DataAnalyzer(),
ReportGenerator(),
MetricsCalculator()
],
tool_config={
"timeout": 30,
"retry": True
}
)
```
</Accordion>
<Accordion title="Error Handling">
Implement comprehensive error management strategies.
```python
task = Task(
error_strategy="retry",
max_retries=3,
fallback_handler=handler,
error_callbacks=[
log_error,
notify_admin
]
)
```
</Accordion>
<Accordion title="Resource Limits">
Set appropriate resource constraints for optimal performance.
```python
task = Task(
memory_limit="2GB",
timeout=300,
max_concurrent=5,
cpu_priority="high",
auto_scale=True
)
```
</Accordion>
<Accordion title="Performance Monitoring">
Configure monitoring and logging for task execution.
```python
task = Task(
monitoring={
"metrics": ["duration", "memory", "cpu"],
"log_level": "INFO",
"trace_enabled": True,
"alert_threshold": 0.85
}
)
```
</Accordion>
</AccordionGroup>
</Card>
</CardGroup>
## Async Task Execution
<CardGroup cols={1}>
<Card title="Async Task Features" icon="bolt" iconType="solid">
<Tabs>
<Tab title="Basic Configuration">
```python
async_task = Task(
description="Perform async operation",
expected_output="Async result",
agent=async_agent,
async_execution=True, # Enable async execution
callback=async_callback # Optional async callback
)
```
- Enable async execution with `async_execution=True`
- Perfect for I/O-heavy operations
- Supports parallel task execution
</Tab>
<Tab title="Async Callbacks">
```python
async def async_callback(output: TaskOutput):
await asyncio.sleep(1) # Simulate async operation
print(f"Processed output: {output.raw}")
task = Task(
description="Task with async callback",
expected_output="Result",
agent=agent,
async_execution=True,
callback=async_callback
)
```
- Support for async callbacks
- Process results asynchronously
- Handle task completion events
</Tab>
<Tab title="Mixed Execution">
```python
# Create mixed task types
sync_task = Task(
description="Synchronous operation",
async_execution=False
)
async_task = Task(
description="Asynchronous operation",
async_execution=True
)
# Run with mixed execution
agents = PraisonAIAgents(
agents=[sync_agent, async_agent],
tasks=[sync_task, async_task]
)
result = await agents.astart()
```
- Mix sync and async tasks
- Flexible execution patterns
- Optimal resource utilization
</Tab>
</Tabs>
</Card>
</CardGroup>
<Tip>
**Pro Tip**: Use async execution for tasks that involve I/O operations (like API calls or file operations) to improve overall performance. Keep CPU-intensive tasks synchronous.
</Tip>
## Next Steps
@@ -252,66 +500,4 @@ task_b = Task(
>
Explore the complete Task API documentation
</Card>
</CardGroup>
## Async Task Execution
Tasks can be executed asynchronously by setting `async_execution=True`. This is particularly useful for tasks that involve I/O operations or when you want to run multiple tasks in parallel.
### Async Task Configuration
```python
async_task = Task(
description="Perform async operation",
expected_output="Async result",
agent=async_agent,
async_execution=True, # Enable async execution
callback=async_callback # Optional async callback
)
```
### Async Callbacks
Tasks support both synchronous and asynchronous callbacks:
```python
async def async_callback(output: TaskOutput):
await asyncio.sleep(1) # Simulate async operation
print(f"Processed output: {output.raw}")
# Task with async callback
task = Task(
description="Task with async callback",
expected_output="Result",
agent=agent,
async_execution=True,
callback=async_callback
)
```
### Mixing Sync and Async Tasks
You can mix synchronous and asynchronous tasks in the same workflow:
```python
# Sync task
sync_task = Task(
description="Synchronous operation",
expected_output="Sync result",
agent=sync_agent,
async_execution=False
)
# Async task
async_task = Task(
description="Asynchronous operation",
expected_output="Async result",
agent=async_agent,
async_execution=True
)
# Create agents with mixed tasks
agents = PraisonAIAgents(
agents=[sync_agent, async_agent],
tasks=[sync_task, async_task]
)
# Run asynchronously
result = await agents.astart()
```
</CardGroup>
+501 -226
View File
@@ -8,48 +8,6 @@ icon: "screwdriver-wrench"
Tools in PraisonAI are functions that agents can use to interact with external systems, perform computations, or access data. They extend the capabilities of agents beyond just language processing.
## Tools Overview
<Frame>
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
<div className="p-4 border rounded-lg bg-white dark:bg-gray-800">
<div className="flex items-center mb-4">
<div className="p-2 bg-blue-100 dark:bg-blue-900 rounded-lg">
<svg className="w-6 h-6 text-blue-600 dark:text-blue-300" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" />
</svg>
</div>
<h3 className="ml-3 text-lg font-semibold">Search Tools</h3>
</div>
<p>Tools for searching and retrieving information from various sources</p>
</div>
<div className="p-4 border rounded-lg bg-white dark:bg-gray-800">
<div className="flex items-center mb-4">
<div className="p-2 bg-green-100 dark:bg-green-900 rounded-lg">
<svg className="w-6 h-6 text-green-600 dark:text-green-300" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M8 7v8a2 2 0 002 2h6M8 7V5a2 2 0 012-2h4.586a1 1 0 01.707.293l4.414 4.414a1 1 0 01.293.707V15a2 2 0 01-2 2h-2M8 7H6a2 2 0 00-2 2v10a2 2 0 002 2h8a2 2 0 002-2v-2" />
</svg>
</div>
<h3 className="ml-3 text-lg font-semibold">File Tools</h3>
</div>
<p>Tools for reading, writing, and manipulating files</p>
</div>
<div className="p-4 border rounded-lg bg-white dark:bg-gray-800">
<div className="flex items-center mb-4">
<div className="p-2 bg-purple-100 dark:bg-purple-900 rounded-lg">
<svg className="w-6 h-6 text-purple-600 dark:text-purple-300" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M3 6l3 1m0 0l-3 9a5.002 5.002 0 006.001 0M6 7l3 9M6 7l6-2m6 2l3-1m-3 1l-3 9a5.002 5.002 0 006.001 0M18 7l3 9m-3-9l-6-2m0-2v2m0 16V5m0 16H9m3 0h3" />
</svg>
</div>
<h3 className="ml-3 text-lg font-semibold">API Tools</h3>
</div>
<p>Tools for interacting with external APIs and services</p>
</div>
</div>
</Frame>
## Creating Custom Tool
<Steps>
<Step>
@@ -99,237 +57,554 @@ Assign the tool to an agent
</Card>
## Implementing Tools Full Code Example
<Tabs>
Tools are implemented as Python functions with type hints and docstrings. Here's a complete example:
<Tab title="Code">
<Steps>
<Step title="Install PraisonAI">
Install the core package:
```bash Terminal
pip install praisonaiagents duckduckgo-search
```
</Step>
```python
from praisonaiagents import Agent, Task, PraisonAIAgents
from duckduckgo_search import DDGS
from typing import List, Dict
<Step title="Configure Environment">
```bash Terminal
export OPENAI_API_KEY=your_openai_key
```
Generate your OpenAI API key from [OpenAI](https://platform.openai.com/api-keys)
Use other LLM providers like Ollama, Anthropic, Groq, Google, etc. Please refer to the [Models](/models) for more information.
</Step>
# 1. Tool Implementation
def internet_search_tool(query: str) -> List[Dict]:
"""
Perform Internet Search using DuckDuckGo
<Step title="Create Agent with Tool">
Create `app.py`
```python
from praisonaiagents import Agent, Task, PraisonAIAgents
from duckduckgo_search import DDGS
from typing import List, Dict
# 1. Tool Implementation
def internet_search_tool(query: str) -> List[Dict]:
"""
Perform Internet Search using DuckDuckGo
Args:
query (str): The search query string
Args:
query (str): The search query string
Returns:
List[Dict]: List of search results containing title, URL, and snippet
"""
results = []
ddgs = DDGS()
for result in ddgs.text(keywords=query, max_results=5):
results.append({
"title": result.get("title", ""),
"url": result.get("href", ""),
"snippet": result.get("body", "")
})
return results
Returns:
List[Dict]: List of search results containing title, URL, and snippet
"""
results = []
ddgs = DDGS()
for result in ddgs.text(keywords=query, max_results=5):
results.append({
"title": result.get("title", ""),
"url": result.get("href", ""),
"snippet": result.get("body", "")
})
return results
# 2. Assign the tool to an agent
data_agent = Agent(
name="DataCollector",
role="Search Specialist",
goal="Perform internet searches to collect relevant information.",
backstory="Expert in finding and organising internet data.",
tools=[internet_search_tool],
self_reflect=False
)
# 2. Assign the tool to an agent
data_agent = Agent(
name="DataCollector",
role="Search Specialist",
goal="Perform internet searches to collect relevant information.",
backstory="Expert in finding and organising internet data.",
tools=[internet_search_tool],
self_reflect=False
)
# 3. Task Definition
collect_task = Task(
description="Perform an internet search using the query: 'AI job trends in 2024'. Return results as a list of title, URL, and snippet.",
expected_output="List of search results with titles, URLs, and snippets.",
agent=data_agent,
name="collect_data",
)
# 3. Task Definition
collect_task = Task(
description="Perform an internet search using the query: 'AI job trends in 2024'. Return results as a list of title, URL, and snippet.",
expected_output="List of search results with titles, URLs, and snippets.",
agent=data_agent,
name="collect_data",
)
# 4. Start Agents
agents = PraisonAIAgents(
agents=[data_agent],
tasks=[collect_task],
process="sequential"
)
# 4. Start Agents
agents = PraisonAIAgents(
agents=[data_agent],
tasks=[collect_task],
process="sequential"
)
agents.start()
```
agents.start()
```
</Step>
<Step title="Start Agents">
Execute your script:
```bash Terminal
python app.py
```
</Step>
</Steps>
</Tab>
<Tab title="No Code">
<Steps>
<Step title="Install PraisonAI">
Install the core package and duckduckgo_search package:
```bash Terminal
pip install praisonai duckduckgo_search
```
</Step>
<Step title="Create Custom Tool">
<Info>
To add additional tools/features you need some coding which can be generated using ChatGPT or any LLM
</Info>
Create a new file `tools.py` with the following content:
```python
from duckduckgo_search import DDGS
from typing import List, Dict
# 1. Tool
def internet_search_tool(query: str) -> List[Dict]:
"""
Perform Internet Search
"""
results = []
ddgs = DDGS()
for result in ddgs.text(keywords=query, max_results=5):
results.append({
"title": result.get("title", ""),
"url": result.get("href", ""),
"snippet": result.get("body", "")
})
return results
```
</Step>
<Step title="Create Agent">
Create a new file `agents.yaml` with the following content:
```yaml
framework: praisonai
topic: create movie script about cat in mars
roles:
scriptwriter:
backstory: Expert in dialogue and script structure, translating concepts into
scripts.
goal: Write a movie script about a cat in Mars
role: Scriptwriter
tools:
- internet_search_tool # <-- Tool assigned to Agent here
tasks:
scriptwriting_task:
description: Turn the story concept into a production-ready movie script,
including dialogue and scene details.
expected_output: Final movie script with dialogue and scene details.
```
</Step>
<Step title="Start Agents">
Execute your script:
```bash Terminal
praisonai agents.yaml
```
</Step>
</Steps>
</Tab>
</Tabs>
## In-build Tools in PraisonAI
<CardGroup cols={2}>
<Card title="Search Tools" icon="magnifying-glass" href="/tools/search">
Tools for searching and retrieving information from various sources
</Card>
<Card title="Python Tools" icon="python" href="/tools/python_tools">
Essential Python utilities for data manipulation and scripting
</Card>
<Card title="Spider Tools" icon="spider" href="/tools/spider_tools">
Web crawling and scraping capabilities for data extraction
</Card>
<Card title="Arxiv Tools" icon="book" href="/tools/arxiv_tools">
Access and search academic papers from arXiv repository
</Card>
<Card title="Newspaper Tools" icon="newspaper" href="/tools/newspaper_tools">
Extract and parse content from news articles and websites
</Card>
<Card title="DuckDB Tools" icon="database" href="/tools/duckdb_tools">
Fast analytical SQL database operations and queries
</Card>
<Card title="DuckDuckGo Tools" icon="duck" href="/tools/duckduckgo_tools">
Web search functionality using DuckDuckGo's API
</Card>
<Card title="Calculator Tools" icon="calculator" href="/tools/calculator_tools">
Perform mathematical calculations and conversions
</Card>
<Card title="YAML Tools" icon="file-code" href="/tools/yaml_tools">
Parse and manipulate YAML format data
</Card>
<Card title="JSON Tools" icon="brackets-curly" href="/tools/json_tools">
Handle JSON data structures and operations
</Card>
<Card title="Pandas Tools" icon="table" href="/tools/pandas_tools">
Data analysis and manipulation using Pandas
</Card>
<Card title="YFinance Tools" icon="chart-line" href="/tools/yfinance_tools">
Fetch financial market data from Yahoo Finance
</Card>
<Card title="Shell Tools" icon="terminal" href="/tools/shell_tools">
Execute shell commands and system operations
</Card>
<Card title="Wikipedia Tools" icon="book-open" href="/tools/wikipedia_tools">
Access and search Wikipedia articles and data
</Card>
<Card title="XML Tools" icon="code" href="/tools/xml_tools">
Process and manipulate XML format data
</Card>
<Card title="File Tools" icon="file" href="/tools/file_tools">
File system operations and management utilities
</Card>
<Card title="Excel Tools" icon="file-excel" href="/tools/excel_tools">
Work with Excel spreadsheets and workbooks
</Card>
<Card title="CSV Tools" icon="file-csv" href="/tools/csv_tools">
Handle CSV file operations and transformations
</Card>
</CardGroup>
## Tools Overview
<CardGroup cols={3}>
<Card
title="Search Tools"
icon="magnifying-glass"
iconType="solid"
>
Tools for searching and retrieving information from various sources
</Card>
<Card
title="File Tools"
icon="file"
iconType="solid"
>
Tools for reading, writing, and manipulating files
</Card>
<Card
title="API Tools"
icon="code"
iconType="solid"
>
Tools for interacting with external APIs and services
</Card>
</CardGroup>
## Advanced Tool Features
### Tool Configuration
<Frame>
<div className="p-4 bg-white dark:bg-gray-800 rounded-lg">
```python
def configured_tool(
query: str,
max_results: int = 5,
timeout: int = 10
) -> List[Dict]:
"""
Example of a configurable tool
```python
def configured_tool(
query: str,
max_results: int = 5,
timeout: int = 10
) -> List[Dict]:
"""
Example of a configurable tool
Args:
query (str): Search query
max_results (int): Maximum number of results
timeout (int): Request timeout in seconds
Args:
query (str): Search query
max_results (int): Maximum number of results
timeout (int): Request timeout in seconds
Returns:
List[Dict]: Search results
"""
# Tool implementation
pass
```
</div>
Returns:
List[Dict]: Search results
"""
# Tool implementation
pass
```
</Frame>
### Tool Chaining
<Frame>
<div className="p-4 bg-white dark:bg-gray-800 rounded-lg">
```python
def chain_tools(input_data: str) -> Dict:
"""
Example of chaining multiple tools
```python
def chain_tools(input_data: str) -> Dict:
"""
Example of chaining multiple tools
Args:
input_data (str): Input data
Args:
input_data (str): Input data
Returns:
Dict: Processed results
"""
# 1. Search for data
search_results = internet_search_tool(input_data)
# 2. Process results
processed_data = process_tool(search_results)
# 3. Format output
return format_tool(processed_data)
```
</div>
Returns:
Dict: Processed results
"""
# 1. Search for data
search_results = internet_search_tool(input_data)
# 2. Process results
processed_data = process_tool(search_results)
# 3. Format output
return format_tool(processed_data)
```
</Frame>
### Tool Categories
1. **Data Collection Tools**
- Web scraping
- API integration
- Database queries
2. **Processing Tools**
- Data transformation
- Text analysis
- Image processing
3. **Output Tools**
- File generation
- Report creation
- Data visualization
<CardGroup cols={3}>
<Card title="Data Collection Tools">
- Web scraping
- API integration
- Database queries
</Card>
<Card title="Processing Tools">
- Data transformation
- Text analysis
- Image processing
</Card>
<Card title="Output Tools">
- File generation
- Report creation
- Data visualization
</Card>
</CardGroup>
## Tool Integration
### Adding Tools to Agents
<Frame>
<div className="p-4 bg-white dark:bg-gray-800 rounded-lg">
```python
# Multiple tools
agent = Agent(
name="MultiTool Agent",
tools=[
internet_search_tool,
file_processing_tool,
api_integration_tool
]
)
```
</div>
```python
# Multiple tools
agent = Agent(
name="MultiTool Agent",
tools=[
internet_search_tool,
file_processing_tool,
api_integration_tool
]
)
```
</Frame>
### Tool Dependencies
<Frame>
<div className="p-4 bg-white dark:bg-gray-800 rounded-lg">
```python
# Tool with dependencies
def advanced_tool(data: Dict) -> Dict:
"""
Tool that depends on external libraries
```python
# Tool with dependencies
def advanced_tool(data: Dict) -> Dict:
"""
Tool that depends on external libraries
Args:
data (Dict): Input data
Args:
data (Dict): Input data
Returns:
Dict: Processed data
"""
try:
import required_library
# Tool implementation
return processed_result
except ImportError:
raise Exception("Required library not installed")
```
</div>
Returns:
Dict: Processed data
"""
try:
import required_library
# Tool implementation
return processed_result
except ImportError:
raise Exception("Required library not installed")
```
</Frame>
## Tool Guidelines
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
<div className="p-4 border rounded-lg bg-white dark:bg-gray-800">
<h3 className="text-lg font-semibold mb-3">Best Practices</h3>
1. **Type Hints**
- Use Python type hints
- Define clear input/output types
- Document complex types
2. **Documentation**
- Write clear docstrings
- Explain parameters
- Provide usage examples
<CardGroup cols={2}>
<Card title="Best Practices">
1. **Type Hints**
- Use Python type hints
- Define clear input/output types
- Document complex types
3. **Error Handling**
- Handle exceptions gracefully
- Return meaningful errors
- Validate inputs
</div>
2. **Documentation**
- Write clear docstrings
- Explain parameters
- Provide usage examples
<div className="p-4 border rounded-lg bg-white dark:bg-gray-800">
<h3 className="text-lg font-semibold mb-3">Tool Types</h3>
1. **Search Tools**
- Web search
- Database queries
- Document search
3. **Error Handling**
- Handle exceptions gracefully
- Return meaningful errors
- Validate inputs
</Card>
2. **File Tools**
- Read/write operations
- File conversion
- Data extraction
<Card title="Tool Types">
1. **Search Tools**
- Web search
- Database queries
- Document search
3. **API Tools**
- REST API calls
- GraphQL queries
- Service integration
</div>
</div>
2. **File Tools**
- Read/write operations
- File conversion
- Data extraction
3. **API Tools**
- REST API calls
- GraphQL queries
- Service integration
</Card>
</CardGroup>
## Best Practices Summary
1. **Design Principles**
- Single responsibility
- Clear interfaces
- Proper documentation
- Error handling
<Note>
Following these best practices will help you create robust, efficient, and secure tools in PraisonAI.
</Note>
2. **Performance**
- Efficient processing
- Resource management
- Caching when appropriate
- Asynchronous operations
<CardGroup cols={1}>
<Card title="Design Principles" icon="compass-drafting" iconType="solid">
<AccordionGroup>
<Accordion title="Single Responsibility">
Each tool should have one clear purpose and do it well. Avoid creating tools that try to do too many things.
```python
# Good Example
def process_image(image: np.array) -> np.array:
return processed_image
3. **Security**
- Input validation
- Rate limiting
- API key management
- Error masking
# Avoid
def process_and_save_and_upload(image):
# Too many responsibilities
pass
```
</Accordion>
<Accordion title="Clear Interfaces">
Define explicit input/output types and maintain consistent parameter naming.
```python
def search_tool(
query: str,
max_results: int = 10
) -> List[Dict[str, Any]]:
"""
Search for information with clear parameters
"""
pass
```
</Accordion>
<Accordion title="Documentation">
Always include detailed docstrings and type hints.
```python
def analyze_text(
text: str,
language: str = "en"
) -> Dict[str, float]:
"""
Analyze text sentiment and emotions.
Args:
text: Input text to analyze
language: ISO language code
Returns:
Dict with sentiment scores
"""
pass
```
</Accordion>
</AccordionGroup>
</Card>
</CardGroup>
<br />
<CardGroup cols={1}>
<Card title="Performance Optimization" icon="bolt" iconType="solid">
<AccordionGroup>
<Accordion title="Efficient Processing">
Optimize resource usage and processing time.
```python
# Use generators for large datasets
def process_large_data():
for chunk in data_generator():
yield process_chunk(chunk)
```
</Accordion>
<Accordion title="Resource Management">
Properly handle resource allocation and cleanup.
```python
async with aiohttp.ClientSession() as session:
# Resource automatically managed
await process_data(session)
```
</Accordion>
<Accordion title="Caching">
Implement caching for frequently accessed data.
```python
@cache.memoize(timeout=300)
def expensive_operation(data: str) -> Dict:
return process_expensive(data)
```
</Accordion>
<Accordion title="Async Operations">
Use async/await for I/O-bound operations.
```python
async def fetch_data(urls: List[str]):
async with aiohttp.ClientSession() as session:
tasks = [fetch_url(session, url) for url in urls]
return await asyncio.gather(*tasks)
```
</Accordion>
</AccordionGroup>
</Card>
</CardGroup>
<br />
<CardGroup cols={1}>
<Card title="Security Best Practices" icon="shield-check" iconType="solid">
<AccordionGroup>
<Accordion title="Input Validation">
Always validate and sanitize inputs to prevent security vulnerabilities.
```python
def process_user_input(data: str) -> str:
if not isinstance(data, str):
raise ValueError("Input must be string")
return sanitize_input(data.strip())
```
</Accordion>
<Accordion title="Rate Limiting">
Implement rate limiting for API calls to prevent abuse.
```python
@rate_limit(calls=100, period=60)
async def api_call():
return await make_request()
```
</Accordion>
<Accordion title="API Key Management">
Securely handle API keys and credentials using environment variables.
```python
# Use environment variables
api_key = os.getenv('API_KEY')
if not api_key:
raise ConfigError("API key not found")
```
</Accordion>
<Accordion title="Error Masking">
Hide sensitive information in error messages to prevent information leakage.
```python
try:
result = process_sensitive_data()
except Exception as e:
# Log detailed error internally
logger.error(f"Detailed error: {str(e)}")
# Return sanitized error to user
raise PublicError("Processing failed")
```
</Accordion>
</AccordionGroup>
</Card>
</CardGroup>
<br />
<Tip>
**Pro Tip**: Start with these practices from the beginning of your project. It's easier to maintain good practices than to retrofit them later.
</Tip>
+109
View File
@@ -0,0 +1,109 @@
---
title: "Examples"
sidebarTitle: "Examples"
description: "Explore real-world examples and use cases built with PraisonAI Agents."
icon: "code"
---
## Use Cases
<CardGroup cols={2}>
<Card
title="Predictive Maintenance"
icon="wrench"
href="/usecases/predictive-maintenance"
>
Learn how to create AI agents for predictive maintenance and equipment monitoring.
</Card>
<Card
title="Emergency Response"
icon="truck-medical"
href="/usecases/emergency-response"
>
Learn how to create AI agents for coordinated emergency response and resource management.
</Card>
<Card
title="Code Review"
icon="code"
href="/usecases/code-review"
>
Learn how to create AI agents for automated code review and issue resolution.
</Card>
<Card
title="Adaptive Learning"
icon="graduation-cap"
href="/usecases/adaptive-learning"
>
Learn how to create AI agents for personalized adaptive learning experiences.
</Card>
<Card
title="Supply Chain"
icon="truck"
href="/usecases/supply-chain"
>
Learn how to create AI agents for supply chain risk management and mitigation.
</Card>
<Card
title="Customer Service"
icon="headset"
href="/usecases/customer-service"
>
Learn how to create AI agents for automated customer service and support.
</Card>
<Card
title="Fraud Detection"
icon="shield-check"
href="/usecases/fraud-detection"
>
Learn how to create AI agents for real-time fraud detection and alert management.
</Card>
<Card
title="Healthcare Diagnosis"
icon="stethoscope"
href="/usecases/healthcare-diagnosis"
>
Learn how to create AI agents for medical diagnosis and treatment recommendations.
</Card>
<Card
title="Smart City"
icon="city"
href="/usecases/smart-city"
>
Learn how to create AI agents for smart city resource optimization and management.
</Card>
<Card
title="Multilingual Content"
icon="language"
href="/usecases/multilingual-content"
>
Learn how to create AI agents for multilingual content generation and cultural adaptation.
</Card>
</CardGroup>
## What's Next?
<CardGroup cols={2}>
<Card
title="Features"
icon="stars"
href="/features/promptchaining"
>
Explore advanced features like prompt chaining and parallel execution
</Card>
<Card
title="API Reference"
icon="code"
href="/api-reference"
>
View the complete API reference documentation
</Card>
</CardGroup>
+155 -68
View File
@@ -1,82 +1,146 @@
---
title: "Async AI Agents"
title: "Async Agents"
description: "Async AI Agents allow you to run AI tasks asynchronously, improving performance and efficiency in your applications."
icon: "clock"
---
<Note>
**Requirements**
- Python 3.10 or higher
- Basic understanding of async/await in Python
</Note>
```mermaid
flowchart LR
In[In] --> Agent1[AI Agent]
Agent1 --> Agent2[AI Agent]
Agent1 --> Agent3[AI Agent]
Agent1 --> Agent4[AI Agent]
Agent2 --> Out[Out]
Agent3 --> Out
Agent4 --> Out
style In fill:#8B0000,color:#fff
style Agent1 fill:#2E8B57,color:#fff
style Agent2 fill:#2E8B57,color:#fff
style Agent3 fill:#2E8B57,color:#fff
style Agent4 fill:#2E8B57,color:#fff
style Out fill:#8B0000,color:#fff
```
Async AI Agents allow you to run AI tasks asynchronously, improving performance and efficiency in your applications.
## Quick Start
<Steps>
<Step title="Install Package">
First, install the PraisonAI Agents package:
```bash
pip install praisonaiagents
```
</Step>
<Tabs>
<Tab title="Code">
<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="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 Project">
Create a new file `app.py` with the basic setup:
```python
import asyncio
from praisonaiagents import Agent, Task, PraisonAIAgents
<Step title="Create Project">
Create a new file `app.py` with the basic setup:
```python
import asyncio
from praisonaiagents import Agent, Task, PraisonAIAgents
# Create an agent
agent = Agent(
name="AsyncAgent",
role="Assistant",
goal="Help with tasks",
backstory="Expert in async operations"
)
# Create an agent
agent = Agent(
name="AsyncAgent",
role="Assistant",
goal="Help with tasks",
backstory="Expert in async operations"
)
# Create a task
task = Task(
name="hello_task",
description="Say hello and introduce yourself",
agent=agent,
async_execution=True,
expected_output="Answer to the question"
)
# Create a task
task = Task(
name="hello_task",
description="Say hello and introduce yourself",
agent=agent,
async_execution=True,
expected_output="Answer to the question"
)
# Create agents manager
agents = PraisonAIAgents(
agents=[agent],
tasks=[task],
process="sequential"
)
# Create agents manager
agents = PraisonAIAgents(
agents=[agent],
tasks=[task],
process="sequential"
)
# Main async function
async def main():
result = await agents.astart()
print(result)
# Main async function
async def main():
result = await agents.astart()
print(result)
# Run the program
if __name__ == "__main__":
asyncio.run(main())
# Run the program
if __name__ == "__main__":
asyncio.run(main())
```
</Step>
```
</Step>
<Step title="Run the Program">
Run your async AI agent:
```bash
python app.py
```
</Step>
</Steps>
</Tab>
<Tab title="No Code">
<Steps>
<Step title="Install Package">
Install the PraisonAI package:
```bash
pip install praisonai
```
</Step>
<Step title="Set API Key">
Set your OpenAI API key as an environment variable:
```bash
export OPENAI_API_KEY=your_api_key_here
```
</Step>
<Step title="Create Project">
Create a new file `agents.yaml` with the basic setup:
```yaml
framework: praisonai
process: sequential
topic: async operations
roles:
assistant:
name: AsyncAgent
role: Assistant
goal: Help with tasks
backstory: Expert in async operations
tasks:
hello_task:
description: Say hello and introduce yourself
expected_output: Answer to the question
async_execution: true
```
</Step>
<Step title="Run the Program">
Run your async AI agent:
```bash
praisonai agents.yaml
```
</Step>
</Steps>
</Tab>
</Tabs>
<Step title="Run the Program">
Run your async AI agent:
```bash
python app.py
```
</Step>
</Steps>
<Note>
**Requirements**
- Python 3.10 or higher
- OpenAI API key. Generate OpenAI API key [here](https://platform.openai.com/api-keys). Use Other models using [this guide](/models).
- Basic understanding of async/await in Python
</Note>
<div className="relative w-full aspect-video">
<iframe
@@ -129,7 +193,9 @@ icon: "clock"
## Advanced Usage
### Async Tasks with Callbacks and Tools Example Code
<Tabs>
<Tab title="Code">
### Async Tasks with Callbacks and Tools Example Code
```python
import asyncio
@@ -357,7 +423,6 @@ async def main():
if __name__ == "__main__":
# Run the main function
asyncio.run(main())
```
### 1. Async Tasks with Callbacks
@@ -402,6 +467,28 @@ async def process_multiple_tasks():
)
return results
```
</Tab>
<Tab title="No Code">
```yaml
framework: praisonai
process: sequential
topic: async operations
roles:
async_agent:
name: AsyncSearchAgent
role: Asynchronous Search Specialist
goal: Perform fast and efficient asynchronous searches
backstory: Expert in parallel search operations
tools:
- async_search_tool
tasks:
search_task:
description: Perform async search operations
expected_output: Structured search results
async_execution: true
```
</Tab>
</Tabs>
## Best Practices
@@ -481,11 +568,11 @@ async def process_multiple_tasks():
## Next Steps
<CardGroup cols={2}>
<Card title="Examples" icon="code" href="./examples">
Check out more examples in our examples directory
<Card title="AutoAgents" icon="robot" href="./autoagents">
Learn about automatically created and managed AI agents
</Card>
<Card title="Advanced Topics" icon="book" href="./advanced">
Learn about advanced async patterns and optimizations
<Card title="Mini Agents" icon="microchip" href="./mini">
Explore lightweight, focused AI agents
</Card>
</CardGroup>
+349
View File
@@ -0,0 +1,349 @@
---
title: "AutoAgents"
description: "AutoAgents automatically creates and manages AI agents and tasks based on high-level instructions."
icon: "robot"
---
```mermaid
flowchart LR
In[In] --> Plan[Plan Tasks]
subgraph Creation[Automatic Agent Creation]
Plan --> Agent1[AI Agent 1]
Plan --> Agent2[AI Agent 2]
Plan --> Agent3[AI Agent 3]
end
subgraph Tools[Automatic Tool Assignment]
Agent1 --> Tool1[Tools 1]
Agent2 --> Tool2[Tools 2]
Agent3 --> Tool3[Tools 3]
end
Tools --> Execution
subgraph Execution[Execution]
Exec1[AI Agent 1] --> Exec2[AI Agent 2]
Exec2 --> Exec3[AI Agent 3]
end
Exec3 --> Out[Out]
style In fill:#8B0000,color:#fff
style Plan fill:#2E8B57,color:#fff
style Agent1 fill:#2E8B57,color:#fff
style Agent2 fill:#2E8B57,color:#fff
style Agent3 fill:#2E8B57,color:#fff
style Tool1 fill:#2E8B57,color:#fff
style Tool2 fill:#2E8B57,color:#fff
style Tool3 fill:#2E8B57,color:#fff
style Exec1 fill:#2E8B57,color:#fff
style Exec2 fill:#2E8B57,color:#fff
style Exec3 fill:#2E8B57,color:#fff
style Out fill:#8B0000,color:#fff
```
AutoAgents automatically creates and manages AI agents and tasks based on high-level instructions.
## Quick Start
<Tabs>
<Tab title="Code">
<Steps>
<Step title="Install Package">
First, install the PraisonAI Agents package:
```bash
pip install praisonaiagents duckduckgo_search
```
</Step>
<Step title="Set API Key">
Set your OpenAI API key as an environment variable in your terminal:
```bash
export OPENAI_API_KEY=your_api_key_here
```
</Step>
<Step title="Create a file">
Create a new file `app.py` with the basic setup:
```python
from praisonaiagents import AutoAgents
from praisonaiagents.tools import duckduckgo
# Create AutoAgents instance
agents = AutoAgents(
instructions="Search for information about AI Agents",
tools=[duckduckgo],
process="sequential",
verbose=True,
max_agents=3 # Maximum number of agents to create
)
# Start the agents
result = agents.start()
print(result)
```
</Step>
<Step title="Start AutoAgents">
Run your AutoAgents:
```bash
python app.py
```
</Step>
</Steps>
<Note>
**Requirements**
- Python 3.10 or higher
- OpenAI API key. Generate OpenAI API key [here](https://platform.openai.com/api-keys). Use Other models using [this guide](/models).
</Note>
</Tab>
<Tab title="No Code">
<Steps>
<Step title="Install Package">
Install the PraisonAI package:
```bash
pip install praisonai
```
</Step>
<Step title="Set API Key">
Set your OpenAI API key as an environment variable in your terminal:
```bash
export OPENAI_API_KEY=your_api_key_here
```
</Step>
<Step title="Start AutoAgents">
Run your AutoAgents:
```bash
praisonai --auto "Create a movie script about a robot in Mars"
```
</Step>
</Steps>
</Tab>
</Tabs>
## Understanding AutoAgents
<Card title="What are AutoAgents?" icon="question">
AutoAgents automatically:
- Creates appropriate AI agents based on your instructions
- Assigns relevant tools to each agent
- Breaks down tasks into manageable steps
- Manages execution flow between agents
- Handles agent coordination and task delegation
</Card>
## Features
<CardGroup cols={2}>
<Card title="Automatic Agent Creation" icon="wand-magic-sparkles">
Creates specialized agents based on task requirements.
</Card>
<Card title="Smart Tool Assignment" icon="toolbox">
Automatically assigns relevant tools to each agent.
</Card>
<Card title="Task Management" icon="list-check">
Breaks down complex tasks into manageable steps.
</Card>
<Card title="Process Optimization" icon="gauge-high">
Chooses optimal execution process (sequential/hierarchical).
</Card>
</CardGroup>
<CodeGroup>
```python Basic
# Basic usage with default settings
agents = AutoAgents(
instructions="Your high-level task description",
tools=[tool1, tool2]
)
```
```python Advanced
# Advanced usage with custom settings
agents = AutoAgents(
instructions="Your task description",
tools=[tool1, tool2],
max_agents=3,
process="hierarchical",
verbose=True,
memory=True,
allow_delegation=True
)
```
</CodeGroup>
## Advanced Usage
### Configuration Options
```python
# Create AutoAgents with advanced configuration
agents = AutoAgents(
instructions="Research and summarize recent AI developments",
tools=[SerperDevTool, WikipediaTools],
max_agents=3, # Maximum number of agents to create
verbose=True, # Enable detailed logging
process="hierarchical", # Use hierarchical process
memory=True, # Enable memory for agents
allow_delegation=True, # Allow task delegation
max_rpm=60, # Maximum requests per minute
max_execution_time=300, # Maximum execution time in seconds
allow_code_execution=True, # Allow code execution
code_execution_mode="safe", # Use safe mode for code execution
self_reflect=True, # Enable agent self-reflection
markdown=True # Enable markdown formatting
)
```
### Process Types
<AccordionGroup>
<Accordion title="Sequential Process">
```python
# Tasks are executed in sequence
agents = AutoAgents(
instructions="Your task",
process="sequential"
)
```
</Accordion>
<Accordion title="Hierarchical Process">
```python
# Manager agent coordinates other agents
agents = AutoAgents(
instructions="Your task",
process="hierarchical",
manager_llm="gpt-4o" # Specify LLM for manager
)
```
</Accordion>
</AccordionGroup>
## Best Practices
<AccordionGroup>
<Accordion title="Clear Instructions">
```python
# Good instruction example
agents = AutoAgents(
instructions="""
Research the latest developments in AI for 2024:
1. Focus on breakthrough technologies
2. Include real-world applications
3. Consider future implications
"""
)
```
</Accordion>
<Accordion title="Tool Selection">
```python
# Provide relevant tools for the task
agents = AutoAgents(
instructions="Research task",
tools=[
SerperDevTool, # For web search
WikipediaTools, # For background info
CustomTool # Your custom tool
]
)
```
</Accordion>
<Accordion title="Resource Management">
```python
# Configure resource limits
agents = AutoAgents(
instructions="Your task",
max_rpm=60, # Rate limiting
max_execution_time=300, # Timeout
max_agents=3 # Agent limit
)
```
</Accordion>
</AccordionGroup>
## Troubleshooting
<CardGroup cols={2}>
<Card title="Tool Assignment Issues" icon="triangle-exclamation">
If tools aren't being assigned correctly:
- Check tool compatibility
- Verify tool names
- Enable verbose mode for debugging
</Card>
<Card title="Performance Issues" icon="gauge">
If execution is slow:
- Reduce max_agents
- Adjust max_rpm
- Consider process type
</Card>
</CardGroup>
## API Reference
### Main Parameters
<ResponseField name="instructions" type="str" required>
High-level task description for the agents
</ResponseField>
<ResponseField name="tools" type="List[Any]">
List of tools available to the agents
</ResponseField>
<ResponseField name="max_agents" type="int" default="3">
Maximum number of agents to create
</ResponseField>
<ResponseField name="process" type="str" default="sequential">
Process type: "sequential" or "hierarchical"
</ResponseField>
### Optional Parameters
<ResponseField name="verbose" type="bool" default="False">
Enable detailed logging
</ResponseField>
<ResponseField name="memory" type="bool" default="True">
Enable agent memory
</ResponseField>
<ResponseField name="allow_delegation" type="bool" default="False">
Allow agents to delegate tasks
</ResponseField>
### Methods
<ResponseField name="start()" type="method">
Start the agents synchronously
</ResponseField>
<ResponseField name="astart()" type="method">
Start the agents asynchronously
</ResponseField>
## Next Steps
<CardGroup cols={2}>
<Card title="Examples" icon="code" href="./examples">
Explore more examples in our examples directory
</Card>
<Card title="Custom Tools" icon="screwdriver-wrench" href="./tools">
Learn how to create custom tools for your agents
</Card>
</CardGroup>
<Note>
For optimal results, provide clear instructions and appropriate tools for your use case.
</Note>
+277
View File
@@ -0,0 +1,277 @@
---
title: "Agentic Autonomous Workflow"
sidebarTitle: "Autonomous Workflow"
description: "Learn how to create AI agents that can autonomously monitor, act, and adapt based on environment feedback."
icon: "robot"
---
```mermaid
flowchart LR
Human[Human] <--> LLM[LLM Call]
LLM -->|ACTION| Environment[Environment]
Environment -->|FEEDBACK| LLM
LLM --> Stop[Stop]
style Human fill:#8B0000,color:#fff
style LLM fill:#2E8B57,color:#fff
style Environment fill:#8B0000,color:#fff
style Stop fill:#333,color:#fff
```
An agent-based workflow where LLMs act autonomously within a loop, interacting with their environment and receiving feedback to refine their actions and decisions.
## 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 in your terminal:
```bash
export OPENAI_API_KEY=your_api_key_here
```
</Step>
<Step title="Create a file">
Create a new file `app.py` with the basic setup:
```python
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()
```
</Step>
<Step title="Start Agents">
Type this in your terminal to run your agents:
```bash
python app.py
```
</Step>
</Steps>
<Note>
**Requirements**
- Python 3.10 or higher
- OpenAI API key. Generate OpenAI API key [here](https://platform.openai.com/api-keys). Use Other models using [this guide](/models).
- Basic understanding of Python
</Note>
## Understanding Autonomous Workflow
<Card title="What is Autonomous Workflow?" icon="question">
Autonomous Workflow enables:
- Continuous environment monitoring
- Automated decision-making and action execution
- Real-time feedback processing
- Self-adapting behavior based on outcomes
</Card>
## Features
<CardGroup cols={2}>
<Card title="Environment Monitoring" icon="eye">
Continuously monitor and analyze environment state.
</Card>
<Card title="Adaptive Actions" icon="gears">
Execute context-aware actions based on state analysis.
</Card>
<Card title="Feedback Processing" icon="rotate">
Process and learn from action outcomes.
</Card>
<Card title="Self-Optimization" icon="arrow-trend-up">
Improve performance through continuous learning.
</Card>
</CardGroup>
## Configuration Options
```python
# Create a monitor agent
monitor = Agent(
name="Environment Monitor",
role="State analyzer",
goal="Monitor and analyze state",
tools=[get_environment_state], # Environment monitoring tools
verbose=True # Enable detailed logging
)
# Create an action agent
action = Agent(
name="Action Executor",
role="Action performer",
goal="Execute appropriate actions",
tools=[perform_action] # Action execution tools
)
# Create monitoring task
monitor_task = Task(
name="monitor_environment",
description="Monitor environment state",
agent=monitor,
is_start=True,
task_type="decision",
condition={
"normal": ["execute_action"],
"critical": ["execute_action"],
"optimal": "exit"
}
)
# Create feedback loop task
feedback_task = Task(
name="process_feedback",
description="Process and adapt",
agent=feedback_agent,
next_tasks=["monitor_environment"], # Create feedback loop
context=[monitor_task, action_task] # Access history
)
```
## Troubleshooting
<CardGroup cols={2}>
<Card title="Monitoring Issues" icon="triangle-exclamation">
If monitoring fails:
- Check environment access
- Verify state detection
- Enable verbose mode for debugging
</Card>
<Card title="Adaptation Flow" icon="diagram-project">
If adaptation is incorrect:
- Review feedback processing
- Check action outcomes
- Verify learning loop
</Card>
</CardGroup>
## Next Steps
<CardGroup cols={2}>
<Card title="AutoAgents" icon="robot" href="./autoagents">
Learn about automatically created and managed AI agents
</Card>
<Card title="Mini Agents" icon="microchip" href="./mini">
Explore lightweight, focused AI agents
</Card>
</CardGroup>
<Note>
For optimal results, ensure your environment monitoring is reliable and your feedback processing logic is properly configured for effective adaptation.
</Note>
File diff suppressed because it is too large. Load diff
+297 -231
View File
@@ -5,73 +5,134 @@ description: "Learn how to create AI agents that can write and execute Python co
icon: "code"
---
<Note>
**Prerequisites**
- Python 3.10 or higher
- PraisonAI Agents package installed
- e2b_code_interpreter package installed
- Basic understanding of Python
</Note>
## Quick Start
Create AI agents that can write and execute Python code in a sandboxed environment!
<Tabs>
<Tab title="Code">
<Steps>
<Step title="Install Package">
First, install the required packages:
```bash
pip install praisonaiagents e2b_code_interpreter
```
</Step>
<Steps>
<Step title="Install Packages">
First, install the required packages:
```bash
pip install praisonaiagents e2b_code_interpreter
```
</Step>
<Step title="Set API Key">
Set your OpenAI API key and E2B API key as an environment variable in your terminal:
```bash
export OPENAI_API_KEY=your_api_key_here
export E2B_API_KEY=your_e2b_api_key_here
```
</Step>
<Step title="Import Required Components">
Import the necessary components:
```python
from praisonaiagents import Agent, Task, PraisonAIAgents
from e2b_code_interpreter import Sandbox
```
</Step>
<Step title="Create a file">
Create a new file `app.py` with the basic setup:
```python
from praisonaiagents import Agent, Task, PraisonAIAgents
from e2b_code_interpreter import Sandbox
<Step title="Define Code Interpreter">
Create a code interpreter function:
```python
def code_interpreter(code: str):
print(f"\n{'='*50}\n> Running following AI-generated code:\n{code}\n{'='*50}")
exec_result = Sandbox().run_code(code)
if exec_result.error:
print("[Code Interpreter error]", exec_result.error)
return {"error": str(exec_result.error)}
else:
results = []
for result in exec_result.results:
if hasattr(result, '__iter__'):
results.extend(list(result))
def code_interpreter(code: str):
print(f"\n{'='*50}\n> Running following AI-generated code:\n{code}\n{'='*50}")
exec_result = Sandbox().run_code(code)
if exec_result.error:
print("[Code Interpreter error]", exec_result.error)
return {"error": str(exec_result.error)}
else:
results.append(str(result))
logs = {"stdout": list(exec_result.logs.stdout), "stderr": list(exec_result.logs.stderr)}
return json.dumps({"results": results, "logs": logs})
```
</Step>
results = []
for result in exec_result.results:
if hasattr(result, '__iter__'):
results.extend(list(result))
else:
results.append(str(result))
logs = {"stdout": list(exec_result.logs.stdout), "stderr": list(exec_result.logs.stderr)}
return json.dumps({"results": results, "logs": logs})
<Step title="Create Code Agents">
Set up your code writing and execution agents:
```python
code_agent = Agent(
name="code_agent",
backstory="Expert in writing Python scripts",
self_reflect=False
)
# Create code agent
code_agent = Agent(
role="Code Developer",
goal="Write and execute Python code",
backstory="Expert Python developer with strong coding skills",
tools=[code_interpreter],
verbose=True
)
execution_agent = Agent(
name="execution_agent",
backstory="Expert in executing Python scripts",
self_reflect=False,
tools=[code_interpreter]
)
```
</Step>
</Steps>
# Create a task
task = Task(
description="Write and execute a Python script to analyze data",
expected_output="Working Python script with execution results",
agent=code_agent
)
# Create and start the agents
agents = PraisonAIAgents(
agents=[code_agent],
tasks=[task],
process="sequential",
verbose=2
)
# Start execution
agents.start()
```
</Step>
<Step title="Start Agents">
Type this in your terminal to run your agents:
```bash
python app.py
```
</Step>
</Steps>
</Tab>
<Tab title="No Code">
<Steps>
<Step title="Install Package">
Install the PraisonAI package:
```bash
pip install praisonai e2b_code_interpreter
```
</Step>
<Step title="Set API Key">
Set your OpenAI API key as an environment variable in your terminal:
```bash
export OPENAI_API_KEY=your_api_key_here
```
</Step>
<Step title="Create a file">
Create a new file `agents.yaml` with the basic setup:
```yaml
framework: praisonai
process: sequential
topic: write and execute Python code
roles:
developer:
backstory: Expert Python developer with strong coding skills.
goal: Write and execute Python code safely
role: Code Developer
tools:
- code_interpreter
tasks:
coding_task:
description: Write and execute a Python script to analyze data.
expected_output: Working Python script with execution results.
```
</Step>
<Step title="Start Agents">
Type this in your terminal to run your agents:
```bash
praisonai agents.yaml
```
</Step>
</Steps>
</Tab>
</Tabs>
<Note>
**Requirements**
- Python 3.10 or higher
- OpenAI API key. Generate OpenAI API key [here](https://platform.openai.com/api-keys). Use Other models using [this guide](/models).
- e2b_code_interpreter package installed
</Note>
## Understanding Code Agents
@@ -83,205 +144,210 @@ Create AI agents that can write and execute Python code in a sandboxed environme
- Work together in a pipeline (writer → executor)
</Card>
## Key Components
## Features
<CardGroup cols={2}>
<Card title="Code Writer Agent" icon="pencil">
Specialized in writing Python code
```python
Agent(
name="code_agent",
backstory="Expert in writing Python scripts"
)
```
<Card title="Code Writer" icon="pencil">
Writes Python code based on requirements.
</Card>
<Card title="Code Executor Agent" icon="play">
Executes code using sandbox
```python
Agent(
name="execution_agent",
tools=[code_interpreter]
)
```
<Card title="Safe Execution" icon="shield">
Executes code in a sandboxed environment.
</Card>
<Card title="Sandbox Environment" icon="box">
Safe code execution environment using e2b
<Card title="Error Handling" icon="bug">
Manages code execution errors and debugging.
</Card>
<Card title="Execution Results" icon="output">
Structured output with results and logs
<Card title="Results Processing" icon="output">
Processes and formats execution results.
</Card>
</CardGroup>
## Examples
## Multi-Agent Code Development
### Simple Hello World Example
<Tabs>
<Tab title="Code">
<Steps>
<Step title="Install Package">
First, install the required packages:
```bash
pip install praisonaiagents e2b_code_interpreter
```
</Step>
<Step title="Set API Key">
Set your OpenAI API key as an environment variable in your terminal:
```bash
export OPENAI_API_KEY=your_api_key_here
```
</Step>
<Step title="Create a file">
Create a new file `app.py` with the basic setup:
```python
from praisonaiagents import Agent, Task, PraisonAIAgents
from e2b_code_interpreter import Sandbox
def code_interpreter(code: str):
print(f"\n{'='*50}\n> Running following AI-generated code:\n{code}\n{'='*50}")
exec_result = Sandbox().run_code(code)
if exec_result.error:
print("[Code Interpreter error]", exec_result.error)
return {"error": str(exec_result.error)}
else:
results = []
for result in exec_result.results:
if hasattr(result, '__iter__'):
results.extend(list(result))
else:
results.append(str(result))
logs = {"stdout": list(exec_result.logs.stdout), "stderr": list(exec_result.logs.stderr)}
return json.dumps({"results": results, "logs": logs})
# Create first agent for writing code
code_writer = Agent(
role="Code Writer",
goal="Write efficient Python code",
backstory="Expert Python developer specializing in code writing",
verbose=True
)
# Create second agent for code execution
code_executor = Agent(
role="Code Executor",
goal="Execute and validate Python code",
backstory="Expert in code execution and testing",
tools=[code_interpreter],
verbose=True
)
# Create first task
writing_task = Task(
description="Write a Python script for data analysis",
expected_output="Complete Python script",
agent=code_writer
)
# Create second task
execution_task = Task(
description="Execute and validate the Python script",
expected_output="Execution results and validation",
agent=code_executor
)
# Create and start the agents
agents = PraisonAIAgents(
agents=[code_writer, code_executor],
tasks=[writing_task, execution_task],
process="sequential"
)
# Start execution
agents.start()
```
</Step>
<Step title="Start Agents">
Type this in your terminal to run your agents:
```bash
python app.py
```
</Step>
</Steps>
</Tab>
<Tab title="No Code">
<Steps>
<Step title="Install Package">
Install the PraisonAI package:
```bash
pip install praisonai e2b_code_interpreter
```
</Step>
<Step title="Set API Key">
Set your OpenAI API key as an environment variable in your terminal:
```bash
export OPENAI_API_KEY=your_api_key_here
```
</Step>
<Step title="Create a file">
Create a new file `agents.yaml` with the basic setup:
```yaml
framework: praisonai
process: sequential
topic: develop and execute Python code
roles:
writer:
backstory: Expert Python developer specializing in code writing.
goal: Write efficient Python code
role: Code Writer
tasks:
writing_task:
description: Write a Python script for data analysis.
expected_output: Complete Python script.
executor:
backstory: Expert in code execution and testing.
goal: Execute and validate Python code
role: Code Executor
tools:
- code_interpreter
tasks:
execution_task:
description: Execute and validate the Python script.
expected_output: Execution results and validation.
```
</Step>
<Step title="Start Agents">
Type this in your terminal to run your agents:
```bash
praisonai agents.yaml
```
</Step>
</Steps>
</Tab>
</Tabs>
### Configuration Options
```python
from praisonaiagents import Agent, Task, PraisonAIAgents
from e2b_code_interpreter import Sandbox
# Create agents
code_agent = Agent(
name="code_agent",
backstory="Expert in writing Python scripts",
self_reflect=False
)
execution_agent = Agent(
name="execution_agent",
backstory="Expert in executing Python scripts",
self_reflect=False,
tools=[code_interpreter]
)
# Define tasks
code_task = Task(
description="Write a simple Python script to print 'Hello, World!'",
expected_output="A Python script that prints 'Hello, World!'",
agent=code_agent
)
execution_task = Task(
description="Execute the Python script",
expected_output="The output of the Python script",
agent=execution_agent
)
# Initialize and run agents
agents = PraisonAIAgents(
agents=[code_agent, execution_agent],
tasks=[code_task, execution_task]
)
result = agents.start()
```
### Advanced Code Generation
<CodeGroup>
```python Data Analysis
# Create a data analysis script
code_task = Task(
description="""
Write a Python script that:
1. Creates a sample dataset
2. Performs basic statistical analysis
3. Generates a plot
""",
agent=code_agent
)
```
```python Web Scraping
# Create a web scraping script
code_task = Task(
description="""
Write a Python script that:
1. Scrapes a website
2. Extracts specific data
3. Saves to CSV
""",
agent=code_agent
)
```
</CodeGroup>
## Best Practices
<AccordionGroup>
<Accordion title="Code Safety">
Ensure safe code execution:
```python
# Always use sandbox environment
exec_result = Sandbox().run_code(code)
# Handle errors gracefully
if exec_result.error:
return {"error": str(exec_result.error)}
```
</Accordion>
<Accordion title="Task Description">
Write clear code requirements:
```python
# Good
Task(description="""
Write a Python script that:
1. Takes user input
2. Validates the input
3. Processes the data
4. Returns formatted output
""")
# Too vague
Task(description="Write some Python code")
```
</Accordion>
</AccordionGroup>
## Common Patterns
### Code Generation and Testing
```python
# Generate code
code_task = Task(
description="Write a function to calculate fibonacci numbers",
agent=code_agent
)
# Generate test cases
test_task = Task(
description="Write test cases for the fibonacci function",
agent=code_agent
)
# Execute tests
execution_task = Task(
description="Run the test cases",
agent=execution_agent
)
```
### Interactive Code Development
```python
# Write initial code
initial_code_task = Task(
description="Write initial version of the script",
agent=code_agent
)
# Test and improve
improvement_task = Task(
description="Analyze execution results and improve the code",
agent=code_agent
# Create an agent with advanced code execution configuration
agent = Agent(
role="Code Developer",
goal="Write and execute Python code",
backstory="Expert in Python development",
tools=[code_interpreter],
verbose=True, # Enable detailed logging
llm="gpt-4o" # Language model to use
)
```
## Troubleshooting
<CardGroup cols={2}>
<Card title="Execution Errors" icon="triangle-exclamation">
Check sandbox execution results:
```python
if exec_result.error:
print("[Error]", exec_result.error)
```
<Card title="Code Errors" icon="triangle-exclamation">
If code execution fails:
- Check syntax errors
- Verify package imports
- Enable verbose mode for debugging
</Card>
<Card title="Code Generation" icon="code">
Provide clear requirements and constraints in task description
<Card title="Sandbox Issues" icon="box">
If sandbox execution fails:
- Check environment setup
- Verify permissions
- Review resource limits
</Card>
</CardGroup>
## Next Steps
<CardGroup cols={2}>
<Card title="Advanced Code Generation" icon="graduation-cap" href="./advanced-code">
Learn about complex code generation patterns
<Card title="AutoAgents" icon="robot" href="./autoagents">
Learn about automatically created and managed AI agents
</Card>
<Card title="Custom Tools" icon="wrench" href="./custom-tools">
Create custom code execution tools
<Card title="Mini Agents" icon="microchip" href="./mini">
Explore lightweight, focused AI agents
</Card>
</CardGroup>
<Note>
Code execution agents provide a powerful way to generate and run Python code safely. They're perfect for automated code generation, testing, and execution in a controlled environment.
For optimal results, ensure code is properly formatted and tested in the sandbox environment before production use.
</Note>
+230
View File
@@ -0,0 +1,230 @@
---
title: "Agentic Evaluator Optimizer"
sidebarTitle: "Evaluator Optimizer"
description: "Learn how to create AI agents that can generate and optimize solutions through iterative feedback."
icon: "arrows-rotate"
---
```mermaid
flowchart LR
In[In] --> Generator[LLM Call Generator]
Generator -->|SOLUTION| Evaluator[LLM Call Evaluator] -->|ACCEPTED| Out[Out]
Evaluator -->|REJECTED + FEEDBACK| Generator
style In fill:#8B0000,color:#fff
style Generator fill:#2E8B57,color:#fff
style Evaluator fill:#2E8B57,color:#fff
style Out fill:#8B0000,color:#fff
```
A feedback loop workflow where LLM-generated outputs are evaluated, refined, and optimized iteratively to improve accuracy and relevance.
## 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 in your terminal:
```bash
export OPENAI_API_KEY=your_api_key_here
```
</Step>
<Step title="Create a file">
Create a new file `app.py` with the basic setup:
```python
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}")
```
</Step>
<Step title="Start Agents">
Type this in your terminal to run your agents:
```bash
python app.py
```
</Step>
</Steps>
<Note>
**Requirements**
- Python 3.10 or higher
- OpenAI API key. Generate OpenAI API key [here](https://platform.openai.com/api-keys). Use Other models using [this guide](/models).
- Basic understanding of Python
</Note>
## Understanding Evaluator-Optimizer
<Card title="What is Evaluator-Optimizer?" icon="question">
Evaluator-Optimizer pattern enables:
- Iterative solution generation and refinement
- Automated quality evaluation
- Feedback-driven optimization
- Continuous improvement loops
</Card>
## Features
<CardGroup cols={2}>
<Card title="Solution Generation" icon="wand-magic-sparkles">
Generate solutions based on requirements and feedback.
</Card>
<Card title="Quality Evaluation" icon="magnifying-glass-chart">
Automatically assess solution quality and completeness.
</Card>
<Card title="Feedback Loop" icon="rotate">
Implement iterative improvement through feedback cycles.
</Card>
<Card title="Process Control" icon="sliders">
Monitor and control the optimization process.
</Card>
</CardGroup>
## Configuration Options
```python
# Create a generator agent
generator = Agent(
name="Generator",
role="Solution generator",
goal="Generate and improve solutions",
instructions="Step-by-step instructions for generation",
verbose=True # Enable detailed logging
)
# Create an evaluator agent
evaluator = Agent(
name="Evaluator",
role="Solution evaluator",
goal="Evaluate and provide feedback",
instructions="Evaluation criteria and feedback format"
)
# Create tasks with feedback loop
generate_task = Task(
name="generate",
description="Generate solution",
agent=generator,
is_start=True,
task_type="decision",
next_tasks=["evaluate"]
)
evaluate_task = Task(
name="evaluate",
description="Evaluate solution",
agent=evaluator,
context=[generate_task],
task_type="decision",
condition={
"more": ["generate"], # Continue optimization
"done": [""] # Exit when complete
}
)
```
## Troubleshooting
<CardGroup cols={2}>
<Card title="Generation Issues" icon="triangle-exclamation">
If generation is not improving:
- Review generator instructions
- Check feedback integration
- Enable verbose mode for debugging
</Card>
<Card title="Evaluation Flow" icon="diagram-project">
If evaluation cycle is incorrect:
- Verify evaluation criteria
- Check condition mappings
- Review feedback loop connections
</Card>
</CardGroup>
## Next Steps
<CardGroup cols={2}>
<Card title="AutoAgents" icon="robot" href="./autoagents">
Learn about automatically created and managed AI agents
</Card>
<Card title="Mini Agents" icon="microchip" href="./mini">
Explore lightweight, focused AI agents
</Card>
</CardGroup>
<Note>
For optimal results, ensure your generator instructions and evaluation criteria are clear and well-defined to achieve the desired optimization outcomes.
</Note>
+219
View File
@@ -0,0 +1,219 @@
---
title: "LangChain Agents"
sidebarTitle: "LangChain Agents"
description: "Learn how to use LangChain tools and utilities with PraisonAI agents."
icon: "link-simple"
---
## Quick Start
<Tabs>
<Tab title="Code">
<Steps>
<Step title="Install Package">
First, install the required packages:
```bash
pip install praisonaiagents langchain-community wikipedia
```
</Step>
<Step title="Set API Key">
Set your OpenAI API key as an environment variable in your terminal:
```bash
export OPENAI_API_KEY=your_api_key_here
```
</Step>
<Step title="Create a file">
Create a new file `app.py` with the basic setup:
<CodeGroup>
```python Single Tool
from praisonaiagents import Agent, Task, PraisonAIAgents
from langchain_community.utilities import WikipediaAPIWrapper
# Create an agent with Wikipedia tool
agent = Agent(
name="WikiAgent",
role="Research Assistant",
goal="Search Wikipedia for accurate information",
backstory="I am an AI assistant specialized in Wikipedia research",
tools=[WikipediaAPIWrapper],
self_reflect=False
)
# Create a research task
task = Task(
name="wiki_search",
description="Research 'Artificial Intelligence' on Wikipedia",
expected_output="Comprehensive information from Wikipedia articles",
agent=agent
)
# Create and start the workflow
agents = PraisonAIAgents(
agents=[agent],
tasks=[task],
verbose=True
)
agents.start()
```
```python Multiple Tools
from praisonaiagents import Agent, Task, PraisonAIAgents
from langchain_community.tools import YouTubeSearchTool
from langchain_community.utilities import WikipediaAPIWrapper
# Create YouTube search agent
agent = Agent(
name="SearchAgent",
role="Research Assistant",
goal="Search for information from YouTube",
backstory="I am an AI assistant that can search YouTube for relevant videos.",
tools=[YouTubeSearchTool],
self_reflect=False
)
# Create Wikipedia research agent
agent2 = Agent(
name="WikiAgent",
role="Research Assistant",
goal="Search for information from Wikipedia",
backstory="I am an AI assistant that can search Wikipedia for accurate information.",
tools=[WikipediaAPIWrapper],
self_reflect=False
)
# Create YouTube search task
task = Task(
name="search_task",
description="Search for information about 'AI advancements' on YouTube",
expected_output="Relevant information from YouTube videos",
agent=agent
)
# Create Wikipedia research task
task2 = Task(
name="wiki_task",
description="Search for information about 'AI advancements' on Wikipedia",
expected_output="Comprehensive information from Wikipedia articles",
agent=agent2
)
# Create and start the workflow
agents = PraisonAIAgents(
agents=[agent, agent2],
tasks=[task, task2],
verbose=True
)
agents.start()
```
</CodeGroup>
</Step>
<Step title="Start Agents">
Type this in your terminal to run your agents:
```bash
python app.py
```
</Step>
</Steps>
</Tab>
<Tab title="No Code">
<Steps>
<Step title="Install Package">
(Upcoming Feature)
Install the PraisonAI package:
```bash
pip install "praisonai"
```
</Step>
<Step title="Set API Key">
Set your OpenAI API key as an environment variable in your terminal:
```bash
export OPENAI_API_KEY=your_api_key_here
```
</Step>
<Step title="Create a file">
Create a new file `agents.yaml` with the basic setup:
```yaml
framework: praisonai
process: sequential
roles:
researcher:
name: SearchAgent
role: Research Assistant
goal: Search for information from multiple sources
backstory: I am an AI assistant that can search YouTube and Wikipedia.
tools:
- youtube_search
- wikipedia
tasks:
search_task:
name: search_task
description: Search for information about 'AI advancements' on both YouTube and Wikipedia
expected_output: Combined information from YouTube videos and Wikipedia articles
```
</Step>
<Step title="Start Agents">
Type this in your terminal to run your agents:
```bash
praisonai agents.yaml
```
</Step>
</Steps>
</Tab>
</Tabs>
<Note>
**Requirements**
- Python 3.10 or higher
- OpenAI API key. Generate OpenAI API key [here](https://platform.openai.com/api-keys)
- LangChain compatible tools and utilities
</Note>
## Understanding LangChain Integration
<Card title="What is LangChain Integration?" icon="question">
LangChain integration enables agents to:
- Use LangChain's extensive tool ecosystem
- Access various data sources and APIs
- Leverage pre-built utilities and wrappers
- Combine multiple tools in a single agent
- Extend agent capabilities with community tools
</Card>
## Features
<CardGroup cols={2}>
<Card title="Tool Integration" icon="plug">
Seamlessly use LangChain tools with PraisonAI agents.
</Card>
<Card title="Multiple Sources" icon="database">
Access various data sources through LangChain utilities.
</Card>
<Card title="Community Tools" icon="users">
Leverage the extensive LangChain community ecosystem.
</Card>
<Card title="Custom Tools" icon="wrench">
Create and integrate custom LangChain tools.
</Card>
</CardGroup>
## Next Steps
<CardGroup cols={2}>
<Card title="Memory Integration" icon="brain" href="../concepts/memory">
Learn how to combine LangChain tools with agent memory
</Card>
<Card title="Custom Tools" icon="wrench" href="./tools">
Create your own custom tools for agents
</Card>
</CardGroup>
<Note>
For optimal results, ensure all required dependencies are installed and API keys are properly configured for each tool.
</Note>
+288 -220
View File
@@ -5,51 +5,128 @@ description: "Learn how to create AI agents that can perform complex mathematica
icon: "calculator"
---
<Note>
**Prerequisites**
- Python 3.10 or higher
- PraisonAI Agents package installed
- Basic understanding of Python
- sympy and pint packages (automatically installed when needed)
</Note>
## Quick Start
Create AI agents that can perform complex mathematical calculations, unit conversions, and financial computations!
<Tabs>
<Tab title="Code">
<Steps>
<Step title="Install Package">
First, install the PraisonAI Agents package:
```bash
pip install praisonaiagents sympy pint
```
</Step>
<Steps>
<Step title="Install Package">
First, install the required package:
```bash
pip install praisonaiagents
```
</Step>
<Step title="Set API Key">
Set your OpenAI API key as an environment variable in your terminal:
```bash
export OPENAI_API_KEY=your_api_key_here
```
</Step>
<Step title="Import Required Components">
Import the necessary components:
```python
from praisonaiagents import Agent, Task, PraisonAIAgents
from praisonaiagents.tools import (
evaluate, solve_equation, convert_units,
calculate_statistics, calculate_financial
)
```
</Step>
<Step title="Create a file">
Create a new file `app.py` with the basic setup:
```python
from praisonaiagents import Agent, Task, PraisonAIAgents
from praisonaiagents.tools import (
evaluate, solve_equation, convert_units,
calculate_statistics, calculate_financial
)
<Step title="Create Math Agent">
Set up your mathematical computation agent:
```python
math_agent = Agent(
name="MathAssistant",
description="Expert in mathematical calculations and analysis",
tools=[
evaluate, solve_equation, convert_units,
calculate_statistics, calculate_financial
]
)
```
</Step>
</Steps>
# Create math agent
math_agent = Agent(
role="Math Expert",
goal="Perform complex mathematical calculations",
backstory="Expert in mathematical computations and analysis",
tools=[
evaluate, solve_equation, convert_units,
calculate_statistics, calculate_financial
],
verbose=True
)
# Create a task
task = Task(
description="Calculate compound interest and statistical analysis",
expected_output="Detailed mathematical analysis",
agent=math_agent
)
# Create and start the agents
agents = PraisonAIAgents(
agents=[math_agent],
tasks=[task],
process="sequential",
verbose=2
)
# Start execution
agents.start()
```
</Step>
<Step title="Start Agents">
Type this in your terminal to run your agents:
```bash
python app.py
```
</Step>
</Steps>
</Tab>
<Tab title="No Code">
<Steps>
<Step title="Install Package">
Install the PraisonAI package:
```bash
pip install praisonai sympy pint
```
</Step>
<Step title="Set API Key">
Set your OpenAI API key as an environment variable in your terminal:
```bash
export OPENAI_API_KEY=your_api_key_here
```
</Step>
<Step title="Create a file">
Create a new file `agents.yaml` with the basic setup:
```yaml
framework: praisonai
process: sequential
topic: perform mathematical analysis
roles:
mathematician:
backstory: Expert in mathematical computations and analysis.
goal: Perform complex mathematical calculations
role: Math Expert
tools:
- evaluate
- solve_equation
- convert_units
- calculate_statistics
- calculate_financial
tasks:
math_task:
description: Calculate compound interest and perform statistical analysis.
expected_output: Detailed mathematical analysis with results.
```
</Step>
<Step title="Start Agents">
Type this in your terminal to run your agents:
```bash
praisonai agents.yaml
```
</Step>
</Steps>
</Tab>
</Tabs>
<Note>
**Requirements**
- Python 3.10 or higher
- OpenAI API key. Generate OpenAI API key [here](https://platform.openai.com/api-keys). Use Other models using [this guide](/models).
- sympy and pint packages (automatically installed when needed)
</Note>
## Understanding Math Agents
@@ -62,180 +139,177 @@ Create AI agents that can perform complex mathematical calculations, unit conver
- Handle financial calculations
</Card>
## Key Components
## Features
<CardGroup cols={2}>
<Card title="Expression Evaluator" icon="function">
Evaluates mathematical expressions
```python
evaluate("2 + 2 * 3")
evaluate("sin(pi/2) + sqrt(16)")
```
Evaluates mathematical expressions and formulas.
</Card>
<Card title="Equation Solver" icon="equals">
Solves mathematical equations
```python
solve_equation("2*x + 3 = 7")
solve_equation("x^2 - 5*x + 6 = 0")
```
Solves mathematical equations and systems.
</Card>
<Card title="Unit Converter" icon="arrows-rotate">
Converts between different units
```python
convert_units(100, "meters", "kilometers")
```
Converts between different units of measurement.
</Card>
<Card title="Statistical Calculator" icon="chart-simple">
Calculates statistical metrics
```python
calculate_statistics([1, 2, 3, 4, 5])
```
Calculates statistical metrics and analysis.
</Card>
</CardGroup>
## Examples
## Multi-Agent AI Math Analysis
### Basic Calculations Example
<Tabs>
<Tab title="Code">
<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 in your terminal:
```bash
export OPENAI_API_KEY=your_api_key_here
```
</Step>
<Step title="Create a file">
Create a new file `app.py` with the basic setup:
```python
from praisonaiagents import Agent, Task, PraisonAIAgents
from praisonaiagents.tools import (
evaluate, solve_equation, convert_units,
calculate_statistics, calculate_financial
)
# Create first agent for calculations
calculator = Agent(
role="Mathematical Calculator",
goal="Perform complex calculations and analysis",
backstory="Expert in mathematical computations",
tools=[evaluate, solve_equation, convert_units],
verbose=True
)
# Create second agent for statistics
statistician = Agent(
role="Statistical Analyst",
goal="Perform statistical analysis and interpretation",
backstory="Expert in statistical analysis",
tools=[calculate_statistics, calculate_financial],
verbose=True
)
# Create first task
calc_task = Task(
description="Calculate compound interest for $10000 at 5% for 3 years",
expected_output="Detailed interest calculation",
agent=calculator
)
# Create second task
stats_task = Task(
description="Analyze the monthly interest distribution",
expected_output="Statistical analysis of interest data",
agent=statistician
)
# Create and start the agents
agents = PraisonAIAgents(
agents=[calculator, statistician],
tasks=[calc_task, stats_task],
process="sequential"
)
# Start execution
agents.start()
```
</Step>
<Step title="Start Agents">
Type this in your terminal to run your agents:
```bash
python app.py
```
</Step>
</Steps>
</Tab>
<Tab title="No Code">
<Steps>
<Step title="Install Package">
Install the PraisonAI package:
```bash
pip install praisonai
```
</Step>
<Step title="Set API Key">
Set your OpenAI API key as an environment variable in your terminal:
```bash
export OPENAI_API_KEY=your_api_key_here
```
</Step>
<Step title="Create a file">
Create a new file `agents.yaml` with the basic setup:
```yaml
framework: praisonai
process: sequential
topic: perform financial and statistical analysis
roles:
calculator:
backstory: Expert in mathematical computations and analysis.
goal: Perform complex calculations
role: Mathematical Calculator
tools:
- evaluate
- solve_equation
- convert_units
tasks:
calc_task:
description: Calculate compound interest for investment scenario.
expected_output: Detailed interest calculations.
statistician:
backstory: Expert in statistical analysis and interpretation.
goal: Analyze numerical data and patterns
role: Statistical Analyst
tools:
- calculate_statistics
- calculate_financial
tasks:
stats_task:
description: Analyze the monthly interest distribution.
expected_output: Statistical analysis report.
```
</Step>
<Step title="Start Agents">
Type this in your terminal to run your agents:
```bash
praisonai agents.yaml
```
</Step>
</Steps>
</Tab>
</Tabs>
### Configuration Options
```python
from praisonaiagents import Agent, Task, PraisonAIAgents
from praisonaiagents.tools import evaluate, solve_equation
# Create agent
math_agent = Agent(
name="MathAssistant",
description="Expert in mathematical calculations",
tools=[evaluate, solve_equation]
)
# Define tasks
calculation_task = Task(
description="Calculate the value of: (3 + 4) * 2 - sqrt(16)",
expected_output="The result of the mathematical expression",
agent=math_agent
)
equation_task = Task(
description="Solve the equation: x^2 - 5x + 6 = 0",
expected_output="The solutions to the quadratic equation",
agent=math_agent
)
# Initialize and run agents
agents = PraisonAIAgents(
agents=[math_agent],
tasks=[calculation_task, equation_task]
)
result = agents.start()
```
### Advanced Mathematical Operations
<CodeGroup>
```python Statistical Analysis
# Create a statistical analysis task
stats_task = Task(
description="""
Calculate statistical metrics for the dataset:
[12, 15, 18, 22, 25, 28, 32, 35, 38, 42]
""",
agent=math_agent
)
```
```python Financial Calculations
# Create a financial calculation task
finance_task = Task(
description="""
Calculate compound interest for:
- Principal: $10,000
- Rate: 5% annually
- Time: 3 years
- Compounding: Monthly
""",
agent=math_agent
)
```
</CodeGroup>
## Best Practices
<AccordionGroup>
<Accordion title="Expression Handling">
Handle expressions safely:
```python
# Good - Using variables dictionary
evaluate(
"x^2 + y",
variables={"x": 3, "y": 4}
)
# Good - Setting precision
evaluate(
"pi + e",
precision=5
)
```
</Accordion>
<Accordion title="Task Description">
Write clear mathematical requirements:
```python
# Good
Task(description="""
Calculate the following:
1. Area of a circle with radius 5
2. Convert the result to square inches
3. Round to 2 decimal places
""")
# Too vague
Task(description="Do some math")
```
</Accordion>
</AccordionGroup>
## Common Patterns
### Multi-Step Calculations
```python
# Calculate area
area_task = Task(
description="Calculate the area of a circle with radius 5",
agent=math_agent
)
# Convert units
conversion_task = Task(
description="Convert the area from square meters to square feet",
agent=math_agent
)
# Format result
formatting_task = Task(
description="Round the result to 2 decimal places",
agent=math_agent
)
```
### Statistical Analysis Pipeline
```python
# Gather data
data_task = Task(
description="Generate a dataset of 100 random numbers",
agent=math_agent
)
# Calculate statistics
stats_task = Task(
description="Calculate mean, median, mode, and standard deviation",
agent=math_agent
)
# Visualize results
viz_task = Task(
description="Create a summary of the statistical analysis",
agent=math_agent
# Create an agent with advanced math configuration
agent = Agent(
role="Math Expert",
goal="Perform complex mathematical analysis",
backstory="Expert in mathematical computations",
tools=[
evaluate,
solve_equation,
convert_units,
calculate_statistics,
calculate_financial
],
verbose=True, # Enable detailed logging
llm="gpt-4o" # Language model to use
)
```
@@ -243,37 +317,31 @@ viz_task = Task(
<CardGroup cols={2}>
<Card title="Expression Errors" icon="triangle-exclamation">
Check expression syntax and variable definitions:
```python
try:
result = evaluate("x + y", variables={"x": 1})
except Exception as e:
print(f"Error: Missing variable 'y'")
```
If expressions are not evaluating:
- Check syntax and formatting
- Verify variable definitions
- Enable verbose mode for debugging
</Card>
<Card title="Unit Conversion" icon="ruler">
Ensure compatible unit types and valid unit names
```python
# Valid conversion
convert_units(100, "celsius", "fahrenheit")
# Invalid conversion
# convert_units(100, "meters", "celsius")
```
<Card title="Calculation Issues" icon="calculator">
If calculations are incorrect:
- Review input formats
- Check unit compatibility
- Verify formula structure
</Card>
</CardGroup>
## Next Steps
<CardGroup cols={2}>
<Card title="Advanced Mathematics" icon="graduation-cap" href="./advanced-math">
Learn about complex mathematical operations
<Card title="AutoAgents" icon="robot" href="./autoagents">
Learn about automatically created and managed AI agents
</Card>
<Card title="Custom Math Tools" icon="wrench" href="./custom-tools">
Create custom mathematical computation tools
<Card title="Mini Agents" icon="microchip" href="./mini">
Explore lightweight, focused AI agents
</Card>
</CardGroup>
<Note>
Math agents provide a powerful way to perform complex mathematical operations, statistical analysis, and financial calculations. They're perfect for data analysis, scientific computing, and financial modeling tasks.
For optimal results, ensure mathematical expressions and units are properly formatted for your specific use case.
</Note>
+93 -65
View File
@@ -4,47 +4,101 @@ description: "Learn how to create simple yet powerful AI agents in just a few li
icon: "robot"
---
<Note>
**Prerequisites**
- Python 3.10 or higher
- PraisonAI Agents package installed
- Basic understanding of Python
</Note>
## Quick Start
Create multiple AI agents that can work together in just a few lines of code!
<Tabs>
<Tab title="Code">
<Steps>
<Step title="Install Package">
First, install the PraisonAI Agents package:
```bash
pip install praisonaiagents duckduckgo_search
```
</Step>
<Step title="Set API Key">
Set your OpenAI API key as an environment variable in your terminal:
```bash
export OPENAI_API_KEY=your_api_key_here
```
</Step>
<Step title="Create Your Agents">
<CodeGroup>
```python Single Agent
from praisonaiagents import Agent, PraisonAIAgents
summarise_agent = Agent(instructions="Summarise Photosynthesis")
agents = PraisonAIAgents(agents=[summarise_agent])
agents.start()
```
```python Multiple Agents
# Agent with Internet Search Tool
from praisonaiagents import Agent, PraisonAIAgents
research_agent = Agent(instructions="Research about AI 2024", tools=[Tools.internet_search])
summarise_agent = Agent(instructions="Summarise research agent's findings")
agents = PraisonAIAgents(agents=[research_agent, summarise_agent])
agents.start()
```
</CodeGroup>
</Step>
<Step title="Run Your Agents">
Execute your agents by running:
```bash
python app.py
```
</Step>
</Steps>
</Tab>
<Tab title="No Code">
<Steps>
<Step title="Install Package">
First, install the PraisonAI Agents package:
```bash
pip install praisonaiagents duckduckgo_search
```
</Step>
<Step title="Set API Key">
Set your OpenAI API key as an environment variable in your terminal:
```bash
export OPENAI_API_KEY=your_api_key_here
```
</Step>
<Step title="Create Your Agents">
<CodeGroup>
```yaml Single Agent
# Create a new file `agents.yaml` with the following content:
roles:
summarise_agent
instructions: Summarise Photosynthesis
```
```yaml Multiple Agents
# Create a new file `agents.yaml` with the following content:
# Agent with Internet Search Tool
roles:
research_agent
instructions: Research about AI 2024
tools:
- internet_search
summarise_agent
instructions: Summarise research agent's findings
```
</CodeGroup>
</Step>
<Step title="Run Your Agents">
Execute your agents by running:
```bash
python app.py
```
</Step>
</Steps>
</Tab>
</Tabs>
<Steps>
<Step title="Install Package">
First, install the PraisonAI Agents package:
```bash
pip install praisonaiagents
```
</Step>
<Step title="Import Required Components">
Import the necessary components:
```python
from praisonaiagents import Agent, Agents
```
</Step>
<Step title="Create Your Agents">
Create specialized agents with specific roles:
```python
summarise_agent = Agent(instructions="Summarise what is Photosynthesis")
```
</Step>
<Step title="Start Your Agents">
Initialize and run your agents:
```python
agents = Agents(agents=[summarise_agent])
agents.start()
```
</Step>
</Steps>
<Note>
**Prerequisites**
- Python 3.10 or higher
- OpenAI API key. Generate OpenAI API key [here](https://platform.openai.com/api-keys). Use Other models using [this guide](/models).
</Note>
<br />
<div className="relative w-full aspect-video">
<iframe
@@ -55,6 +109,7 @@ Create multiple AI agents that can work together in just a few lines of code!
allowFullScreen
></iframe>
</div>
<br />
## Understanding Mini AI Agents
@@ -106,34 +161,7 @@ Create multiple AI agents that can work together in just a few lines of code!
</Card>
</CardGroup>
## Examples
### Basic Research and Summary
```terminal
pip install praisonaiagents duckduckgo_search
```
```python
from praisonaiagents import Agent, Agents, Tools
# Create a research agent
research_agent = Agent(
instructions="You are a research agent to search internet about AI 2024",
tools=[Tools.internet_search]
)
# Create a summarize agent
summarise_agent = Agent(
instructions="You are a summarize agent to summarise research agent's findings"
)
# Initialize and run agents
agents = Agents(agents=[research_agent, summarise_agent])
agents.start()
```
### Custom Instructions
## Custom Instructions
<CodeGroup>
```python Basic
+314
View File
@@ -0,0 +1,314 @@
---
title: "Multimodal Agents"
description: "Guide for creating and using multimodal AI agents in PraisonAI for processing images, videos, and other media types"
icon: "images"
---
## Quick Start
<Tabs>
<Tab title="Code">
<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 in your terminal:
```bash
export OPENAI_API_KEY=xxxxxxxxxxxxxxxxxxxxxx
```
</Step>
<Step title="Create a file">
Create a new file `app.py` with the basic setup:
```python
from praisonaiagents import Agent, Task, PraisonAIAgents
# Create Vision Analysis Agent
vision_agent = Agent(
name="VisionAnalyst",
role="Computer Vision 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 with different media types
task = 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=vision_agent,
images=["https://upload.wikimedia.org/wikipedia/commons/b/bf/Krakow_-_Kosciol_Mariacki.jpg"]
)
# Run the agents
agents = PraisonAIAgents(
agents=[vision_agent],
tasks=[task],
process="sequential",
verbose=True
)
agents.start()
```
</Step>
<Step title="Start Agents">
Type this in your terminal to run your agents:
```bash
python app.py
```
</Step>
</Steps>
</Tab>
<Tab title="No Code">
<Steps>
<Step title="Install Package">
Install the PraisonAI package:
```bash
pip install praisonai
```
</Step>
<Step title="Set API Key">
Set your OpenAI API key as an environment variable in your terminal:
```bash
export OPENAI_API_KEY=xxxxxxxxxxxxxxxxxxxxxx
```
</Step>
<Step title="Create a file">
Create a new file `agents.yaml` with the basic setup:
```yaml
framework: praisonai
process: sequential
topic: analyze landmark image
roles:
vision_analyst:
name: VisionAnalyst
role: Computer Vision 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
tasks:
analyze_landmark:
description: Describe this famous landmark and its architectural features.
expected_output: Detailed description of the landmark's architecture and significance
images:
- https://upload.wikimedia.org/wikipedia/commons/b/bf/Krakow_-_Kosciol_Mariacki.jpg
```
</Step>
<Step title="Start Agents">
Type this in your terminal to run your agents:
```bash
praisonai agents.yaml
```
</Step>
</Steps>
</Tab>
</Tabs>
<Note>
**Requirements**
- Python 3.10 or higher
- OpenAI API key with vision model access
- Basic understanding of Python and media handling
</Note>
<div className="relative w-full aspect-video">
<iframe
className="absolute top-0 left-0 w-full h-full"
src="https://www.youtube.com/embed/hjAWmUT1qqY"
title="YouTube video player"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowFullScreen
></iframe>
</div>
## Understanding Multimodal Agents
<Card title="What are Multimodal Agents?" icon="question">
Multimodal agents are designed to:
- Process multiple types of data (text, images, videos)
- Understand context across different modalities
- Generate insights from diverse media sources
- Handle complex multimedia tasks
</Card>
## Features
<CardGroup cols={2}>
<Card title="Vision Processing" icon="eye">
Analyze images, detect objects, and understand visual content.
</Card>
<Card title="Video Analysis" icon="video">
Process video content for events and actions.
</Card>
<Card title="Text Extraction" icon="font">
Extract and analyze text from images and documents.
</Card>
<Card title="Cross-Modal Understanding" icon="arrows-repeat">
Integrate insights across different media types.
</Card>
</CardGroup>
## Multi-Agent Media Processing
<Tabs>
<Tab title="Code">
```python
from praisonaiagents import Agent, Task, PraisonAIAgents
# Create first agent for image analysis
vision_agent = Agent(
role="Image Analyst",
goal="Analyze visual content and extract key information",
backstory="Expert in visual analysis and image understanding",
llm="gpt-4o-mini",
self_reflect=False
)
# Create second agent for content writing
writer_agent = Agent(
role="Content Writer",
goal="Create engaging content based on image analysis",
backstory="Expert in creating compelling content from visual insights",
llm="gpt-4o-mini"
)
# Create tasks for different media types
document_task = Task(
description="Extract and summarize text from this document image",
expected_output="Structured text content with key information highlighted",
agent=vision_agent,
images=["document.jpg"]
)
writing_task = Task(
description="Create engaging content based on image analysis",
expected_output="Compelling article incorporating visual insights",
agent=writer_agent
)
# Create and start the agents
agents = PraisonAIAgents(
agents=[vision_agent, writer_agent],
tasks=[document_task, writing_task],
process="sequential"
)
result = agents.start()
```
</Tab>
<Tab title="No Code">
```yaml
framework: praisonai
process: sequential
topic: document analysis and content creation
roles:
vision_analyst:
role: Image Analyst
goal: Analyze visual content and extract key information
backstory: Expert in visual analysis and image understanding
llm: gpt-4o-mini
self_reflect: false
tasks:
document_task:
description: Extract and summarize text from this document image
expected_output: Structured text content with key information highlighted
images:
- document.jpg
content_writer:
role: Content Writer
goal: Create engaging content based on image analysis
backstory: Expert in creating compelling content from visual insights
llm: gpt-4o-mini
tasks:
writing_task:
description: Create engaging content based on image analysis
expected_output: Compelling article incorporating visual insights
```
</Tab>
</Tabs>
### Configuration Options
```python
# Create an agent with multimodal configuration
agent = Agent(
role="Media Analyst",
goal="Process multiple types of media",
backstory="Expert in multimedia analysis",
llm="gpt-4o-mini", # Must support vision capabilities
verbose=True, # Enable detailed logging
self_reflect=False # Optional: disable self-reflection
)
# Task with media requirements
task = Task(
description="Analyze media content",
expected_output="Comprehensive analysis",
agent=agent,
images=[ # Support multiple media sources
"https://example.com/image1.jpg",
"path/to/local/image.jpg",
"path/to/video.mp4"
]
)
```
## Best Practices
<CardGroup cols={2}>
<Card title="Media Handling" icon="image">
- Use supported formats (JPEG, PNG)
- Keep reasonable file sizes
- Provide high-quality media
- Validate files before processing
</Card>
<Card title="Task Design" icon="list-check">
- Write clear descriptions
- Break down complex analyses
- Specify expected outputs
- Handle errors gracefully
</Card>
</CardGroup>
## Example Use Cases
<CardGroup cols={2}>
<Card title="Document Analysis" icon="file-lines">
Extract and analyze text from document images.
</Card>
<Card title="Security Monitoring" icon="camera-cctv">
Monitor security feeds for suspicious activity.
</Card>
<Card title="Medical Imaging" icon="microscope">
Analyze medical scans for abnormalities.
</Card>
<Card title="Architectural Analysis" icon="building">
Study architectural features and designs.
</Card>
</CardGroup>
## Next Steps
<CardGroup cols={2}>
<Card title="AutoAgents" icon="robot" href="./autoagents">
Learn about automatically created and managed AI agents
</Card>
<Card title="Mini Agents" icon="microchip" href="./mini">
Explore lightweight, focused AI agents
</Card>
</CardGroup>
<Note>
For optimal results, ensure your media files are in supported formats and sizes for processing.
</Note>
+278
View File
@@ -0,0 +1,278 @@
---
title: "Agentic Orchestrator Worker"
sidebarTitle: "Orchestrator Worker"
description: "Learn how to create AI agents that orchestrate and distribute tasks among specialized workers."
icon: "sitemap"
---
```mermaid
flowchart LR
In[In] --> Router[LLM Call Router]
Router --> LLM1[LLM Call 1]
Router --> LLM2[LLM Call 2]
Router --> LLM3[LLM Call 3]
LLM1 --> Synthesizer[Synthesizer]
LLM2 --> Synthesizer
LLM3 --> Synthesizer
Synthesizer --> Out[Out]
style In fill:#8B0000,color:#fff
style Router fill:#2E8B57,color:#fff
style LLM1 fill:#2E8B57,color:#fff
style LLM2 fill:#2E8B57,color:#fff
style LLM3 fill:#2E8B57,color:#fff
style Synthesizer fill:#2E8B57,color:#fff
style Out fill:#8B0000,color:#fff
```
A workflow with a central orchestrator directing multiple worker LLMs to perform subtasks, synthesizing their outputs for complex, coordinated operations.
## 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 in your terminal:
```bash
export OPENAI_API_KEY=your_api_key_here
```
</Step>
<Step title="Create a file">
Create a new file `app.py` with the basic setup:
```python
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}")
```
</Step>
<Step title="Start Agents">
Type this in your terminal to run your agents:
```bash
python app.py
```
</Step>
</Steps>
<Note>
**Requirements**
- Python 3.10 or higher
- OpenAI API key. Generate OpenAI API key [here](https://platform.openai.com/api-keys). Use Other models using [this guide](/models).
- Basic understanding of Python
</Note>
## Understanding Orchestrator-Worker Pattern
<Card title="What is Orchestrator-Worker?" icon="question">
Orchestrator-Worker pattern enables:
- Dynamic task distribution and routing
- Specialized worker execution
- Result synthesis and aggregation
- Coordinated workflow management
</Card>
## Features
<CardGroup cols={2}>
<Card title="Task Routing" icon="route">
Intelligently distribute tasks to specialized workers.
</Card>
<Card title="Worker Specialization" icon="user-gear">
Dedicated agents for specific task types.
</Card>
<Card title="Result Synthesis" icon="object-group">
Combine and process worker outputs effectively.
</Card>
<Card title="Process Control" icon="sliders">
Monitor and manage the orchestrated workflow.
</Card>
</CardGroup>
## Configuration Options
```python
# Create an orchestrator agent
router = Agent(
name="Router",
role="Task router",
goal="Distribute tasks based on conditions",
tools=[get_time_check], # Tools for routing decisions
verbose=True # Enable detailed logging
)
# Create a worker agent
worker = Agent(
name="Worker",
role="Specialized worker",
goal="Handle specific task type",
instructions="Processing instructions"
)
# Create routing task
router_task = Task(
name="route_task",
description="Route tasks to workers",
agent=router,
is_start=True,
task_type="decision",
condition={
"1": ["worker1_task"],
"2": ["worker2_task"]
}
)
# Create synthesis task
synthesis_task = Task(
name="synthesize",
description="Combine worker results",
agent=synthesizer,
context=[worker1_task, worker2_task] # Reference worker tasks
)
```
## Troubleshooting
<CardGroup cols={2}>
<Card title="Routing Issues" icon="triangle-exclamation">
If task routing fails:
- Check routing conditions
- Verify worker availability
- Enable verbose mode for debugging
</Card>
<Card title="Synthesis Flow" icon="diagram-project">
If result synthesis is incorrect:
- Review worker outputs
- Check context connections
- Verify synthesis logic
</Card>
</CardGroup>
## Next Steps
<CardGroup cols={2}>
<Card title="AutoAgents" icon="robot" href="./autoagents">
Learn about automatically created and managed AI agents
</Card>
<Card title="Mini Agents" icon="microchip" href="./mini">
Explore lightweight, focused AI agents
</Card>
</CardGroup>
<Note>
For optimal results, ensure your routing logic is well-defined and your workers are properly configured for their specialized tasks.
</Note>
+252
View File
@@ -0,0 +1,252 @@
---
title: "Agentic Parallelization"
sidebarTitle: "Parallelization"
description: "Learn how to create AI agents that can execute tasks in parallel for improved performance."
icon: "arrows-split-up-and-left"
---
```mermaid
flowchart LR
In[In] --> LLM2[LLM Call 2]
In --> LLM1[LLM Call 1]
In --> LLM3[LLM Call 3]
LLM1 --> Aggregator[Aggregator]
LLM2 --> Aggregator
LLM3 --> Aggregator
Aggregator --> Out[Out]
style In fill:#8B0000,color:#fff
style LLM1 fill:#2E8B57,color:#fff
style LLM2 fill:#2E8B57,color:#fff
style LLM3 fill:#2E8B57,color:#fff
style Aggregator fill:#fff,color:#000
style Out fill:#8B0000,color:#fff
```
A workflow that distributes tasks across multiple LLM calls simultaneously, aggregating results to handle complex or large-scale operations efficiently.
## 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 in your terminal:
```bash
export OPENAI_API_KEY=your_api_key_here
```
</Step>
<Step title="Create a file">
Create a new file `app.py` with the basic setup:
```python
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())
```
</Step>
<Step title="Start Agents">
Type this in your terminal to run your agents:
```bash
python app.py
```
</Step>
</Steps>
<Note>
**Requirements**
- Python 3.10 or higher
- OpenAI API key. Generate OpenAI API key [here](https://platform.openai.com/api-keys). Use Other models using [this guide](/models).
- Basic understanding of Python and async programming
</Note>
## Understanding Parallelisation
<Card title="What is Parallelisation?" icon="question">
Parallelisation enables:
- Concurrent execution of multiple tasks
- Improved performance through parallel processing
- Efficient handling of independent operations
- Aggregation of parallel task results
</Card>
## Features
<CardGroup cols={2}>
<Card title="Parallel Execution" icon="arrows-split-up-and-left">
Run multiple tasks simultaneously for improved performance.
</Card>
<Card title="Async Support" icon="bolt">
Built-in support for asynchronous execution.
</Card>
<Card title="Result Aggregation" icon="layer-group">
Combine results from parallel tasks efficiently.
</Card>
<Card title="Process Control" icon="sliders">
Monitor and manage parallel task execution.
</Card>
</CardGroup>
## Configuration Options
```python
# Create a parallel task
task = Task(
name="parallel_task",
description="Task to run in parallel",
expected_output="Task result",
agent=agent,
is_start=True,
async_execution=True # Enable parallel execution
)
# Create an aggregator task
aggregator_task = Task(
name="aggregate",
description="Aggregate results from parallel tasks",
expected_output="Combined results",
agent=aggregator,
context=[task1, task2, task3] # Reference parallel tasks
)
# Async workflow execution
async def run_workflow():
workflow = PraisonAIAgents(
agents=[agent1, agent2, aggregator],
tasks=[task1, task2, aggregator_task],
process="workflow",
verbose=True
)
results = await workflow.astart()
```
## Troubleshooting
<CardGroup cols={2}>
<Card title="Execution Issues" icon="triangle-exclamation">
If parallel execution fails:
- Check async configuration
- Verify task independence
- Monitor resource usage
</Card>
<Card title="Result Aggregation" icon="diagram-project">
If aggregation is incorrect:
- Review task outputs
- Check context connections
- Verify aggregator logic
</Card>
</CardGroup>
## Next Steps
<CardGroup cols={2}>
<Card title="AutoAgents" icon="robot" href="./autoagents">
Learn about automatically created and managed AI agents
</Card>
<Card title="Mini Agents" icon="microchip" href="./mini">
Explore lightweight, focused AI agents
</Card>
</CardGroup>
<Note>
For optimal results, ensure your parallel tasks are truly independent and your system has sufficient resources to handle concurrent execution.
</Note>
+265
View File
@@ -0,0 +1,265 @@
---
title: "Agentic Prompt Chaining"
sidebarTitle: "Prompt Chaining"
description: "Learn how to create AI agents with sequential prompt chaining for complex workflows."
icon: "link"
---
```mermaid
flowchart LR
In[In] --> LLM1[LLM Call 1] --> Gate{Gate}
Gate -->|Pass| LLM2[LLM Call 2] -->|Output 2| LLM3[LLM Call 3] --> Out[Out]
Gate -->|Fail| Exit[Exit]
style In fill:#8B0000,color:#fff
style LLM1 fill:#2E8B57,color:#fff
style LLM2 fill:#2E8B57,color:#fff
style LLM3 fill:#2E8B57,color:#fff
style Out fill:#8B0000,color:#fff
style Exit fill:#8B0000,color:#fff
```
A workflow where the output of one LLM call becomes the input for the next. This sequential design allows for structured reasoning and step-by-step task completion.
## 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 in your terminal:
```bash
export OPENAI_API_KEY=your_api_key_here
```
</Step>
<Step title="Create a file">
Create a new file `app.py` with the basic setup:
```python
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": "" # 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}")
```
</Step>
<Step title="Start Agents">
Type this in your terminal to run your agents:
```bash
python app.py
```
</Step>
</Steps>
<Note>
**Requirements**
- Python 3.10 or higher
- OpenAI API key. Generate OpenAI API key [here](https://platform.openai.com/api-keys). Use Other models using [this guide](/models).
- Basic understanding of Python
</Note>
## Understanding Prompt Chaining
<Card title="What is Prompt Chaining?" icon="question">
Prompt chaining enables:
- Sequential execution of prompts
- Data flow between agents
- Conditional branching in workflows
- Step-by-step processing of complex tasks
</Card>
## Features
<CardGroup cols={2}>
<Card title="Sequential Processing" icon="arrow-right">
Execute tasks in a defined sequence with data passing between steps.
</Card>
<Card title="Decision Points" icon="code-branch">
Implement conditional logic to control workflow progression.
</Card>
<Card title="Data Flow" icon="arrows-up-down">
Pass data seamlessly between agents in the chain.
</Card>
<Card title="Process Control" icon="sliders">
Monitor and control the execution of each step in the chain.
</Card>
</CardGroup>
## Configuration Options to exit the chain
```python
# Task with chaining configuration
task = Task(
name="time_check",
description="Check time and make decision",
expected_output="Time check result",
agent=agent,
is_start=True,
task_type="decision",
next_tasks=["next_step"],
condition={
"even": ["next_step"],
"odd": ""
}
)
```
```python
task = Task(
name="time_check",
description="Check time and make decision",
expected_output="Time check result",
agent=agent,
is_start=True,
task_type="decision",
next_tasks=["next_step"],
condition={
"even": ["next_step"],
"odd": "exit"
}
)
```
```python
task = Task(
name="time_check",
description="Check time and make decision",
expected_output="Time check result",
agent=agent,
is_start=True,
task_type="decision",
next_tasks=["next_step"],
condition={
"even": ["next_step"],
"odd": ["exit"]
}
)
```
```python
task = Task(
name="time_check",
description="Check time and make decision",
expected_output="Time check result",
agent=agent,
is_start=True,
task_type="decision",
next_tasks=["next_step"],
condition={
"even": ["next_step"],
"odd": [""]
}
)
```
## Troubleshooting
<CardGroup cols={2}>
<Card title="Chain Issues" icon="triangle-exclamation">
If chain execution fails:
- Verify task connections
- Check condition logic
- Enable verbose mode for debugging
</Card>
<Card title="Data Flow" icon="diagram-project">
If data flow is incorrect:
- Review task outputs
- Check agent configurations
- Verify task dependencies
</Card>
</CardGroup>
## Next Steps
<CardGroup cols={2}>
<Card title="AutoAgents" icon="robot" href="./autoagents">
Learn about automatically created and managed AI agents
</Card>
<Card title="Mini Agents" icon="microchip" href="./mini">
Explore lightweight, focused AI agents
</Card>
</CardGroup>
<Note>
For optimal results, ensure your chain is properly configured with clear task dependencies and conditions for branching logic.
</Note>
+323 -209
View File
@@ -1,10 +1,139 @@
---
title: "Reasoning AI Agents"
sidebarTitle: "Reasoning"
description: "Reasoning enables AI agents to think logically, solve complex problems autonomously, and make human-like decisions through multi-step logical reasoning."
icon: "brain-circuit"
title: "Reasoning Agents"
description: "Learn how to create AI agents with advanced reasoning capabilities for complex problem-solving."
icon: "brain"
---
```mermaid
flowchart LR
In[In] --> Agent[AI Agent]
Agent --> Think[Think]
Think --> Decide[Decide]
Decide --> Act[Act]
Act --> Out[Out]
style In fill:#8B0000,color:#fff
style Agent fill:#2E8B57,color:#fff
style Think fill:#2E8B57,color:#fff
style Decide fill:#2E8B57,color:#fff
style Act fill:#2E8B57,color:#fff
style Out fill:#8B0000,color:#fff
```
Learn how to create AI agents with advanced reasoning capabilities for complex problem-solving.
## Quick Start
<Tabs>
<Tab title="Code">
<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 in your terminal:
```bash
export OPENAI_API_KEY=your_api_key_here
```
</Step>
<Step title="Create a file">
Create a new file `app.py` with the basic setup:
```python
from praisonaiagents import Agent, Task, PraisonAIAgents, Tools
# Create reasoning agent
reasoner = Agent(
role="Problem Solver",
goal="Solve complex problems using logical reasoning",
backstory="Expert in logical analysis and problem-solving",
tools=[Tools.internet_search],
verbose=True
)
# Create task
task = Task(
description="Analyze and solve a complex business problem",
expected_output="Detailed solution with reasoning steps",
agent=reasoner
)
# Create and start the agents
agents = PraisonAIAgents(
agents=[reasoner],
tasks=[task],
process="sequential",
verbose=2
)
# Start execution
result = agents.start()
print(result)
```
</Step>
<Step title="Start Agents">
Type this in your terminal to run your agents:
```bash
python app.py
```
</Step>
</Steps>
</Tab>
<Tab title="No Code">
<Steps>
<Step title="Install Package">
Install the PraisonAI package:
```bash
pip install praisonai
```
</Step>
<Step title="Set API Key">
Set your OpenAI API key as an environment variable in your terminal:
```bash
export OPENAI_API_KEY=your_api_key_here
```
</Step>
<Step title="Create a file">
Create a new file `agents.yaml` with the basic setup:
```yaml
framework: praisonai
process: sequential
topic: solve complex business problem
roles:
reasoner:
backstory: Expert in logical analysis and problem-solving.
goal: Solve complex problems using logical reasoning
role: Problem Solver
tools:
- internet_search
tasks:
analysis_task:
description: Analyze and solve a complex business problem.
expected_output: Detailed solution with reasoning steps.
```
</Step>
<Step title="Start Agents">
Type this in your terminal to run your agents:
```bash
praisonai agents.yaml
```
</Step>
</Steps>
</Tab>
</Tabs>
<Note>
**Requirements**
- Python 3.10 or higher
- OpenAI API key. Generate OpenAI API key [here](https://platform.openai.com/api-keys). Use Other models using [this guide](/models).
- Basic understanding of Python
</Note>
<div className="relative w-full aspect-video">
<iframe
className="absolute top-0 left-0 w-full h-full"
@@ -15,225 +144,210 @@ icon: "brain-circuit"
></iframe>
</div>
## Overview
## Understanding Reasoning
Reasoning in PraisonAI agents enables:
- Autonomous problem solving
- Multi-step logical reasoning
- Human-like decision making
- Deep comprehension of tasks
- Error handling with alternative solutions
<Card title="What is Reasoning?" icon="question">
Reasoning agents are designed to:
- Break down complex problems into manageable steps
- Apply logical analysis to find solutions
- Explain their thought process and decisions
- Handle uncertainty and incomplete information
</Card>
## Usage
## Features
Reasoning is controlled through reflection cycles using `min_reflect` and `max_reflect` parameters:
<CardGroup cols={2}>
<Card title="Problem Decomposition" icon="puzzle-piece">
Break complex problems into smaller, manageable parts.
</Card>
<Card title="Logical Analysis" icon="brain">
Apply structured thinking to solve problems.
</Card>
<Card title="Error Recovery" icon="shield-check">
Handle edge cases and recover from errors.
</Card>
<Card title="Explanation" icon="comment">
Provide detailed reasoning for decisions.
</Card>
</CardGroup>
## Multi-Agent Reasoning
<Tabs>
<Tab title="Code">
<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 in your terminal:
```bash
export OPENAI_API_KEY=your_api_key_here
```
</Step>
<Step title="Create a file">
Create a new file `app.py` with the basic setup:
```python
from praisonaiagents import Agent, Task, PraisonAIAgents, Tools
# Create first agent for analysis
analyst = Agent(
role="Business Analyst",
goal="Analyze business problems and identify key issues",
backstory="Expert in business analysis and problem identification",
tools=[Tools.internet_search],
verbose=True
)
# Create second agent for solution development
solver = Agent(
role="Solution Architect",
goal="Develop comprehensive solutions to business problems",
backstory="Expert in solution design and implementation",
verbose=True
)
# Create first task
analysis_task = Task(
description="Analyze the current market challenges",
expected_output="Detailed analysis of key issues",
agent=analyst
)
# Create second task
solution_task = Task(
description="Develop solutions for identified challenges",
expected_output="Comprehensive solution strategy",
agent=solver
)
# Create and start the agents
agents = PraisonAIAgents(
agents=[analyst, solver],
tasks=[analysis_task, solution_task],
process="sequential"
)
# Start execution
result = agents.start()
```
</Step>
<Step title="Start Agents">
Type this in your terminal to run your agents:
```bash
python app.py
```
</Step>
</Steps>
</Tab>
<Tab title="No Code">
<Steps>
<Step title="Install Package">
Install the PraisonAI package:
```bash
pip install praisonai
```
</Step>
<Step title="Set API Key">
Set your OpenAI API key as an environment variable in your terminal:
```bash
export OPENAI_API_KEY=your_api_key_here
```
</Step>
<Step title="Create a file">
Create a new file `agents.yaml` with the basic setup:
```yaml
framework: praisonai
process: sequential
topic: solve market challenges
roles:
analyst:
backstory: Expert in business analysis and problem identification.
goal: Analyze business problems and identify key issues
role: Business Analyst
tools:
- internet_search
tasks:
analysis_task:
description: Analyze the current market challenges.
expected_output: Detailed analysis of key issues.
solver:
backstory: Expert in solution design and implementation.
goal: Develop comprehensive solutions to business problems
role: Solution Architect
tasks:
solution_task:
description: Develop solutions for identified challenges.
expected_output: Comprehensive solution strategy.
```
</Step>
<Step title="Start Agents">
Type this in your terminal to run your agents:
```bash
praisonai agents.yaml
```
</Step>
</Steps>
</Tab>
</Tabs>
### Configuration Options
```python
from praisonaiagents import Agent
# Create an agent with reasoning configuration
agent = Agent(
name="SystemOps",
role="System Administrator",
goal="Manage and monitor system operations",
backstory="You are an expert system administrator",
min_reflect=6, # Minimum reflection cycles
max_reflect=10 # Maximum reflection cycles
)
```
## Benefits
- **Deep Comprehension**: Instead of rule-based responses, agents understand tasks deeply
- **Error Recovery**: Agents can reason through errors and find alternative solutions
- **Step-by-Step Processing**: Complex tasks are broken down and processed systematically
- **Quality Control**: Multiple reflection cycles ensure high-quality outputs
- **Adaptive Problem Solving**: Agents can adjust their approach based on reasoning
## Example
Here's a complete example showing reasoning in action:
```python
from praisonaiagents import Agent, Task, PraisonAIAgents
import subprocess
import os
def run_terminal_command(command: str):
"""
Run a terminal command and return its output.
"""
try:
result = subprocess.run(command, shell=True, check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
print(f"Command output: {result}")
return {"stdout": result.stdout, "stderr": result.stderr}
except subprocess.CalledProcessError as e:
return {"error": str(e), "stdout": e.stdout, "stderr": e.stderr}
def save_to_file(file_path: str, content: str):
"""
Save the given content to the specified file path. Create the folder/file if it doesn't exist.
"""
# Ensure the directory exists
os.makedirs(os.path.dirname(file_path), exist_ok=True)
# Write the content to the file
with open(file_path, 'w') as file:
file.write(content)
return file_path
# Create System Operations Agent
system_ops_agent = Agent(
name="SystemOps",
role="System Operations Specialist",
goal="Execute and manage complex system operations and commands",
backstory="""You are an expert system administrator with deep knowledge of Unix/Linux systems.
You excel at running complex system commands, managing processes, and handling system operations.
You always validate commands before execution and ensure they are safe to run.""",
min_reflect=6,
max_reflect=10,
tools=[run_terminal_command, save_to_file],
llm="gpt-4o-mini"
role="Problem Solver",
goal="Solve complex problems",
backstory="Expert in problem-solving",
tools=[Tools.internet_search],
verbose=True, # Enable detailed logging
llm="gpt-4o" # Language model to use
)
# Create a complex task that tests various system operations
# Task with reasoning requirements
task = Task(
name="system_analysis_task",
description="""Perform a comprehensive system analysis by executing the following operations in sequence:
1. Get system information (OS, kernel version)
2. List 5 running processes and sort them by CPU usage
3. Check disk space usage and list directories over 1GB
4. Display current system load and memory usage
5. List 5 network connections
6. Create a summary report with all findings in a text file called system_report.txt
Do it step by step. One task at a time.
Save only the Summary report in the file.
Use appropriate commands for each step and ensure proper error handling.""",
expected_output="A comprehensive system report containing all requested information saved in system_report.txt",
agent=system_ops_agent,
description="Solve complex problem",
expected_output="Detailed solution",
agent=agent
)
agents = PraisonAIAgents(
agents=[system_ops_agent],
tasks=[task],
process="sequential"
)
result = agents.start()
```
## e2b Tool Integration Example
## Troubleshooting
```python
from praisonaiagents import Agent, Task, PraisonAIAgents, error_logs
import json
from e2b_code_interpreter import Sandbox
<CardGroup cols={2}>
<Card title="Reasoning Errors" icon="triangle-exclamation">
If reasoning seems incorrect:
- Check problem description clarity
- Enable verbose mode for debugging
- Review agent configuration
</Card>
def code_interpret(code: str):
"""
A function to demonstrate running Python code dynamically using e2b_code_interpreter.
"""
print(f"\n{'='*50}\n> Running following AI-generated code:\n{code}\n{'='*50}")
exec_result = Sandbox().run_code(code)
if exec_result.error:
print("[Code Interpreter error]", exec_result.error)
return {"error": str(exec_result.error)}
else:
results = []
for result in exec_result.results:
if hasattr(result, '__iter__'):
results.extend(list(result))
else:
results.append(str(result))
logs = {"stdout": list(exec_result.logs.stdout), "stderr": list(exec_result.logs.stderr)}
return json.dumps({"results": results, "logs": logs})
<Card title="Process Flow" icon="code">
If process flow is unclear:
- Verify task dependencies
- Check agent roles and goals
- Review task descriptions
</Card>
</CardGroup>
# 1) Create Agents
web_scraper_agent = Agent(
name="WebScraper",
role="Web Scraper",
goal="Extract URLs from https://quotes.toscrape.com/",
backstory="An expert in data extraction from websites, adept at navigating and retrieving detailed information.",
tools=[code_interpret],
llm="gpt-4o"
)
## Next Steps
url_data_extractor_agent = Agent(
name="URLDataExtractor",
role="URL Data Extractor",
goal="Crawl each URL for data extraction",
backstory="Specializes in crawling websites to gather comprehensive data, ensuring nothing is missed from each link.",
tools=[code_interpret],
llm="gpt-4o"
)
<CardGroup cols={2}>
<Card title="AutoAgents" icon="robot" href="./autoagents">
Learn about automatically created and managed AI agents
</Card>
<Card title="Mini Agents" icon="microchip" href="./mini">
Explore lightweight, focused AI agents
</Card>
</CardGroup>
blog_writer_agent = Agent(
name="BlogWriter",
role="Creative Content Writer",
goal="Create engaging and insightful blog posts from provided data",
backstory="An experienced content creator and storyteller with a knack for weaving compelling narratives. Skilled at analyzing quotes and creating meaningful connections that resonate with readers.",
tools=[code_interpret],
llm="gpt-4o"
)
# 2) Create Tasks
task_url_extraction = Task(
name="url_extraction_task",
description="""Use code_interpret to run Python code that fetches https://quotes.toscrape.com/
and extracts 5 URLs from the page, then outputs them as a list. Only first 5 urls""",
expected_output="A list of URLs extracted from the source page.",
agent=web_scraper_agent,
output_file="urls.txt"
)
task_data_extraction = Task(
name="data_extraction_task",
description="""Take the URLs from url_extraction_task, crawl each URL and extract all pertinent
data using code_interpret to run Python code, then output raw txt, not the html.""",
expected_output="Raw data collected from each crawled URL.",
agent=url_data_extractor_agent,
context=[task_url_extraction]
)
blog_writing_task = Task(
name="blog_writing_task",
description="""Write an engaging blog post using the extracted quotes data. The blog post should:
1. Have a catchy title
2. Include relevant quotes from the data
3. Provide commentary and insights about the quotes
4. Be well-structured with introduction, body, and conclusion
5. Be approximately 500 words long""",
expected_output="A well-written blog post incorporating the extracted quotes with analysis",
agent=blog_writer_agent,
context=[task_data_extraction],
output_file="blog_post.txt"
)
# 3) Create and run Agents manager
agents_manager = PraisonAIAgents(
agents=[web_scraper_agent, url_data_extractor_agent, blog_writer_agent],
tasks=[task_url_extraction, task_data_extraction, blog_writing_task],
verbose=True,
process="hierarchical",
manager_llm="gpt-4o"
)
result = agents_manager.start()
```
## Integration with Tools
Reasoning works particularly well with tools that require complex decision-making:
- **Code Interpreter**: For dynamic code generation and execution
- **System Operations**: For multi-step system management tasks
- **Data Analysis**: For complex data processing workflows
- **Web Scraping**: For intelligent data extraction and processing
## Performance Considerations
- Higher reflection cycles mean more thorough reasoning but longer processing time
- `min_reflect` ensures minimum quality standards
- `max_reflect` prevents excessive processing
- Balance based on task complexity and quality requirements
<Note>
For optimal results, ensure your problem descriptions are clear and provide sufficient context for the reasoning agents.
</Note>
+244
View File
@@ -0,0 +1,244 @@
---
title: "Agentic Routing"
description: "Learn how to create AI agents that can dynamically route tasks to specialized LLM instances."
icon: "route"
---
```mermaid
flowchart LR
In[In] --> Router[LLM Call Router]
Router --> LLM1[LLM Call 1]
Router --> LLM2[LLM Call 2]
Router --> LLM3[LLM Call 3]
LLM1 --> Out[Out]
LLM2 --> Out
LLM3 --> Out
style In fill:#8B0000,color:#fff
style Router fill:#2E8B57,color:#fff
style LLM1 fill:#2E8B57,color:#fff
style LLM2 fill:#2E8B57,color:#fff
style LLM3 fill:#2E8B57,color:#fff
style Out fill:#8B0000,color:#fff
```
A low-latency workflow where inputs are dynamically routed to the most appropriate LLM instance or configuration, optimizing efficiency and specialization.
## 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 in your terminal:
```bash
export OPENAI_API_KEY=your_api_key_here
```
</Step>
<Step title="Create a file">
Create a new file `app.py` with the basic setup:
```python
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)
```
</Step>
<Step title="Start Agents">
Type this in your terminal to run your agents:
```bash
python app.py
```
</Step>
</Steps>
<Note>
**Requirements**
- Python 3.10 or higher
- OpenAI API key. Generate OpenAI API key [here](https://platform.openai.com/api-keys). Use Other models using [this guide](/models).
- Basic understanding of Python
</Note>
<div className="relative w-full aspect-video">
<iframe
className="absolute top-0 left-0 w-full h-full"
src="https://www.youtube.com/embed/KNDVWGN3TpM"
title="YouTube video player"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowFullScreen
></iframe>
</div>
## Understanding Agentic Routing
<Card title="What is Agentic Routing?" icon="question">
Agentic routing enables:
- Dynamic decision-making in workflows
- Conditional task execution paths
- Automated process branching
- Intelligent workflow management
</Card>
## Features
<CardGroup cols={2}>
<Card title="Dynamic Routing" icon="route">
Route tasks based on real-time decisions and conditions.
</Card>
<Card title="Conditional Logic" icon="code-branch">
Implement complex branching logic in workflows.
</Card>
<Card title="Task Management" icon="tasks">
Handle task dependencies and execution order.
</Card>
<Card title="Process Control" icon="sliders">
Control workflow execution with detailed monitoring.
</Card>
</CardGroup>
## Configuration Options
```python
# Create a router agent
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], # Custom tools for routing decisions
verbose=True # Enable detailed logging
)
# Task with routing configuration
routing_task = Task(
name="initial_routing",
description="Route based on conditions",
expected_output="Routing decision",
agent=router,
is_start=True,
task_type="decision",
condition={
"pass": ["next_task"],
"fail": ["alternate_task"]
}
)
```
## Troubleshooting
<CardGroup cols={2}>
<Card title="Routing Issues" icon="triangle-exclamation">
If routing doesn't work as expected:
- Verify condition mappings
- Check task dependencies
- Enable verbose mode for debugging
</Card>
<Card title="Workflow Flow" icon="diagram-project">
If workflow is unclear:
- Review task connections
- Verify agent configurations
- Check routing conditions
</Card>
</CardGroup>
## Next Steps
<CardGroup cols={2}>
<Card title="AutoAgents" icon="robot" href="./autoagents">
Learn about automatically created and managed AI agents
</Card>
<Card title="Mini Agents" icon="microchip" href="./mini">
Explore lightweight, focused AI agents
</Card>
</CardGroup>
<Note>
For optimal results, ensure your routing conditions are well-defined and your task dependencies are properly configured.
</Note>
+324 -73
View File
@@ -1,10 +1,140 @@
---
title: "Self Reflection AI Agents"
sidebarTitle: "Self-Reflection"
description: "Self-reflection is a powerful feature in PraisonAI that enables agents to evaluate and improve their own responses before delivering them. This leads to higher quality outputs and more reliable task completion."
sidebarTitle: "Self Reflection Agents"
description: "Self-reflection enables agents to evaluate and improve their own responses before delivering them."
icon: "brain"
---
```mermaid
flowchart LR
In[In] --> Agent[AI Agent]
Agent --> Reflect[Self Reflection]
Reflect --> Agent
Agent --> Out[Out]
style In fill:#8B0000,color:#fff
style Agent fill:#2E8B57,color:#fff
style Reflect fill:#2E8B57,color:#fff
style Out fill:#8B0000,color:#fff
```
Self-reflection enables agents to evaluate and improve their own responses before delivering them.
## Quick Start
<Tabs>
<Tab title="Code">
<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 in your terminal:
```bash
export OPENAI_API_KEY=your_api_key_here
```
</Step>
<Step title="Create a file">
Create a new file `app.py` with the basic setup:
```python
from praisonaiagents import Agent, Task, PraisonAIAgents
# Create an agent with self-reflection
agent = Agent(
role="Senior Research Analyst",
goal="Analyze and provide insights on given topics",
backstory="You are an expert analyst with strong critical thinking skills",
self_reflect=True # Enable self-reflection
)
# Create a task
task = Task(
description="Analyze recent developments in AI",
expected_output="A detailed analysis report",
agent=agent
)
# Create and start the agents
agents = PraisonAIAgents(
agents=[agent],
tasks=[task],
process="sequential",
verbose=2
)
# Start execution
agents.start()
```
</Step>
<Step title="Start Agents">
Type this in your terminal to run your agents:
```bash
python app.py
```
</Step>
</Steps>
</Tab>
<Tab title="No Code">
<Steps>
<Step title="Install Package">
Install the PraisonAI package:
```bash
pip install praisonai
```
</Step>
<Step title="Set API Key">
Set your OpenAI API key as an environment variable in your terminal:
```bash
export OPENAI_API_KEY=your_api_key_here
```
</Step>
<Step title="Create a file">
Create a new file `agents.yaml` with the basic setup:
```yaml
framework: praisonai
process: sequential
topic: create movie script about cat in mars
roles:
scriptwriter:
backstory: Expert in dialogue and script structure, translating concepts into
scripts.
goal: Write a movie script about a cat in Mars
role: Scriptwriter
self_reflect: true
min_reflect: 1
max_reflect: 2
tasks:
scriptwriting_task:
description: Turn the story concept into a production-ready movie script,
including dialogue and scene details.
expected_output: Final movie script with dialogue and scene details.
tools:
- search_tool
```
</Step>
<Step title="Start Agents">
Type this in your terminal to run your agents:
```bash
praisonai agents.yaml
```
</Step>
</Steps>
</Tab>
</Tabs>
<Note>
**Requirements**
- Python 3.10 or higher
- OpenAI API key. Generate OpenAI API key [here](https://platform.openai.com/api-keys). Use Other models using [this guide](/models).
</Note>
<div className="relative w-full aspect-video">
<iframe
className="absolute top-0 left-0 w-full h-full"
@@ -15,88 +145,209 @@ icon: "brain"
></iframe>
</div>
## Overview
## Understanding Self-Reflection
When an agent with self-reflection enabled processes a task:
1. It generates an initial response using its tools and capabilities
2. The agent then reflects on its own response, evaluating:
- Completeness
- Accuracy
- Relevance
- Quality
3. Based on this reflection, the agent may revise and improve its response
4. This cycle can repeat until the agent is satisfied with the quality
<Card title="What is Self-Reflection?" icon="question">
Self-reflection enables agents to:
- Evaluate their own responses before delivery
- Check for completeness and accuracy
- Improve output quality through iteration
- Ensure task requirements are met
- Make conscious decisions about their responses
</Card>
## Usage
## Features
Self-reflection is enabled by default for all agents. You can explicitly control it using the `self_reflect` parameter:
<CardGroup cols={2}>
<Card title="Quality Assurance" icon="check-double">
Evaluates and improves response quality through self-review.
</Card>
<Card title="Iterative Improvement" icon="rotate">
Refines responses through multiple reflection cycles.
</Card>
<Card title="Task Validation" icon="list-check">
Ensures all aspects of the task are properly addressed.
</Card>
<Card title="Conscious Decision Making" icon="brain">
Enables thoughtful evaluation of responses.
</Card>
</CardGroup>
## Multi-Agent Self-Reflection
<Tabs>
<Tab title="Code">
<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 in your terminal:
```bash
export OPENAI_API_KEY=your_api_key_here
```
</Step>
<Step title="Create a file">
Create a new file `app.py` with the basic setup:
```python
from praisonaiagents import Agent, Task, PraisonAIAgents
# Create first agent with self-reflection
researcher = Agent(
role="Senior Research Analyst",
goal="Research and analyze AI developments",
backstory="Expert analyst specializing in AI trends and impacts",
self_reflect=True,
verbose=True
)
# Create second agent with self-reflection
writer = Agent(
role="Technical Writer",
goal="Transform research into clear documentation",
backstory="Experienced in creating technical content and documentation",
self_reflect=True,
verbose=True
)
# Create first task
research_task = Task(
description="Research and analyze recent AI developments",
expected_output="Comprehensive analysis of AI trends",
agent=researcher
)
# Create second task
documentation_task = Task(
description="Create technical documentation from research findings",
expected_output="Well-structured technical documentation",
agent=writer
)
# Create and start the agents
agents = PraisonAIAgents(
agents=[researcher, writer],
tasks=[research_task, documentation_task],
process="sequential"
)
# Start execution
agents.start()
```
</Step>
<Step title="Start Agents">
Type this in your terminal to run your agents:
```bash
python app.py
```
</Step>
</Steps>
</Tab>
<Tab title="No Code">
<Steps>
<Step title="Install Package">
Install the PraisonAI package:
```bash
pip install praisonai duckduckgo_search
```
</Step>
<Step title="Set API Key">
Set your OpenAI API key as an environment variable in your terminal:
```bash
export OPENAI_API_KEY=your_api_key_here
```
</Step>
<Step title="Create a file">
Create a new file `agents.yaml` with the basic setup:
```yaml
framework: praisonai
process: sequential
topic: create technical documentation about AI trends
roles:
researcher:
backstory: Expert analyst specializing in AI trends and their implications.
goal: Research and analyze current AI developments
role: Senior Research Analyst
self_reflect: true
min_reflect: 1
max_reflect: 2
tasks:
research_task:
description: Research and analyze recent developments in AI technology.
expected_output: Comprehensive analysis of current AI trends.
tools:
- duckduckgo
writer:
backstory: Experienced technical writer skilled in creating clear documentation.
goal: Transform research into accessible documentation
role: Technical Writer
tasks:
documentation_task:
description: Create technical documentation from research findings.
expected_output: Well-structured technical documentation.
```
</Step>
<Step title="Start Agents">
Type this in your terminal to run your agents:
```bash
praisonai agents.yaml
```
</Step>
</Steps>
</Tab>
</Tabs>
### Configuration Options
```python
from praisonaiagents import Agent
# Create an agent with advanced self-reflection configuration
agent = Agent(
name="Researcher",
role="Senior Research Analyst",
goal="Uncover cutting-edge developments in AI",
backstory="You are an expert at analyzing tech trends",
self_reflect=True # Enable self-reflection (default)
role="Research Analyst",
goal="Provide comprehensive analysis",
backstory="Expert analyst with critical thinking skills",
self_reflect=True, # Enable self-reflection
verbose=True, # Enable detailed logging
llm="gpt-4o", # Language model to use
allow_delegation=True # Allow task delegation
)
```
## Benefits
## Troubleshooting
- **Higher Quality Outputs**: Agents can catch and correct potential issues before delivering responses
- **More Reliable Task Completion**: Self-reflection helps ensure all aspects of a task are properly addressed
- **Conscious Decision Making**: Agents evaluate their own work, leading to more thoughtful responses
- **Improved Accuracy**: Multiple reflection cycles help refine and perfect the output
<CardGroup cols={2}>
<Card title="Response Issues" icon="rotate">
If responses are not meeting expectations:
- Enable verbose mode for debugging
- Review agent configuration
- Check task description clarity
</Card>
## Integration with Processes
<Card title="Quality Issues" icon="triangle-exclamation">
If output quality is insufficient:
- Enable verbose mode
- Review agent role and goal
- Clarify expected output
</Card>
</CardGroup>
Self-reflection works seamlessly with both sequential and hierarchical processes:
## Next Steps
- **Sequential**: Each agent self-reflects on their individual tasks
- **Hierarchical**: Agents self-reflect before reporting to the manager agent, ensuring high-quality inputs for decision-making
<CardGroup cols={2}>
<Card title="AutoAgents" icon="robot" href="./autoagents">
Learn about automatically created and managed AI agents
</Card>
<Card title="Mini Agents" icon="microchip" href="./mini">
Explore lightweight, focused AI agents
</Card>
</CardGroup>
## Example
Here's a complete example showing self-reflection in action:
```python
from praisonaiagents import Agent, Task, PraisonAIAgents
researcher = Agent(
name="Researcher",
role="Senior Research Analyst",
goal="Uncover cutting-edge developments in AI",
backstory="You are an expert at analyzing tech trends",
self_reflect=True,
llm="gpt-4o"
)
task = Task(
name="research_task",
description="Analyze 2024's AI advancements",
expected_output="A detailed report on AI trends",
agent=researcher
)
agents = PraisonAIAgents(
agents=[researcher],
tasks=[task],
process="sequential"
)
result = agents.start()
```
In this example, the researcher agent will:
1. Research AI advancements
2. Generate an initial report
3. Self-reflect on the report's quality
4. Make improvements if needed
5. Deliver the final, refined output
## Performance Impact
While self-reflection adds additional processing time, the improvement in output quality often justifies the extra computation.
The number of reflection cycles need to be manually optimized to balance quality and performance.
<Note>
For optimal results, configure reflection parameters based on your specific use case requirements.
</Note>
+311 -264
View File
@@ -4,62 +4,133 @@ description: "Learn how to create AI agents that return structured, type-safe ou
icon: "cube"
---
<Note>
**Prerequisites**
- Python 3.10 or higher
- PraisonAI Agents package installed
- Basic understanding of Python and Pydantic
</Note>
## Quick Start
Create AI agents that return structured, validated outputs in just a few lines of code!
<Tabs>
<Tab title="Code">
<Steps>
<Step title="Install Package">
First, install the PraisonAI Agents package:
```bash
pip install praisonaiagents
```
</Step>
<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 in your terminal:
```bash
export OPENAI_API_KEY=your_api_key_here
```
</Step>
<Step title="Import Required Components">
Import the necessary components:
```python
from praisonaiagents import Agent, Task, PraisonAIAgents, Tools
from pydantic import BaseModel
```
</Step>
<Step title="Create a file">
Create a new file `app.py` with the basic setup:
```python
from praisonaiagents import Agent, Task, PraisonAIAgents, Tools
from pydantic import BaseModel
<Step title="Define Your Data Model">
Create a Pydantic model to define your output structure:
```python
class AnalysisReport(BaseModel):
title: str
findings: str
summary: str
```
</Step>
# Define your data structure
class AnalysisReport(BaseModel):
title: str
findings: str
summary: str
<Step title="Create Structured Tasks">
Create tasks with structured outputs:
```python
research_task = Task(
description="Research recent AI developments",
agent=researcher,
expected_output="Research findings"
)
# Create agent
analyst = Agent(
role="Data Analyst",
goal="Analyze data and provide structured insights",
backstory="Expert in data analysis and insights generation",
tools=[Tools.internet_search],
verbose=True
)
analysis_task = Task(
description="Analyze research findings",
agent=analyst,
output_pydantic=AnalysisReport, # For Pydantic output
# or output_json=AnalysisReport # For JSON output
expected_output="Structured analysis report"
)
```
</Step>
</Steps>
# Create task with structured output
task = Task(
description="Analyze recent AI developments",
expected_output="Structured analysis report",
agent=analyst,
output_pydantic=AnalysisReport
)
# Create and start the agents
agents = PraisonAIAgents(
agents=[analyst],
tasks=[task],
process="sequential",
verbose=2
)
# Start execution
result = agents.start()
print(result.pydantic.title)
print(result.pydantic.findings)
print(result.pydantic.summary)
```
</Step>
<Step title="Start Agents">
Type this in your terminal to run your agents:
```bash
python app.py
```
</Step>
</Steps>
</Tab>
<Tab title="No Code">
<Steps>
<Step title="Install Package">
Install the PraisonAI package:
```bash
pip install praisonai
```
</Step>
<Step title="Set API Key">
Set your OpenAI API key as an environment variable in your terminal:
```bash
export OPENAI_API_KEY=your_api_key_here
```
</Step>
<Step title="Create a file">
Create a new file `agents.yaml` with the basic setup:
```yaml
framework: praisonai
process: sequential
topic: analyze AI developments with structured output
roles:
analyst:
backstory: Expert in data analysis and insights generation.
goal: Analyze data and provide structured insights
role: Data Analyst
tools:
- internet_search
tasks:
analysis_task:
description: Analyze recent AI developments.
expected_output: Structured analysis report.
output_structure:
type: pydantic
model:
title: str
findings: str
summary: str
```
</Step>
<Step title="Start Agents">
Type this in your terminal to run your agents:
```bash
praisonai agents.yaml
```
</Step>
</Steps>
</Tab>
</Tabs>
<Note>
**Requirements**
- Python 3.10 or higher
- OpenAI API key. Generate OpenAI API key [here](https://platform.openai.com/api-keys). Use Other models using [this guide](/models).
- Basic understanding of Python and Pydantic
</Note>
## Understanding Structured Outputs
@@ -71,221 +142,196 @@ Create AI agents that return structured, validated outputs in just a few lines o
- Ensure consistent output format across agent responses
</Card>
## Key Components
## Features
<CardGroup cols={2}>
<Card title="Pydantic Models" icon="cube">
Define your data structure
```python
class ResearchReport(BaseModel):
title: str
content: str
```
</Card>
<Card title="Task Configuration" icon="gear">
Configure output format
```python
Task(output_pydantic=Model)
# or
Task(output_json=Model)
```
</Card>
<Card title="Output Validation" icon="check">
Automatic validation of responses against your model
</Card>
<Card title="Format Options" icon="code">
Choose between Pydantic objects or JSON output
</Card>
</CardGroup>
## Output Types
<CardGroup cols={2}>
<Card title="Pydantic Output" icon="cube">
```python
task = Task(
output_pydantic=AnalysisReport
)
# Returns Pydantic object
```
Get type-safe Pydantic model instances
Define exact data structures with validation.
</Card>
<Card title="JSON Output" icon="brackets-curly">
```python
task = Task(
output_json=AnalysisReport
)
# Returns JSON dict
```
Get JSON dictionary matching model schema
Get structured JSON responses.
</Card>
<Card title="Type Safety" icon="shield-check">
Ensure type-safe, validated outputs.
</Card>
<Card title="Format Options" icon="code">
Choose between Pydantic or JSON.
</Card>
</CardGroup>
## Examples
## Multi-Agent Structured Analysis
### Research Analysis with Structured Output
<Tabs>
<Tab title="Code">
<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 in your terminal:
```bash
export OPENAI_API_KEY=your_api_key_here
```
</Step>
<Step title="Create a file">
Create a new file `app.py` with the basic setup:
```python
from praisonaiagents import Agent, Task, PraisonAIAgents, Tools
from pydantic import BaseModel
# Define output structures
class ResearchReport(BaseModel):
topic: str
findings: str
sources: list[str]
class Analysis(BaseModel):
key_points: list[str]
implications: str
recommendations: str
# Create first agent for research
researcher = Agent(
role="Research Analyst",
goal="Gather and structure research data",
backstory="Expert in research and data collection",
tools=[Tools.internet_search],
verbose=True
)
# Create second agent for analysis
analyst = Agent(
role="Data Analyst",
goal="Analyze research and provide structured insights",
backstory="Expert in data analysis and insights generation",
verbose=True
)
# Create first task
research_task = Task(
description="Research quantum computing developments",
expected_output="Structured research findings",
agent=researcher,
output_pydantic=ResearchReport
)
# Create second task
analysis_task = Task(
description="Analyze research implications",
expected_output="Structured analysis report",
agent=analyst,
output_pydantic=Analysis
)
# Create and start the agents
agents = PraisonAIAgents(
agents=[researcher, analyst],
tasks=[research_task, analysis_task],
process="sequential"
)
# Start execution
result = agents.start()
```
</Step>
<Step title="Start Agents">
Type this in your terminal to run your agents:
```bash
python app.py
```
</Step>
</Steps>
</Tab>
<Tab title="No Code">
<Steps>
<Step title="Install Package">
Install the PraisonAI package:
```bash
pip install praisonai
```
</Step>
<Step title="Set API Key">
Set your OpenAI API key as an environment variable in your terminal:
```bash
export OPENAI_API_KEY=your_api_key_here
```
</Step>
<Step title="Create a file">
Create a new file `agents.yaml` with the basic setup:
```yaml
framework: praisonai
process: sequential
topic: research and analyze quantum computing
roles:
researcher:
backstory: Expert in research and data collection.
goal: Gather and structure research data
role: Research Analyst
tools:
- internet_search
tasks:
research_task:
description: Research quantum computing developments.
expected_output: Structured research findings.
output_structure:
type: pydantic
model:
topic: str
findings: str
sources: list[str]
analyst:
backstory: Expert in data analysis and insights generation.
goal: Analyze research and provide structured insights
role: Data Analyst
tasks:
analysis_task:
description: Analyze research implications.
expected_output: Structured analysis report.
output_structure:
type: pydantic
model:
key_points: list[str]
implications: str
recommendations: str
```
</Step>
<Step title="Start Agents">
Type this in your terminal to run your agents:
```bash
praisonai agents.yaml
```
</Step>
</Steps>
</Tab>
</Tabs>
### Configuration Options
```python
from praisonaiagents import Agent, Task, PraisonAIAgents, Tools
from pydantic import BaseModel
# Define output structure
class AnalysisReport(BaseModel):
title: str
findings: str
summary: str
# Create agents
researcher = Agent(
name="AIResearcher",
role="Technology Research Analyst",
tools=[Tools.internet_search]
# Create an agent with structured output configuration
agent = Agent(
role="Data Analyst",
goal="Provide structured analysis",
backstory="Expert in data analysis",
tools=[Tools.internet_search],
verbose=True, # Enable detailed logging
llm="gpt-4o" # Language model to use
)
analyst = Agent(
name="DataAnalyst",
role="Data Insights Specialist"
)
# Define structured tasks
research_task = Task(
name="gather_research",
description="Research recent AI developments in 2024",
agent=researcher,
expected_output="Research findings"
)
analysis_task = Task(
name="analyze_findings",
description="Analyze research findings and create structured report",
agent=analyst,
output_pydantic=AnalysisReport,
expected_output="Structured analysis report"
)
# Initialize and run agents
agents = PraisonAIAgents(
agents=[researcher, analyst],
tasks=[research_task, analysis_task]
)
result = agents.start()
```
### Different Output Formats
<CodeGroup>
```python Pydantic
# Get Pydantic model instance
analysis_task = Task(
description="Analyze findings",
agent=analyst,
output_pydantic=AnalysisReport
)
# Result will be AnalysisReport instance
result.pydantic.title
result.pydantic.findings
result.pydantic.summary
```
```python JSON
# Get JSON dictionary
analysis_task = Task(
description="Analyze findings",
agent=analyst,
output_json=AnalysisReport
)
# Result will be dictionary
result.json_dict['title']
result.json_dict['findings']
result.json_dict['summary']
```
</CodeGroup>
## Best Practices
<AccordionGroup>
<Accordion title="Model Design">
Design clear, focused Pydantic models:
```python
# Good
class ResearchReport(BaseModel):
title: str
findings: str
summary: str
# Too complex
class Report(BaseModel):
title: str
subtitle: Optional[str]
findings: List[Dict[str, Any]]
```
</Accordion>
<Accordion title="Output Format Selection">
Choose the right output format:
```python
# Use Pydantic when you need:
# - Type validation
# - Model methods
task = Task(output_pydantic=Model)
# Use JSON when you need:
# - Simple dictionary access
# - Serialization
task = Task(output_json=Model)
```
</Accordion>
</AccordionGroup>
## Common Patterns
### Research and Structured Analysis
```python
class ResearchReport(BaseModel):
topic: str
findings: str
sources: list[str]
class Analysis(BaseModel):
key_points: list[str]
implications: str
recommendations: str
research_task = Task(
description="Research quantum computing",
agent=researcher,
output_pydantic=ResearchReport
)
analysis_task = Task(
description="Analyze research implications",
agent=analyst,
output_pydantic=Analysis
)
```
### Data Collection and Summary
```python
class DataPoint(BaseModel):
timestamp: str
value: float
source: str
class Summary(BaseModel):
average: float
trends: str
insights: str
collection_task = Task(
description="Collect data points",
output_pydantic=DataPoint
)
summary_task = Task(
description="Summarize data",
output_pydantic=Summary
# Task with Pydantic output
task = Task(
description="Analyze data",
expected_output="Structured report",
agent=agent,
output_pydantic=AnalysisReport # Use Pydantic model
# or output_json=AnalysisReport # Use JSON output
)
```
@@ -293,30 +339,31 @@ summary_task = Task(
<CardGroup cols={2}>
<Card title="Validation Errors" icon="triangle-exclamation">
Check if your model matches the expected output structure
```python
# Print model schema
print(Model.schema_json())
```
If model validation fails:
- Check data types match model
- Verify required fields
- Enable verbose mode for debugging
</Card>
<Card title="Output Format" icon="code">
Verify you're accessing the right output field:
- `result.pydantic` for Pydantic
- `result.json_dict` for JSON
If output format is incorrect:
- Verify model definition
- Check output_pydantic vs output_json
- Review field specifications
</Card>
</CardGroup>
## Next Steps
<CardGroup cols={2}>
<Card title="Advanced Models" icon="graduation-cap" href="./advanced-models">
Learn about advanced Pydantic model configurations
<Card title="AutoAgents" icon="robot" href="./autoagents">
Learn about automatically created and managed AI agents
</Card>
<Card title="Custom Validation" icon="check-double" href="./validation">
Add custom validation to your models
<Card title="Mini Agents" icon="microchip" href="./mini">
Explore lightweight, focused AI agents
</Card>
</CardGroup>
<Note>
Structured outputs make your AI agents more reliable and their responses more predictable. They're perfect for production systems where data consistency is crucial.
For optimal results, ensure your Pydantic models accurately represent your desired output structure.
</Note>
Loaded 100 of 203 files, more files were not shown because too many files have changed in this diff. Show more