mirror of
https://github.com/MervinPraison/PraisonAI.git
synced 2026-11-07 22:52:58 -10:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
57040333a7 | ||
|
|
8c6800f876 | ||
|
|
0d701ae43c | ||
|
|
7a8c25621c | ||
|
|
218c5443b1 | ||
|
|
f56810341c | ||
|
|
4f601a573f | ||
|
|
43c03f4813 | ||
|
|
03856b74bf | ||
|
|
eadfc0cff0 | ||
|
|
f33c44d4c5 | ||
|
|
3f7885289d | ||
|
|
833c795e9a | ||
|
|
c460c9da60 | ||
|
|
656887c700 | ||
|
|
e0089cac41 | ||
|
|
bf5e069c7b | ||
|
|
94cf264b4c | ||
|
|
ab44fd4b27 | ||
|
|
7bad6cf7e9 | ||
|
|
4ffbe48c58 |
No files matched your search
+1
-1
@@ -1,6 +1,6 @@
|
||||
FROM python:3.11-slim
|
||||
WORKDIR /app
|
||||
COPY . .
|
||||
RUN pip install flask praisonai==2.0.28 gunicorn markdown
|
||||
RUN pip install flask praisonai==2.0.36 gunicorn markdown
|
||||
EXPOSE 8080
|
||||
CMD ["gunicorn", "-b", "0.0.0.0:8080", "api:app"]
|
||||
@@ -0,0 +1,6 @@
|
||||
Make it minimal change as possible
|
||||
|
||||
Firstly try not to make any modification to the existing code as possible
|
||||
|
||||
Only if its highly required, without that if it can't be done, then modify the existing.
|
||||
So by default try to add new code section and not modify the existing.
|
||||
Whitespace-only changes.
@@ -0,0 +1,50 @@
|
||||
from praisonaiagents import Agent, Task, PraisonAIAgents
|
||||
import json
|
||||
from e2b_code_interpreter import Sandbox
|
||||
|
||||
def code_interpreter(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})
|
||||
|
||||
code_agent = Agent(
|
||||
name="code_agent",
|
||||
llm="gpt-4o-mini",
|
||||
backstory="Expert in writing Python scripts",
|
||||
self_reflect=False
|
||||
)
|
||||
execution_agent = Agent(
|
||||
name="execution_agent",
|
||||
llm="gpt-4o-mini",
|
||||
backstory="Expert in executing Python scripts",
|
||||
self_reflect=False,
|
||||
tools=[code_interpreter]
|
||||
)
|
||||
|
||||
code_agent_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_agent_task = Task(
|
||||
description="Execute the Python script",
|
||||
expected_output="The output of the Python script",
|
||||
agent=execution_agent
|
||||
)
|
||||
|
||||
agents = PraisonAIAgents(agents=[code_agent, execution_agent], tasks=[code_agent_task, execution_agent_task])
|
||||
agents.start()
|
||||
@@ -1,74 +0,0 @@
|
||||
from praisonaiagents import Agent, Task, PraisonAIAgents
|
||||
from typing import List, Dict
|
||||
from duckduckgo_search import DDGS
|
||||
|
||||
# 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 []
|
||||
|
||||
# 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",
|
||||
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()
|
||||
@@ -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.
@@ -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()
|
||||
@@ -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()
|
||||
@@ -0,0 +1,6 @@
|
||||
from praisonaiagents import Agent, Agents, Tools
|
||||
|
||||
research_agent = Agent(instructions="You are a research agent to search internet about AI 2024", tools=[Tools.internet_search])
|
||||
summarise_agent = Agent(instructions="You are a summarize agent to summarise in points")
|
||||
agents = Agents(agents=[research_agent, summarise_agent])
|
||||
agents.start()
|
||||
@@ -5,6 +5,7 @@ Praison AI Agents - A package for hierarchical AI agent task execution
|
||||
from .agent.agent import Agent
|
||||
from .agents.agents import PraisonAIAgents
|
||||
from .task.task import Task
|
||||
from .tools.tools import Tools
|
||||
from .main import (
|
||||
TaskOutput,
|
||||
ReflectionOutput,
|
||||
@@ -21,9 +22,14 @@ from .main import (
|
||||
async_display_callbacks,
|
||||
)
|
||||
|
||||
# Add Agents as an alias for PraisonAIAgents
|
||||
Agents = PraisonAIAgents
|
||||
|
||||
__all__ = [
|
||||
'Agent',
|
||||
'PraisonAIAgents',
|
||||
'Agents',
|
||||
'Tools',
|
||||
'Task',
|
||||
'TaskOutput',
|
||||
'ReflectionOutput',
|
||||
|
||||
@@ -3,7 +3,7 @@ import time
|
||||
import json
|
||||
import logging
|
||||
import asyncio
|
||||
from typing import List, Optional, Any, Dict, Union, Literal
|
||||
from typing import List, Optional, Any, Dict, Union, Literal, TYPE_CHECKING
|
||||
from rich.console import Console
|
||||
from rich.live import Live
|
||||
from openai import AsyncOpenAI
|
||||
@@ -18,6 +18,10 @@ from ..main import (
|
||||
client,
|
||||
error_logs
|
||||
)
|
||||
import inspect
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from ..task.task import Task
|
||||
|
||||
class Agent:
|
||||
def _generate_tool_definition(self, function_name):
|
||||
@@ -64,9 +68,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": {},
|
||||
@@ -92,7 +111,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:
|
||||
@@ -132,11 +151,12 @@ class Agent:
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
name: str,
|
||||
role: str,
|
||||
goal: str,
|
||||
backstory: str,
|
||||
llm: Optional[Union[str, Any]] = "gpt-4o",
|
||||
name: Optional[str] = None,
|
||||
role: Optional[str] = None,
|
||||
goal: Optional[str] = None,
|
||||
backstory: Optional[str] = None,
|
||||
instructions: Optional[str] = None,
|
||||
llm: Optional[Union[str, Any]] = None,
|
||||
tools: Optional[List[Any]] = None,
|
||||
function_calling_llm: Optional[Any] = None,
|
||||
max_iter: int = 20,
|
||||
@@ -158,16 +178,35 @@ class Agent:
|
||||
knowledge_sources: Optional[List[Any]] = None,
|
||||
use_system_prompt: Optional[bool] = True,
|
||||
markdown: bool = True,
|
||||
self_reflect: bool = True,
|
||||
self_reflect: Optional[bool] = None,
|
||||
max_reflect: int = 3,
|
||||
min_reflect: int = 1,
|
||||
reflect_llm: Optional[str] = None
|
||||
):
|
||||
self.name = name
|
||||
self.role = role
|
||||
self.goal = goal
|
||||
self.backstory = backstory
|
||||
self.llm = llm
|
||||
# Handle backward compatibility for required fields
|
||||
if all(x is None for x in [name, role, goal, backstory, instructions]):
|
||||
raise ValueError("At least one of name, role, goal, backstory, or instructions must be provided")
|
||||
|
||||
# If instructions are provided, use them to set role, goal, and backstory
|
||||
if instructions:
|
||||
self.name = name or "Agent"
|
||||
self.role = role or "Assistant"
|
||||
self.goal = goal or instructions
|
||||
self.backstory = backstory or instructions
|
||||
# Set self_reflect to False by default for instruction-based agents
|
||||
self.self_reflect = False if self_reflect is None else self_reflect
|
||||
else:
|
||||
# Use provided values or defaults
|
||||
self.name = name or "Agent"
|
||||
self.role = role or "Assistant"
|
||||
self.goal = goal or "Help the user with their tasks"
|
||||
self.backstory = backstory or "I am an AI assistant"
|
||||
# Default to True for traditional agents if not specified
|
||||
self.self_reflect = True if self_reflect is None else self_reflect
|
||||
|
||||
self.instructions = instructions
|
||||
# Check for model name in environment variable if not provided
|
||||
self.llm = llm or os.getenv('OPENAI_MODEL_NAME', 'gpt-4o')
|
||||
self.tools = tools if tools else [] # Store original tools
|
||||
self.function_calling_llm = function_calling_llm
|
||||
self.max_iter = max_iter
|
||||
@@ -190,10 +229,10 @@ class Agent:
|
||||
self.use_system_prompt = use_system_prompt
|
||||
self.chat_history = []
|
||||
self.markdown = markdown
|
||||
self.self_reflect = self_reflect
|
||||
self.max_reflect = max_reflect
|
||||
self.min_reflect = min_reflect
|
||||
self.reflect_llm = reflect_llm
|
||||
# Use the same model selection logic for reflect_llm
|
||||
self.reflect_llm = reflect_llm or os.getenv('OPENAI_MODEL_NAME', 'gpt-4o')
|
||||
self.console = Console() # Create a single console instance for the agent
|
||||
|
||||
# Initialize system prompt
|
||||
@@ -202,6 +241,21 @@ Your Role: {self.role}\n
|
||||
Your Goal: {self.goal}
|
||||
"""
|
||||
|
||||
def generate_task(self) -> 'Task':
|
||||
"""Generate a Task object from the agent's instructions"""
|
||||
from ..task.task import Task
|
||||
|
||||
description = self.instructions if self.instructions else f"Execute task as {self.role} with goal: {self.goal}"
|
||||
expected_output = "Complete the assigned task successfully"
|
||||
|
||||
return Task(
|
||||
name=self.name,
|
||||
description=description,
|
||||
expected_output=expected_output,
|
||||
agent=self,
|
||||
tools=self.tools
|
||||
)
|
||||
|
||||
def execute_tool(self, function_name, arguments):
|
||||
"""
|
||||
Execute a tool dynamically based on the function name and arguments.
|
||||
@@ -211,25 +265,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}")
|
||||
@@ -356,7 +416,7 @@ Your Goal: {self.goal}
|
||||
display_error(f"Error in chat completion: {e}")
|
||||
return None
|
||||
|
||||
def chat(self, prompt, temperature=0.2, tools=None, output_json=None):
|
||||
def chat(self, prompt, temperature=0.2, tools=None, output_json=None, output_pydantic=None):
|
||||
if self.use_system_prompt:
|
||||
system_prompt = f"""{self.backstory}\n
|
||||
Your Role: {self.role}\n
|
||||
@@ -364,6 +424,8 @@ Your Goal: {self.goal}
|
||||
"""
|
||||
if output_json:
|
||||
system_prompt += f"\nReturn ONLY a JSON object that matches this Pydantic model: {output_json.schema_json()}"
|
||||
elif output_pydantic:
|
||||
system_prompt += f"\nReturn ONLY a JSON object that matches this Pydantic model: {output_pydantic.schema_json()}"
|
||||
else:
|
||||
system_prompt = None
|
||||
|
||||
@@ -372,9 +434,9 @@ Your Goal: {self.goal}
|
||||
messages.append({"role": "system", "content": system_prompt})
|
||||
messages.extend(self.chat_history)
|
||||
|
||||
# Modify prompt if output_json is specified
|
||||
# Modify prompt if output_json or output_pydantic is specified
|
||||
original_prompt = prompt
|
||||
if output_json:
|
||||
if output_json or output_pydantic:
|
||||
if isinstance(prompt, str):
|
||||
prompt += "\nReturn ONLY a valid JSON object. No other text or explanation."
|
||||
elif isinstance(prompt, list):
|
||||
@@ -449,23 +511,15 @@ Your Goal: {self.goal}
|
||||
return None
|
||||
response_text = response.choices[0].message.content.strip()
|
||||
|
||||
# Handle output_json if specified
|
||||
if output_json:
|
||||
try:
|
||||
# Clean the response text to get only JSON
|
||||
cleaned_json = self.clean_json_output(response_text)
|
||||
# Parse into Pydantic model
|
||||
parsed_model = output_json.model_validate_json(cleaned_json)
|
||||
# Add to chat history and return
|
||||
self.chat_history.append({"role": "user", "content": original_prompt})
|
||||
self.chat_history.append({"role": "assistant", "content": response_text})
|
||||
if self.verbose:
|
||||
display_interaction(original_prompt, response_text, markdown=self.markdown,
|
||||
generation_time=time.time() - start_time, console=self.console)
|
||||
return parsed_model
|
||||
except Exception as e:
|
||||
display_error(f"Failed to parse response as {output_json.__name__}: {e}")
|
||||
return None
|
||||
# Handle output_json or output_pydantic if specified
|
||||
if output_json or output_pydantic:
|
||||
# Add to chat history and return raw response
|
||||
self.chat_history.append({"role": "user", "content": original_prompt})
|
||||
self.chat_history.append({"role": "assistant", "content": response_text})
|
||||
if self.verbose:
|
||||
display_interaction(original_prompt, response_text, markdown=self.markdown,
|
||||
generation_time=time.time() - start_time, console=self.console)
|
||||
return response_text
|
||||
|
||||
if not self.self_reflect:
|
||||
self.chat_history.append({"role": "user", "content": original_prompt})
|
||||
@@ -547,19 +601,21 @@ Output MUST be JSON with 'reflection' and 'satisfactory'.
|
||||
cleaned = cleaned[:-3].strip()
|
||||
return cleaned
|
||||
|
||||
async def achat(self, prompt, temperature=0.2, tools=None, output_json=None):
|
||||
async def achat(self, prompt, temperature=0.2, tools=None, output_json=None, output_pydantic=None):
|
||||
"""Async version of chat method"""
|
||||
try:
|
||||
# Build system prompt
|
||||
system_prompt = self.system_prompt
|
||||
if output_json:
|
||||
system_prompt += f"\nReturn ONLY a JSON object that matches this Pydantic model: {output_json.schema_json()}"
|
||||
elif output_pydantic:
|
||||
system_prompt += f"\nReturn ONLY a JSON object that matches this Pydantic model: {output_pydantic.schema_json()}"
|
||||
|
||||
# Build messages
|
||||
if isinstance(prompt, str):
|
||||
messages = [
|
||||
{"role": "system", "content": system_prompt},
|
||||
{"role": "user", "content": prompt + ("\nReturn ONLY a valid JSON object. No other text or explanation." if output_json else "")}
|
||||
{"role": "user", "content": prompt + ("\nReturn ONLY a valid JSON object. No other text or explanation." if (output_json or output_pydantic) else "")}
|
||||
]
|
||||
else:
|
||||
# For multimodal prompts
|
||||
@@ -567,7 +623,7 @@ Output MUST be JSON with 'reflection' and 'satisfactory'.
|
||||
{"role": "system", "content": system_prompt},
|
||||
{"role": "user", "content": prompt}
|
||||
]
|
||||
if output_json:
|
||||
if output_json or output_pydantic:
|
||||
# Add JSON instruction to text content
|
||||
for item in messages[-1]["content"]:
|
||||
if item["type"] == "text":
|
||||
@@ -601,22 +657,15 @@ Output MUST be JSON with 'reflection' and 'satisfactory'.
|
||||
tools=formatted_tools
|
||||
)
|
||||
return await self._achat_completion(response, tools)
|
||||
elif output_json:
|
||||
elif output_json or output_pydantic:
|
||||
response = await async_client.chat.completions.create(
|
||||
model=self.llm,
|
||||
messages=messages,
|
||||
temperature=temperature,
|
||||
response_format={"type": "json_object"}
|
||||
)
|
||||
result = response.choices[0].message.content
|
||||
# Clean and parse the JSON response
|
||||
cleaned_json = self.clean_json_output(result)
|
||||
try:
|
||||
parsed = json.loads(cleaned_json)
|
||||
return output_json(**parsed)
|
||||
except Exception as e:
|
||||
display_error(f"Error parsing JSON response: {e}")
|
||||
return None
|
||||
# Return the raw response
|
||||
return response.choices[0].message.content
|
||||
else:
|
||||
response = await async_client.chat.completions.create(
|
||||
model=self.llm,
|
||||
|
||||
@@ -41,7 +41,10 @@ def process_video(video_path: str, seconds_per_frame=2):
|
||||
return base64_frames
|
||||
|
||||
class PraisonAIAgents:
|
||||
def __init__(self, agents, tasks, 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):
|
||||
if not agents:
|
||||
raise ValueError("At least one agent must be provided")
|
||||
|
||||
self.agents = agents
|
||||
self.tasks = {}
|
||||
if max_retries < 3:
|
||||
@@ -51,12 +54,41 @@ class PraisonAIAgents:
|
||||
self.verbose = verbose
|
||||
self.max_retries = max_retries
|
||||
self.process = process
|
||||
if not manager_llm:
|
||||
logging.debug("No manager_llm provided. Using OPENAI_MODEL_NAME environment variable or defaulting to 'gpt-4o'")
|
||||
self.manager_llm = manager_llm if manager_llm else os.getenv('OPENAI_MODEL_NAME', 'gpt-4o')
|
||||
|
||||
# Check for manager_llm in environment variable if not provided
|
||||
self.manager_llm = manager_llm or os.getenv('OPENAI_MODEL_NAME', 'gpt-4o')
|
||||
if self.verbose:
|
||||
logging.info(f"Using model {self.manager_llm} for manager")
|
||||
|
||||
# If no tasks provided, generate them from agents
|
||||
if tasks is None:
|
||||
tasks = []
|
||||
for agent in self.agents:
|
||||
task = agent.generate_task()
|
||||
tasks.append(task)
|
||||
logging.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")
|
||||
|
||||
# Add tasks and set their status
|
||||
for task in tasks:
|
||||
self.add_task(task)
|
||||
task.status = "not started"
|
||||
|
||||
# If tasks were auto-generated from agents or process is sequential, set up sequential flow
|
||||
if len(tasks) > 1 and (process == "sequential" or all(task.next_tasks == [] for task in tasks)):
|
||||
for i in range(len(tasks) - 1):
|
||||
# Set up next task relationship
|
||||
tasks[i].next_tasks = [tasks[i + 1].name]
|
||||
# Set up context for the next task to include the current task
|
||||
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")
|
||||
|
||||
self._state = {} # Add state storage at PraisonAIAgents level
|
||||
|
||||
def add_task(self, task):
|
||||
@@ -119,9 +151,9 @@ Expected Output: {task.expected_output}.
|
||||
else:
|
||||
context_results += f"Previous task {context_task.name if context_task.name else context_task.description} had no result.\n"
|
||||
task_prompt += f"""
|
||||
Here are the results of previous tasks that might be useful:\n
|
||||
{context_results}
|
||||
"""
|
||||
Here are the results of previous tasks that might be useful:\n
|
||||
{context_results}
|
||||
"""
|
||||
task_prompt += "Please provide only the final result of your work. Do not add any conversation or extra explanation."
|
||||
|
||||
if self.verbose >= 2:
|
||||
@@ -163,10 +195,17 @@ Expected Output: {task.expected_output}.
|
||||
|
||||
agent_output = await executor_agent.achat(
|
||||
_get_multimodal_message(task_prompt, task.images),
|
||||
tools=task.tools
|
||||
tools=task.tools,
|
||||
output_json=task.output_json,
|
||||
output_pydantic=task.output_pydantic
|
||||
)
|
||||
else:
|
||||
agent_output = await executor_agent.achat(task_prompt, tools=task.tools)
|
||||
agent_output = await executor_agent.achat(
|
||||
task_prompt,
|
||||
tools=task.tools,
|
||||
output_json=task.output_json,
|
||||
output_pydantic=task.output_pydantic
|
||||
)
|
||||
|
||||
if agent_output:
|
||||
task_output = TaskOutput(
|
||||
@@ -320,7 +359,7 @@ Expected Output: {task.expected_output}.
|
||||
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:
|
||||
@@ -329,9 +368,9 @@ Expected Output: {task.expected_output}.
|
||||
else:
|
||||
context_results += f"Previous task {context_task.name if context_task.name else context_task.description} had no result.\n"
|
||||
task_prompt += f"""
|
||||
Here are the results of previous tasks that might be useful:\n
|
||||
{context_results}
|
||||
"""
|
||||
Here are the results of previous tasks that might be useful:\n
|
||||
{context_results}
|
||||
"""
|
||||
task_prompt += "Please provide only the final result of your work. Do not add any conversation or extra explanation."
|
||||
|
||||
if self.verbose >= 2:
|
||||
@@ -373,10 +412,17 @@ Expected Output: {task.expected_output}.
|
||||
|
||||
agent_output = executor_agent.chat(
|
||||
_get_multimodal_message(task_prompt, task.images),
|
||||
tools=task.tools
|
||||
tools=task.tools,
|
||||
output_json=task.output_json,
|
||||
output_pydantic=task.output_pydantic
|
||||
)
|
||||
else:
|
||||
agent_output = executor_agent.chat(task_prompt, tools=task.tools)
|
||||
agent_output = executor_agent.chat(
|
||||
task_prompt,
|
||||
tools=task.tools,
|
||||
output_json=task.output_json,
|
||||
output_pydantic=task.output_pydantic
|
||||
)
|
||||
|
||||
if agent_output:
|
||||
task_output = TaskOutput(
|
||||
|
||||
@@ -0,0 +1,149 @@
|
||||
# PraisonAI Tools Guide
|
||||
|
||||
Welcome to the PraisonAI Tools directory! This guide will help you understand how our tools work and how to create new ones, whether you're a beginner or an experienced programmer.
|
||||
|
||||
## What is a Tool?
|
||||
|
||||
A tool is a piece of code that helps our AI agents perform specific tasks. Think of tools as special abilities that we give to our agents. For example:
|
||||
- An internet search tool lets agents search the web
|
||||
- A stock market tool lets agents check stock prices
|
||||
- A weather tool lets agents check the weather
|
||||
|
||||
## Creating New Tools: The Two Approaches
|
||||
|
||||
### 1. Function-Based Approach (Simple Tools)
|
||||
|
||||
Best for simple tools that do one specific thing. Like a calculator that just adds numbers.
|
||||
|
||||
**When to use:**
|
||||
- Tool does one simple task
|
||||
- Doesn't need to remember information between uses
|
||||
- Doesn't need to share information with other tools
|
||||
- Quick, one-time operations
|
||||
|
||||
**Example:**
|
||||
```python
|
||||
def internet_search(query: str):
|
||||
# Search the internet and return results
|
||||
return search_results
|
||||
```
|
||||
|
||||
**Usage:**
|
||||
```python
|
||||
from praisonaiagents.tools import internet_search
|
||||
|
||||
results = internet_search("AI news")
|
||||
```
|
||||
|
||||
### 2. Class-Based Approach (Complex Tools)
|
||||
|
||||
Best for tools that do multiple related things or need to remember information. Like a smart calculator that remembers your previous calculations and can do many different math operations.
|
||||
|
||||
**When to use:**
|
||||
- Tool has multiple related functions
|
||||
- Needs to remember or share information
|
||||
- Needs to manage resources efficiently
|
||||
- Has complex setup requirements
|
||||
|
||||
**Example:**
|
||||
```python
|
||||
class StockTools:
|
||||
def get_stock_price(self, symbol):
|
||||
# Get current stock price
|
||||
return price
|
||||
|
||||
def get_stock_info(self, symbol):
|
||||
# Get detailed stock information
|
||||
return info
|
||||
```
|
||||
|
||||
**Usage:**
|
||||
```python
|
||||
from praisonaiagents.tools import get_stock_price, get_stock_info
|
||||
|
||||
price = get_stock_price("AAPL")
|
||||
info = get_stock_info("AAPL")
|
||||
```
|
||||
|
||||
## How to Choose Your Approach
|
||||
|
||||
Ask yourself these questions:
|
||||
|
||||
1. **Is your tool doing one simple thing?**
|
||||
- Yes → Use Function-Based Approach
|
||||
- No → Consider Class-Based Approach
|
||||
|
||||
2. **Does your tool need to remember information?**
|
||||
- Yes → Use Class-Based Approach
|
||||
- No → Use Function-Based Approach
|
||||
|
||||
3. **Are your tool's operations related to each other?**
|
||||
- Yes → Use Class-Based Approach
|
||||
- No → Use Function-Based Approach
|
||||
|
||||
4. **Does your tool need to manage resources efficiently?**
|
||||
- Yes → Use Class-Based Approach
|
||||
- No → Use Function-Based Approach
|
||||
|
||||
## Real-World Examples
|
||||
|
||||
### Internet Search Tool (Function-Based)
|
||||
- Does one thing: searches the internet
|
||||
- Doesn't need to remember previous searches
|
||||
- Each search is independent
|
||||
- Simple input/output operation
|
||||
|
||||
### Stock Market Tool (Class-Based)
|
||||
- Does multiple things: check prices, get company info, get historical data
|
||||
- Remembers stock information to avoid repeated downloads
|
||||
- Operations are related (all about stocks)
|
||||
- Manages connections efficiently
|
||||
|
||||
## Getting Started
|
||||
|
||||
1. **Choose Your Approach** based on the guidelines above
|
||||
|
||||
2. **Create Your Tool File**:
|
||||
- Name it descriptively (e.g., `weather_tools.py`)
|
||||
- Place it in the `praisonaiagents/tools` directory
|
||||
|
||||
3. **Write Your Tool**:
|
||||
- Add clear documentation
|
||||
- Include type hints for better understanding
|
||||
- Handle errors gracefully
|
||||
|
||||
4. **Test Your Tool**:
|
||||
- Make sure it works as expected
|
||||
- Test error cases
|
||||
- Check performance
|
||||
|
||||
## Best Practices
|
||||
|
||||
1. **Documentation**:
|
||||
- Explain what your tool does
|
||||
- Provide examples
|
||||
- List any requirements
|
||||
|
||||
2. **Error Handling**:
|
||||
- Always handle possible errors
|
||||
- Return helpful error messages
|
||||
- Don't let your tool crash
|
||||
|
||||
3. **Performance**:
|
||||
- Keep it efficient
|
||||
- Don't waste resources
|
||||
- Cache when helpful
|
||||
|
||||
4. **User-Friendly**:
|
||||
- Make it easy to use
|
||||
- Use clear function/method names
|
||||
- Keep it simple
|
||||
|
||||
## Need Help?
|
||||
|
||||
- Check existing tools for examples
|
||||
- Ask in our community
|
||||
- Read the documentation
|
||||
- Don't hesitate to ask questions!
|
||||
|
||||
Remember: The goal is to make tools that are easy to use and maintain. Choose the approach that makes the most sense for your specific tool's needs.
|
||||
@@ -0,0 +1,178 @@
|
||||
"""Tools package for PraisonAI Agents"""
|
||||
from importlib import import_module
|
||||
from typing import Any
|
||||
|
||||
# Map of function names to their module and class (if any)
|
||||
TOOL_MAPPINGS = {
|
||||
# Direct functions
|
||||
'internet_search': ('.duckduckgo_tools', None),
|
||||
'duckduckgo': ('.duckduckgo_tools', None),
|
||||
|
||||
# arXiv Tools
|
||||
'search_arxiv': ('.arxiv_tools', None),
|
||||
'get_arxiv_paper': ('.arxiv_tools', None),
|
||||
'get_papers_by_author': ('.arxiv_tools', None),
|
||||
'get_papers_by_category': ('.arxiv_tools', None),
|
||||
'arxiv_tools': ('.arxiv_tools', None),
|
||||
|
||||
# Wikipedia Tools
|
||||
'wiki_search': ('.wikipedia_tools', None),
|
||||
'wiki_summary': ('.wikipedia_tools', None),
|
||||
'wiki_page': ('.wikipedia_tools', None),
|
||||
'wiki_random': ('.wikipedia_tools', None),
|
||||
'wiki_language': ('.wikipedia_tools', None),
|
||||
'wikipedia_tools': ('.wikipedia_tools', None),
|
||||
|
||||
# Newspaper Tools
|
||||
'get_article': ('.newspaper_tools', None),
|
||||
'get_news_sources': ('.newspaper_tools', None),
|
||||
'get_articles_from_source': ('.newspaper_tools', None),
|
||||
'get_trending_topics': ('.newspaper_tools', None),
|
||||
'newspaper_tools': ('.newspaper_tools', None),
|
||||
|
||||
# Spider Tools
|
||||
'scrape_page': ('.spider_tools', None),
|
||||
'extract_links': ('.spider_tools', None),
|
||||
'crawl': ('.spider_tools', None),
|
||||
'extract_text': ('.spider_tools', None),
|
||||
'spider_tools': ('.spider_tools', None),
|
||||
|
||||
# DuckDB Tools
|
||||
'query': ('.duckdb_tools', None),
|
||||
'create_table': ('.duckdb_tools', None),
|
||||
'load_data': ('.duckdb_tools', None),
|
||||
'export_data': ('.duckdb_tools', None),
|
||||
'get_table_info': ('.duckdb_tools', None),
|
||||
'analyze_data': ('.duckdb_tools', None),
|
||||
'duckdb_tools': ('.duckdb_tools', None),
|
||||
|
||||
# Shell Tools
|
||||
'execute_command': ('.shell_tools', None),
|
||||
'list_processes': ('.shell_tools', None),
|
||||
'kill_process': ('.shell_tools', None),
|
||||
'get_system_info': ('.shell_tools', None),
|
||||
'shell_tools': ('.shell_tools', None),
|
||||
|
||||
# Calculator Tools
|
||||
'evaluate': ('.calculator_tools', None),
|
||||
'solve_equation': ('.calculator_tools', None),
|
||||
'convert_units': ('.calculator_tools', None),
|
||||
'calculate_statistics': ('.calculator_tools', None),
|
||||
'calculate_financial': ('.calculator_tools', None),
|
||||
'calculator_tools': ('.calculator_tools', None),
|
||||
|
||||
# Class methods from YFinance
|
||||
'get_stock_price': ('.yfinance_tools', 'YFinanceTools'),
|
||||
'get_stock_info': ('.yfinance_tools', 'YFinanceTools'),
|
||||
'get_historical_data': ('.yfinance_tools', 'YFinanceTools'),
|
||||
'yfinance': ('.yfinance_tools', 'YFinanceTools'),
|
||||
|
||||
# File Tools
|
||||
'read_file': ('.file_tools', 'FileTools'),
|
||||
'write_file': ('.file_tools', 'FileTools'),
|
||||
'list_files': ('.file_tools', 'FileTools'),
|
||||
'get_file_info': ('.file_tools', 'FileTools'),
|
||||
'copy_file': ('.file_tools', 'FileTools'),
|
||||
'move_file': ('.file_tools', 'FileTools'),
|
||||
'delete_file': ('.file_tools', 'FileTools'),
|
||||
'file_tools': ('.file_tools', 'FileTools'),
|
||||
|
||||
# CSV Tools
|
||||
'read_csv': ('.csv_tools', 'CSVTools'),
|
||||
'write_csv': ('.csv_tools', 'CSVTools'),
|
||||
'merge_csv': ('.csv_tools', 'CSVTools'),
|
||||
'analyze_csv': ('.csv_tools', 'CSVTools'),
|
||||
'split_csv': ('.csv_tools', 'CSVTools'),
|
||||
'csv_tools': ('.csv_tools', 'CSVTools'),
|
||||
|
||||
# JSON Tools
|
||||
'read_json': ('.json_tools', 'JSONTools'),
|
||||
'write_json': ('.json_tools', 'JSONTools'),
|
||||
'merge_json': ('.json_tools', 'JSONTools'),
|
||||
'validate_json': ('.json_tools', 'JSONTools'),
|
||||
'analyze_json': ('.json_tools', 'JSONTools'),
|
||||
'transform_json': ('.json_tools', 'JSONTools'),
|
||||
'json_tools': ('.json_tools', 'JSONTools'),
|
||||
|
||||
# Excel Tools
|
||||
'read_excel': ('.excel_tools', 'ExcelTools'),
|
||||
'write_excel': ('.excel_tools', 'ExcelTools'),
|
||||
'merge_excel': ('.excel_tools', 'ExcelTools'),
|
||||
'create_chart': ('.excel_tools', 'ExcelTools'),
|
||||
'add_chart_to_sheet': ('.excel_tools', 'ExcelTools'),
|
||||
'excel_tools': ('.excel_tools', 'ExcelTools'),
|
||||
|
||||
# XML Tools
|
||||
'read_xml': ('.xml_tools', 'XMLTools'),
|
||||
'write_xml': ('.xml_tools', 'XMLTools'),
|
||||
'transform_xml': ('.xml_tools', 'XMLTools'),
|
||||
'validate_xml': ('.xml_tools', 'XMLTools'),
|
||||
'xml_to_dict': ('.xml_tools', 'XMLTools'),
|
||||
'dict_to_xml': ('.xml_tools', 'XMLTools'),
|
||||
'xpath_query': ('.xml_tools', 'XMLTools'),
|
||||
'xml_tools': ('.xml_tools', 'XMLTools'),
|
||||
|
||||
# YAML Tools
|
||||
'read_yaml': ('.yaml_tools', 'YAMLTools'),
|
||||
'write_yaml': ('.yaml_tools', 'YAMLTools'),
|
||||
'merge_yaml': ('.yaml_tools', 'YAMLTools'),
|
||||
'validate_yaml': ('.yaml_tools', 'YAMLTools'),
|
||||
'analyze_yaml': ('.yaml_tools', 'YAMLTools'),
|
||||
'transform_yaml': ('.yaml_tools', 'YAMLTools'),
|
||||
'yaml_tools': ('.yaml_tools', 'YAMLTools'),
|
||||
|
||||
# Python Tools
|
||||
'execute_code': ('.python_tools', 'PythonTools'),
|
||||
'analyze_code': ('.python_tools', 'PythonTools'),
|
||||
'format_code': ('.python_tools', 'PythonTools'),
|
||||
'lint_code': ('.python_tools', 'PythonTools'),
|
||||
'disassemble_code': ('.python_tools', 'PythonTools'),
|
||||
'python_tools': ('.python_tools', 'PythonTools'),
|
||||
|
||||
# Pandas Tools
|
||||
'filter_data': ('.pandas_tools', 'PandasTools'),
|
||||
'get_summary': ('.pandas_tools', 'PandasTools'),
|
||||
'group_by': ('.pandas_tools', 'PandasTools'),
|
||||
'pivot_table': ('.pandas_tools', 'PandasTools'),
|
||||
'pandas_tools': ('.pandas_tools', 'PandasTools'),
|
||||
}
|
||||
|
||||
_instances = {} # Cache for class instances
|
||||
|
||||
def __getattr__(name: str) -> Any:
|
||||
"""Smart lazy loading of tools with class method support."""
|
||||
if name not in TOOL_MAPPINGS:
|
||||
raise AttributeError(f"module '{__package__}' has no attribute '{name}'")
|
||||
|
||||
module_path, class_name = TOOL_MAPPINGS[name]
|
||||
|
||||
if class_name is None:
|
||||
# Direct function import
|
||||
module = import_module(module_path, __package__)
|
||||
if name in [
|
||||
'duckduckgo', 'internet_search',
|
||||
'search_arxiv', 'get_arxiv_paper', 'get_papers_by_author', 'get_papers_by_category',
|
||||
'wiki_search', 'wiki_summary', 'wiki_page', 'wiki_random', 'wiki_language',
|
||||
'get_article', 'get_news_sources', 'get_articles_from_source', 'get_trending_topics',
|
||||
'scrape_page', 'extract_links', 'crawl', 'extract_text',
|
||||
'query', 'create_table', 'load_data', 'export_data', 'get_table_info', 'analyze_data',
|
||||
'execute_command', 'list_processes', 'kill_process', 'get_system_info',
|
||||
'evaluate', 'solve_equation', 'convert_units', 'calculate_statistics', 'calculate_financial'
|
||||
]:
|
||||
return getattr(module, name)
|
||||
if name in ['file_tools', 'pandas_tools', 'wikipedia_tools',
|
||||
'newspaper_tools', 'arxiv_tools', 'spider_tools', 'duckdb_tools', 'csv_tools', 'json_tools', 'excel_tools', 'xml_tools', 'yaml_tools', 'calculator_tools', 'python_tools', 'shell_tools']:
|
||||
return module # Returns the callable module
|
||||
return getattr(module, name)
|
||||
else:
|
||||
# Class method import
|
||||
if class_name not in _instances:
|
||||
module = import_module(module_path, __package__)
|
||||
class_ = getattr(module, class_name)
|
||||
_instances[class_name] = class_()
|
||||
|
||||
# Get the method and bind it to the instance
|
||||
method = getattr(_instances[class_name], name)
|
||||
return method
|
||||
|
||||
__all__ = list(TOOL_MAPPINGS.keys())
|
||||
@@ -0,0 +1,292 @@
|
||||
"""Tools for searching and retrieving papers from arXiv.
|
||||
|
||||
Usage:
|
||||
from praisonaiagents.tools import arxiv_tools
|
||||
papers = arxiv_tools.search("quantum computing")
|
||||
paper = arxiv_tools.get_paper("2401.00123")
|
||||
|
||||
or
|
||||
from praisonaiagents.tools import search_arxiv, get_arxiv_paper
|
||||
papers = search_arxiv("quantum computing")
|
||||
"""
|
||||
|
||||
import logging
|
||||
from typing import List, Dict, Union, Optional, Any
|
||||
from importlib import util
|
||||
import json
|
||||
|
||||
# Map sort criteria to arxiv.SortCriterion
|
||||
SORT_CRITERIA = {
|
||||
"relevance": "Relevance",
|
||||
"lastupdateddate": "LastUpdatedDate",
|
||||
"submitteddate": "SubmittedDate"
|
||||
}
|
||||
|
||||
# Map sort order to arxiv.SortOrder
|
||||
SORT_ORDER = {
|
||||
"ascending": "Ascending",
|
||||
"descending": "Descending"
|
||||
}
|
||||
|
||||
class ArxivTools:
|
||||
"""Tools for searching and retrieving papers from arXiv."""
|
||||
|
||||
def __init__(self):
|
||||
"""Initialize ArxivTools and check for arxiv package."""
|
||||
self._check_arxiv()
|
||||
|
||||
def _check_arxiv(self):
|
||||
"""Check if arxiv package is installed."""
|
||||
if util.find_spec("arxiv") is None:
|
||||
raise ImportError("arxiv package is not available. Please install it using: pip install arxiv")
|
||||
global arxiv
|
||||
import arxiv
|
||||
|
||||
def search(
|
||||
self,
|
||||
query: str,
|
||||
max_results: int = 10,
|
||||
sort_by: str = "relevance",
|
||||
sort_order: str = "descending",
|
||||
include_fields: Optional[List[str]] = None
|
||||
) -> Union[List[Dict[str, Any]], Dict[str, str]]:
|
||||
"""
|
||||
Search arXiv for papers matching the query.
|
||||
|
||||
Args:
|
||||
query: Search query (e.g., "quantum computing", "author:Einstein")
|
||||
max_results: Maximum number of results to return
|
||||
sort_by: Sort results by ("relevance", "lastUpdatedDate", "submittedDate")
|
||||
sort_order: Sort order ("ascending" or "descending")
|
||||
include_fields: List of fields to include in results. If None, includes all.
|
||||
Available fields: ["title", "authors", "summary", "comment", "journal_ref",
|
||||
"doi", "primary_category", "categories", "links"]
|
||||
|
||||
Returns:
|
||||
List[Dict] or Dict: List of papers or error dict
|
||||
"""
|
||||
try:
|
||||
import arxiv
|
||||
|
||||
# Configure search client
|
||||
client = arxiv.Client()
|
||||
|
||||
# Map sort criteria
|
||||
sort_by_enum = getattr(arxiv.SortCriterion, SORT_CRITERIA[sort_by.lower()])
|
||||
sort_order_enum = getattr(arxiv.SortOrder, SORT_ORDER[sort_order.lower()])
|
||||
|
||||
# Build search query
|
||||
search = arxiv.Search(
|
||||
query=query,
|
||||
max_results=max_results,
|
||||
sort_by=sort_by_enum,
|
||||
sort_order=sort_order_enum
|
||||
)
|
||||
|
||||
# Execute search
|
||||
results = []
|
||||
for result in client.results(search):
|
||||
# Convert to dict with selected fields
|
||||
paper = self._result_to_dict(result, include_fields)
|
||||
results.append(paper)
|
||||
|
||||
return results
|
||||
except Exception as e:
|
||||
error_msg = f"Error searching arXiv: {str(e)}"
|
||||
logging.error(error_msg)
|
||||
return {"error": error_msg}
|
||||
|
||||
def get_paper(
|
||||
self,
|
||||
paper_id: str,
|
||||
include_fields: Optional[List[str]] = None
|
||||
) -> Union[Dict[str, Any], Dict[str, str]]:
|
||||
"""
|
||||
Get details of a specific paper by its arXiv ID.
|
||||
|
||||
Args:
|
||||
paper_id: arXiv paper ID (e.g., "2401.00123")
|
||||
include_fields: List of fields to include in results. If None, includes all.
|
||||
Available fields: ["title", "authors", "summary", "comment", "journal_ref",
|
||||
"doi", "primary_category", "categories", "links"]
|
||||
|
||||
Returns:
|
||||
Dict: Paper details or error dict
|
||||
"""
|
||||
try:
|
||||
import arxiv
|
||||
|
||||
# Configure client
|
||||
client = arxiv.Client()
|
||||
|
||||
# Get paper by ID
|
||||
search = arxiv.Search(id_list=[paper_id])
|
||||
results = list(client.results(search))
|
||||
|
||||
if not results:
|
||||
return {"error": f"Paper with ID {paper_id} not found"}
|
||||
|
||||
# Convert to dict with selected fields
|
||||
paper = self._result_to_dict(results[0], include_fields)
|
||||
return paper
|
||||
except Exception as e:
|
||||
error_msg = f"Error getting paper {paper_id}: {str(e)}"
|
||||
logging.error(error_msg)
|
||||
return {"error": error_msg}
|
||||
|
||||
def get_papers_by_author(
|
||||
self,
|
||||
author: str,
|
||||
max_results: int = 10,
|
||||
sort_by: str = "submittedDate",
|
||||
sort_order: str = "descending",
|
||||
include_fields: Optional[List[str]] = None
|
||||
) -> Union[List[Dict[str, Any]], Dict[str, str]]:
|
||||
"""
|
||||
Get papers by a specific author.
|
||||
|
||||
Args:
|
||||
author: Author name (e.g., "Einstein")
|
||||
max_results: Maximum number of results to return
|
||||
sort_by: Sort results by ("relevance", "lastUpdatedDate", "submittedDate")
|
||||
sort_order: Sort order ("ascending" or "descending")
|
||||
include_fields: List of fields to include in results
|
||||
|
||||
Returns:
|
||||
List[Dict] or Dict: List of papers or error dict
|
||||
"""
|
||||
query = f'au:"{author}"'
|
||||
return self.search(query, max_results, sort_by, sort_order, include_fields)
|
||||
|
||||
def get_papers_by_category(
|
||||
self,
|
||||
category: str,
|
||||
max_results: int = 10,
|
||||
sort_by: str = "submittedDate",
|
||||
sort_order: str = "descending",
|
||||
include_fields: Optional[List[str]] = None
|
||||
) -> Union[List[Dict[str, Any]], Dict[str, str]]:
|
||||
"""
|
||||
Get papers from a specific category.
|
||||
|
||||
Args:
|
||||
category: arXiv category (e.g., "cs.AI", "physics.gen-ph")
|
||||
max_results: Maximum number of results to return
|
||||
sort_by: Sort results by ("relevance", "lastUpdatedDate", "submittedDate")
|
||||
sort_order: Sort order ("ascending" or "descending")
|
||||
include_fields: List of fields to include in results
|
||||
|
||||
Returns:
|
||||
List[Dict] or Dict: List of papers or error dict
|
||||
"""
|
||||
query = f'cat:{category}'
|
||||
return self.search(query, max_results, sort_by, sort_order, include_fields)
|
||||
|
||||
def _result_to_dict(
|
||||
self,
|
||||
result: Any,
|
||||
include_fields: Optional[List[str]] = None
|
||||
) -> Dict[str, Any]:
|
||||
"""Convert arxiv.Result to dictionary with selected fields."""
|
||||
# Default fields to include
|
||||
if include_fields is None:
|
||||
include_fields = [
|
||||
"title", "authors", "summary", "comment", "journal_ref",
|
||||
"doi", "primary_category", "categories", "links"
|
||||
]
|
||||
|
||||
# Build paper dict with selected fields
|
||||
paper = {}
|
||||
|
||||
# Always include these basic fields
|
||||
paper["arxiv_id"] = result.entry_id.split("/")[-1]
|
||||
paper["updated"] = result.updated.isoformat() if result.updated else None
|
||||
paper["published"] = result.published.isoformat() if result.published else None
|
||||
|
||||
# Add requested fields
|
||||
if "title" in include_fields:
|
||||
paper["title"] = result.title
|
||||
if "authors" in include_fields:
|
||||
paper["authors"] = [str(author) for author in result.authors]
|
||||
if "summary" in include_fields:
|
||||
paper["summary"] = result.summary
|
||||
if "comment" in include_fields:
|
||||
paper["comment"] = result.comment
|
||||
if "journal_ref" in include_fields:
|
||||
paper["journal_ref"] = result.journal_ref
|
||||
if "doi" in include_fields:
|
||||
paper["doi"] = result.doi
|
||||
if "primary_category" in include_fields:
|
||||
paper["primary_category"] = result.primary_category
|
||||
if "categories" in include_fields:
|
||||
paper["categories"] = result.categories
|
||||
if "links" in include_fields:
|
||||
paper["pdf_url"] = result.pdf_url
|
||||
paper["abstract_url"] = f"https://arxiv.org/abs/{paper['arxiv_id']}"
|
||||
|
||||
return paper
|
||||
|
||||
# Create instance for direct function access
|
||||
_arxiv_tools = ArxivTools()
|
||||
search_arxiv = _arxiv_tools.search
|
||||
get_arxiv_paper = _arxiv_tools.get_paper
|
||||
get_papers_by_author = _arxiv_tools.get_papers_by_author
|
||||
get_papers_by_category = _arxiv_tools.get_papers_by_category
|
||||
|
||||
if __name__ == "__main__":
|
||||
# Example usage
|
||||
print("\n==================================================")
|
||||
print("ArxivTools Demonstration")
|
||||
print("==================================================\n")
|
||||
|
||||
# 1. Search for papers
|
||||
print("1. Searching for Papers")
|
||||
print("------------------------------")
|
||||
query = "quantum computing"
|
||||
papers = search_arxiv(query, max_results=3)
|
||||
print(f"Papers about {query}:")
|
||||
if isinstance(papers, list):
|
||||
print(json.dumps(papers, indent=2))
|
||||
else:
|
||||
print(papers) # Show error
|
||||
print()
|
||||
|
||||
# 2. Get specific paper
|
||||
print("2. Getting Specific Paper")
|
||||
print("------------------------------")
|
||||
if isinstance(papers, list) and papers:
|
||||
paper_id = papers[0]["arxiv_id"]
|
||||
paper = get_arxiv_paper(paper_id)
|
||||
print(f"Paper {paper_id}:")
|
||||
if "error" not in paper:
|
||||
print(json.dumps(paper, indent=2))
|
||||
else:
|
||||
print(paper) # Show error
|
||||
print()
|
||||
|
||||
# 3. Get papers by author
|
||||
print("3. Getting Papers by Author")
|
||||
print("------------------------------")
|
||||
author = "Yoshua Bengio"
|
||||
author_papers = get_papers_by_author(author, max_results=3)
|
||||
print(f"Papers by {author}:")
|
||||
if isinstance(author_papers, list):
|
||||
print(json.dumps(author_papers, indent=2))
|
||||
else:
|
||||
print(author_papers) # Show error
|
||||
print()
|
||||
|
||||
# 4. Get papers by category
|
||||
print("4. Getting Papers by Category")
|
||||
print("------------------------------")
|
||||
category = "cs.AI"
|
||||
category_papers = get_papers_by_category(category, max_results=3)
|
||||
print(f"Papers in category {category}:")
|
||||
if isinstance(category_papers, list):
|
||||
print(json.dumps(category_papers, indent=2))
|
||||
else:
|
||||
print(category_papers) # Show error
|
||||
|
||||
print("\n==================================================")
|
||||
print("Demonstration Complete")
|
||||
print("==================================================")
|
||||
@@ -0,0 +1,278 @@
|
||||
"""Tools for performing calculations.
|
||||
|
||||
Usage:
|
||||
from praisonaiagents.tools import calculator_tools
|
||||
result = calculator_tools.evaluate("2 + 2 * 3")
|
||||
|
||||
or
|
||||
from praisonaiagents.tools import evaluate, solve_equation, convert_units
|
||||
result = evaluate("2 + 2 * 3")
|
||||
"""
|
||||
|
||||
import logging
|
||||
from typing import List, Dict, Optional, Any
|
||||
from importlib import util
|
||||
import math
|
||||
|
||||
class CalculatorTools:
|
||||
"""Tools for performing calculations."""
|
||||
|
||||
def __init__(self):
|
||||
"""Initialize CalculatorTools."""
|
||||
self._check_dependencies()
|
||||
|
||||
def _check_dependencies(self):
|
||||
"""Check if required packages are installed."""
|
||||
missing = []
|
||||
for package in ['sympy', 'pint']:
|
||||
if util.find_spec(package) is None:
|
||||
missing.append(package)
|
||||
|
||||
if missing:
|
||||
raise ImportError(
|
||||
f"Required packages not available. Please install: {', '.join(missing)}\n"
|
||||
f"Run: pip install {' '.join(missing)}"
|
||||
)
|
||||
|
||||
def evaluate(
|
||||
self,
|
||||
expression: str,
|
||||
variables: Optional[Dict[str, float]] = None,
|
||||
precision: int = 10
|
||||
) -> Dict[str, Any]:
|
||||
"""Evaluate a mathematical expression."""
|
||||
try:
|
||||
if util.find_spec('sympy') is None:
|
||||
error_msg = "sympy package is not available. Please install it using: pip install sympy"
|
||||
logging.error(error_msg)
|
||||
return {"error": error_msg}
|
||||
|
||||
# Import sympy only when needed
|
||||
import sympy
|
||||
|
||||
# Replace common mathematical functions
|
||||
expression = expression.lower()
|
||||
replacements = {
|
||||
'sin(': 'math.sin(',
|
||||
'cos(': 'math.cos(',
|
||||
'tan(': 'math.tan(',
|
||||
'sqrt(': 'math.sqrt(',
|
||||
'log(': 'math.log(',
|
||||
'exp(': 'math.exp(',
|
||||
'pi': str(math.pi),
|
||||
'e': str(math.e)
|
||||
}
|
||||
for old, new in replacements.items():
|
||||
expression = expression.replace(old, new)
|
||||
|
||||
# Create safe namespace
|
||||
safe_dict = {
|
||||
'math': math,
|
||||
'__builtins__': None
|
||||
}
|
||||
if variables:
|
||||
safe_dict.update(variables)
|
||||
|
||||
# Evaluate expression
|
||||
result = eval(expression, safe_dict)
|
||||
|
||||
# Round to specified precision
|
||||
if isinstance(result, (int, float)):
|
||||
return {"result": round(float(result), precision)}
|
||||
return {"error": "Invalid expression"}
|
||||
except Exception as e:
|
||||
error_msg = f"Error evaluating expression: {str(e)}"
|
||||
logging.error(error_msg)
|
||||
return {"error": error_msg}
|
||||
|
||||
def solve_equation(
|
||||
self,
|
||||
equation: str,
|
||||
variable: str = 'x'
|
||||
) -> Dict[str, Any]:
|
||||
"""Solve a mathematical equation."""
|
||||
try:
|
||||
if util.find_spec('sympy') is None:
|
||||
error_msg = "sympy package is not available. Please install it using: pip install sympy"
|
||||
logging.error(error_msg)
|
||||
return {"error": error_msg}
|
||||
|
||||
# Import sympy only when needed
|
||||
import sympy
|
||||
|
||||
# Parse equation
|
||||
if '=' in equation:
|
||||
left, right = equation.split('=')
|
||||
equation = f"({left}) - ({right})"
|
||||
|
||||
# Convert to SymPy expression
|
||||
x = sympy.Symbol(variable)
|
||||
expr = sympy.sympify(equation)
|
||||
|
||||
# Solve equation
|
||||
solutions = sympy.solve(expr, x)
|
||||
|
||||
# Convert complex solutions to real if possible
|
||||
real_solutions = []
|
||||
for sol in solutions:
|
||||
if sol.is_real:
|
||||
real_solutions.append(float(sol))
|
||||
|
||||
return {"solutions": real_solutions} if real_solutions else {"error": "No real solutions found"}
|
||||
except Exception as e:
|
||||
error_msg = f"Error solving equation: {str(e)}"
|
||||
logging.error(error_msg)
|
||||
return {"error": error_msg}
|
||||
|
||||
def convert_units(
|
||||
self,
|
||||
value: float,
|
||||
from_unit: str,
|
||||
to_unit: str
|
||||
) -> Dict[str, Any]:
|
||||
"""Convert between different units."""
|
||||
try:
|
||||
if util.find_spec('pint') is None:
|
||||
error_msg = "pint package is not available. Please install it using: pip install pint"
|
||||
logging.error(error_msg)
|
||||
return {"error": error_msg}
|
||||
|
||||
# Import pint only when needed
|
||||
import pint
|
||||
|
||||
# Create quantity with source unit
|
||||
ureg = pint.UnitRegistry()
|
||||
quantity = value * ureg(from_unit)
|
||||
|
||||
# Convert to target unit
|
||||
result = quantity.to(to_unit)
|
||||
|
||||
return {"result": float(result.magnitude)}
|
||||
except Exception as e:
|
||||
error_msg = f"Error converting units: {str(e)}"
|
||||
logging.error(error_msg)
|
||||
return {"error": error_msg}
|
||||
|
||||
def calculate_statistics(
|
||||
self,
|
||||
numbers: List[float]
|
||||
) -> Dict[str, Any]:
|
||||
"""Calculate basic statistics for a list of numbers."""
|
||||
try:
|
||||
if not numbers:
|
||||
return {"error": "No numbers provided"}
|
||||
|
||||
n = len(numbers)
|
||||
mean = sum(numbers) / n
|
||||
|
||||
# Calculate variance and std dev
|
||||
squared_diff_sum = sum((x - mean) ** 2 for x in numbers)
|
||||
variance = squared_diff_sum / (n - 1) if n > 1 else 0
|
||||
std_dev = math.sqrt(variance)
|
||||
|
||||
# Calculate median
|
||||
sorted_nums = sorted(numbers)
|
||||
if n % 2 == 0:
|
||||
median = (sorted_nums[n//2 - 1] + sorted_nums[n//2]) / 2
|
||||
else:
|
||||
median = sorted_nums[n//2]
|
||||
|
||||
return {
|
||||
"mean": mean,
|
||||
"median": median,
|
||||
"std_dev": std_dev,
|
||||
"variance": variance,
|
||||
"min": min(numbers),
|
||||
"max": max(numbers),
|
||||
"range": max(numbers) - min(numbers),
|
||||
"count": n
|
||||
}
|
||||
except Exception as e:
|
||||
error_msg = f"Error calculating statistics: {str(e)}"
|
||||
logging.error(error_msg)
|
||||
return {"error": error_msg}
|
||||
|
||||
def calculate_financial(
|
||||
self,
|
||||
principal: float,
|
||||
rate: float,
|
||||
time: float,
|
||||
frequency: str = 'yearly'
|
||||
) -> Dict[str, Any]:
|
||||
"""Calculate financial metrics like compound interest."""
|
||||
try:
|
||||
# Convert rate to decimal
|
||||
rate = rate / 100
|
||||
|
||||
# Get compounding frequency
|
||||
freq_map = {
|
||||
'yearly': 1,
|
||||
'semi-annual': 2,
|
||||
'quarterly': 4,
|
||||
'monthly': 12,
|
||||
'daily': 365
|
||||
}
|
||||
n = freq_map.get(frequency.lower(), 1)
|
||||
|
||||
# Calculate compound interest
|
||||
amount = principal * (1 + rate/n)**(n*time)
|
||||
interest = amount - principal
|
||||
|
||||
# Calculate simple interest
|
||||
simple_interest = principal * rate * time
|
||||
|
||||
return {
|
||||
"final_amount": amount,
|
||||
"compound_interest": interest,
|
||||
"simple_interest": simple_interest,
|
||||
"difference": interest - simple_interest
|
||||
}
|
||||
except Exception as e:
|
||||
error_msg = f"Error calculating financial metrics: {str(e)}"
|
||||
logging.error(error_msg)
|
||||
return {"error": error_msg}
|
||||
|
||||
# Create instance for direct function access
|
||||
_calculator_tools = CalculatorTools()
|
||||
evaluate = _calculator_tools.evaluate
|
||||
solve_equation = _calculator_tools.solve_equation
|
||||
convert_units = _calculator_tools.convert_units
|
||||
calculate_statistics = _calculator_tools.calculate_statistics
|
||||
calculate_financial = _calculator_tools.calculate_financial
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("\n==================================================")
|
||||
print("CalculatorTools Demonstration")
|
||||
print("==================================================\n")
|
||||
|
||||
print("1. Basic Arithmetic")
|
||||
print("------------------------------")
|
||||
print("2 + 2 =", evaluate("2 + 2")["result"])
|
||||
print("5 * 6 =", evaluate("5 * 6")["result"])
|
||||
print("10 / 3 =", evaluate("10 / 3")["result"])
|
||||
print()
|
||||
|
||||
print("2. Complex Expressions")
|
||||
print("------------------------------")
|
||||
print("(2 + 3) * 4 =", evaluate("(2 + 3) * 4")["result"])
|
||||
print("2^3 + 4 =", evaluate("2^3 + 4")["result"])
|
||||
print("sqrt(16) + 2 =", evaluate("sqrt(16) + 2")["result"])
|
||||
print()
|
||||
|
||||
print("3. Solving Equations")
|
||||
print("------------------------------")
|
||||
result = solve_equation("x^2 - 5*x + 6 = 0")
|
||||
print("x^2 - 5*x + 6 = 0")
|
||||
print("Solutions:", result["solutions"])
|
||||
print()
|
||||
|
||||
print("4. Unit Conversions")
|
||||
print("------------------------------")
|
||||
print("100 meters to kilometers:", convert_units(100, "meters", "kilometers")["result"])
|
||||
print("1 hour to minutes:", convert_units(1, "hours", "minutes")["result"])
|
||||
print("32 fahrenheit to celsius:", convert_units(32, "fahrenheit", "celsius")["result"])
|
||||
print()
|
||||
|
||||
print("==================================================")
|
||||
print("Demonstration Complete")
|
||||
print("==================================================")
|
||||
@@ -0,0 +1,266 @@
|
||||
"""Tools for working with CSV files.
|
||||
|
||||
Usage:
|
||||
from praisonaiagents.tools import csv_tools
|
||||
df = csv_tools.read_csv("data.csv")
|
||||
|
||||
or
|
||||
from praisonaiagents.tools import read_csv, write_csv, merge_csv
|
||||
df = read_csv("data.csv")
|
||||
"""
|
||||
|
||||
import logging
|
||||
from typing import List, Dict, Union, Optional, Any, TYPE_CHECKING
|
||||
from importlib import util
|
||||
import json
|
||||
import csv
|
||||
from pathlib import Path
|
||||
|
||||
if TYPE_CHECKING:
|
||||
import pandas as pd
|
||||
|
||||
class CSVTools:
|
||||
"""Tools for working with CSV files."""
|
||||
|
||||
def __init__(self):
|
||||
"""Initialize CSVTools."""
|
||||
pass
|
||||
|
||||
def _get_pandas(self) -> Optional['pd']:
|
||||
"""Get pandas module, installing if needed"""
|
||||
if util.find_spec('pandas') is None:
|
||||
error_msg = "pandas package is not available. Please install it using: pip install pandas"
|
||||
logging.error(error_msg)
|
||||
return None
|
||||
import pandas as pd
|
||||
return pd
|
||||
|
||||
def read_csv(
|
||||
self,
|
||||
filepath: str,
|
||||
encoding: str = 'utf-8',
|
||||
delimiter: str = ',',
|
||||
header: Union[int, List[int], None] = 0,
|
||||
usecols: Optional[List[str]] = None,
|
||||
dtype: Optional[Dict[str, str]] = None,
|
||||
parse_dates: Optional[List[str]] = None,
|
||||
na_values: Optional[List[str]] = None,
|
||||
nrows: Optional[int] = None
|
||||
) -> List[Dict[str, Any]]:
|
||||
"""Read a CSV file with advanced options.
|
||||
|
||||
Args:
|
||||
filepath: Path to CSV file
|
||||
encoding: File encoding
|
||||
delimiter: Column delimiter
|
||||
header: Row number(s) to use as column names
|
||||
usecols: Columns to read
|
||||
dtype: Dict of column dtypes
|
||||
parse_dates: List of columns to parse as dates
|
||||
na_values: Additional strings to recognize as NA/NaN
|
||||
nrows: Number of rows to read
|
||||
|
||||
Returns:
|
||||
List of row dicts
|
||||
"""
|
||||
try:
|
||||
pd = self._get_pandas()
|
||||
if pd is None:
|
||||
return {"error": "pandas package not available"}
|
||||
|
||||
df = pd.read_csv(
|
||||
filepath,
|
||||
encoding=encoding,
|
||||
delimiter=delimiter,
|
||||
header=header,
|
||||
usecols=usecols,
|
||||
dtype=dtype,
|
||||
parse_dates=parse_dates,
|
||||
na_values=na_values,
|
||||
nrows=nrows
|
||||
)
|
||||
return df.to_dict('records')
|
||||
|
||||
except Exception as e:
|
||||
error_msg = f"Error reading CSV file {filepath}: {str(e)}"
|
||||
logging.error(error_msg)
|
||||
return {"error": error_msg}
|
||||
|
||||
def write_csv(
|
||||
self,
|
||||
filepath: str,
|
||||
data: List[Dict[str, Any]],
|
||||
encoding: str = 'utf-8',
|
||||
delimiter: str = ',',
|
||||
index: bool = False,
|
||||
header: bool = True,
|
||||
float_format: Optional[str] = None,
|
||||
date_format: Optional[str] = None,
|
||||
mode: str = 'w'
|
||||
) -> bool:
|
||||
"""Write data to a CSV file.
|
||||
|
||||
Args:
|
||||
filepath: Path to CSV file
|
||||
data: List of row dicts to write
|
||||
encoding: File encoding
|
||||
delimiter: Column delimiter
|
||||
index: Whether to write row indices
|
||||
header: Whether to write column headers
|
||||
float_format: Format string for float values
|
||||
date_format: Format string for date values
|
||||
mode: Write mode ('w' for write, 'a' for append)
|
||||
|
||||
Returns:
|
||||
bool: Success status
|
||||
"""
|
||||
try:
|
||||
pd = self._get_pandas()
|
||||
if pd is None:
|
||||
return False
|
||||
|
||||
df = pd.DataFrame(data)
|
||||
df.to_csv(
|
||||
filepath,
|
||||
encoding=encoding,
|
||||
sep=delimiter,
|
||||
index=index,
|
||||
header=header,
|
||||
float_format=float_format,
|
||||
date_format=date_format,
|
||||
mode=mode
|
||||
)
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
error_msg = f"Error writing CSV file {filepath}: {str(e)}"
|
||||
logging.error(error_msg)
|
||||
return False
|
||||
|
||||
def merge_csv(
|
||||
self,
|
||||
files: List[str],
|
||||
output_file: str,
|
||||
how: str = 'inner',
|
||||
on: Optional[Union[str, List[str]]] = None,
|
||||
suffixes: Optional[tuple] = None
|
||||
) -> bool:
|
||||
"""Merge multiple CSV files.
|
||||
|
||||
Args:
|
||||
files: List of CSV files to merge
|
||||
output_file: Output file path
|
||||
how: Merge method ('inner', 'outer', 'left', 'right')
|
||||
on: Column(s) to merge on
|
||||
suffixes: Suffixes for overlapping columns
|
||||
|
||||
Returns:
|
||||
bool: Success status
|
||||
"""
|
||||
try:
|
||||
if len(files) < 2:
|
||||
error_msg = "At least two files are required for merging"
|
||||
logging.error(error_msg)
|
||||
return False
|
||||
|
||||
pd = self._get_pandas()
|
||||
if pd is None:
|
||||
return False
|
||||
|
||||
# Read first file
|
||||
result = pd.read_csv(files[0])
|
||||
|
||||
# Merge with remaining files
|
||||
for file in files[1:]:
|
||||
df = pd.read_csv(file)
|
||||
result = pd.merge(
|
||||
result,
|
||||
df,
|
||||
how=how,
|
||||
on=on,
|
||||
suffixes=suffixes or ('_1', '_2')
|
||||
)
|
||||
|
||||
# Write merged result
|
||||
result.to_csv(output_file, index=False)
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
error_msg = f"Error merging CSV files: {str(e)}"
|
||||
logging.error(error_msg)
|
||||
return False
|
||||
|
||||
# Create instance for direct function access
|
||||
_csv_tools = CSVTools()
|
||||
read_csv = _csv_tools.read_csv
|
||||
write_csv = _csv_tools.write_csv
|
||||
merge_csv = _csv_tools.merge_csv
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("\n==================================================")
|
||||
print("CSVTools Demonstration")
|
||||
print("==================================================\n")
|
||||
|
||||
# Create a temporary file for testing
|
||||
import tempfile
|
||||
import os
|
||||
|
||||
with tempfile.NamedTemporaryFile(suffix='.csv', delete=False) as temp:
|
||||
temp_file = temp.name
|
||||
|
||||
print("1. Writing CSV File")
|
||||
print("------------------------------")
|
||||
data = [
|
||||
{"name": "Alice", "age": 25, "city": "New York"},
|
||||
{"name": "Bob", "age": 30, "city": "San Francisco"},
|
||||
{"name": "Charlie", "age": 35, "city": "Chicago"}
|
||||
]
|
||||
result = write_csv(temp_file, data)
|
||||
print(f"Data written successfully: {result}")
|
||||
print()
|
||||
|
||||
print("2. Reading CSV File")
|
||||
print("------------------------------")
|
||||
read_data = read_csv(temp_file)
|
||||
print("Contents of CSV file:")
|
||||
for row in read_data:
|
||||
print(row)
|
||||
print()
|
||||
|
||||
print("3. Merging CSV Files")
|
||||
print("------------------------------")
|
||||
# Create a second file for merging
|
||||
with tempfile.NamedTemporaryFile(suffix='.csv', delete=False) as temp2:
|
||||
temp_file2 = temp2.name
|
||||
data2 = [
|
||||
{"name": "Alice", "salary": 75000},
|
||||
{"name": "Bob", "salary": 85000},
|
||||
{"name": "Charlie", "salary": 95000}
|
||||
]
|
||||
write_csv(temp_file2, data2)
|
||||
|
||||
# Merge files
|
||||
with tempfile.NamedTemporaryFile(suffix='.csv', delete=False) as temp3:
|
||||
temp_file3 = temp3.name
|
||||
result = merge_csv(
|
||||
[temp_file, temp_file2],
|
||||
temp_file3,
|
||||
how='inner',
|
||||
on='name'
|
||||
)
|
||||
print(f"Files merged successfully: {result}")
|
||||
if result:
|
||||
merged_data = read_csv(temp_file3)
|
||||
print("\nMerged contents:")
|
||||
for row in merged_data:
|
||||
print(row)
|
||||
print()
|
||||
|
||||
# Clean up temporary files
|
||||
os.unlink(temp_file)
|
||||
os.unlink(temp_file2)
|
||||
os.unlink(temp_file3)
|
||||
|
||||
print("==================================================")
|
||||
print("Demonstration Complete")
|
||||
print("==================================================\n")
|
||||
@@ -0,0 +1,268 @@
|
||||
"""Tools for working with DuckDB databases.
|
||||
|
||||
Usage:
|
||||
from praisonaiagents.tools import duckdb_tools
|
||||
df = duckdb_tools.query("SELECT * FROM my_table")
|
||||
|
||||
or
|
||||
from praisonaiagents.tools import query_db, create_table, load_data
|
||||
df = query_db("SELECT * FROM my_table")
|
||||
"""
|
||||
|
||||
import logging
|
||||
from typing import List, Dict, Any, Optional, Union, TYPE_CHECKING
|
||||
from importlib import util
|
||||
import json
|
||||
|
||||
if TYPE_CHECKING:
|
||||
import duckdb
|
||||
import pandas as pd
|
||||
|
||||
class DuckDBTools:
|
||||
"""Tools for working with DuckDB databases."""
|
||||
|
||||
def __init__(self, database: str = ':memory:'):
|
||||
"""Initialize DuckDBTools.
|
||||
|
||||
Args:
|
||||
database: Path to database file or ':memory:' for in-memory database
|
||||
"""
|
||||
self.database = database
|
||||
self._conn = None
|
||||
|
||||
def _get_duckdb(self) -> Optional['duckdb']:
|
||||
"""Get duckdb module, installing if needed"""
|
||||
if util.find_spec('duckdb') is None:
|
||||
error_msg = "duckdb package is not available. Please install it using: pip install duckdb"
|
||||
logging.error(error_msg)
|
||||
return None
|
||||
import duckdb
|
||||
return duckdb
|
||||
|
||||
def _get_pandas(self) -> Optional['pd']:
|
||||
"""Get pandas module, installing if needed"""
|
||||
if util.find_spec('pandas') is None:
|
||||
error_msg = "pandas package is not available. Please install it using: pip install pandas"
|
||||
logging.error(error_msg)
|
||||
return None
|
||||
import pandas as pd
|
||||
return pd
|
||||
|
||||
def _get_connection(self) -> Optional['duckdb.DuckDBPyConnection']:
|
||||
"""Get or create database connection"""
|
||||
if self._conn is None:
|
||||
duckdb = self._get_duckdb()
|
||||
if duckdb is None:
|
||||
return None
|
||||
try:
|
||||
self._conn = duckdb.connect(self.database)
|
||||
except Exception as e:
|
||||
error_msg = f"Error connecting to database {self.database}: {str(e)}"
|
||||
logging.error(error_msg)
|
||||
return None
|
||||
return self._conn
|
||||
|
||||
def execute_query(
|
||||
self,
|
||||
query: str,
|
||||
params: Optional[Union[tuple, dict]] = None,
|
||||
return_df: bool = True
|
||||
) -> Union[List[Dict[str, Any]], Dict[str, str]]:
|
||||
"""Execute a SQL query.
|
||||
|
||||
Args:
|
||||
query: SQL query to execute
|
||||
params: Query parameters
|
||||
return_df: If True, return results as DataFrame records
|
||||
|
||||
Returns:
|
||||
Query results as list of dicts, or error dict
|
||||
"""
|
||||
try:
|
||||
conn = self._get_connection()
|
||||
if conn is None:
|
||||
return {"error": "Could not connect to database"}
|
||||
|
||||
if params:
|
||||
result = conn.execute(query, params)
|
||||
else:
|
||||
result = conn.execute(query)
|
||||
|
||||
if return_df:
|
||||
pd = self._get_pandas()
|
||||
if pd is None:
|
||||
return {"error": "pandas package not available"}
|
||||
df = result.df()
|
||||
return df.to_dict('records')
|
||||
else:
|
||||
return [dict(row) for row in result.fetchall()]
|
||||
|
||||
except Exception as e:
|
||||
error_msg = f"Error executing query: {str(e)}"
|
||||
logging.error(error_msg)
|
||||
return {"error": error_msg}
|
||||
|
||||
def load_csv(
|
||||
self,
|
||||
table_name: str,
|
||||
filepath: str,
|
||||
schema: Optional[Dict[str, str]] = None,
|
||||
if_exists: str = 'replace'
|
||||
) -> bool:
|
||||
"""Load a CSV file into a table.
|
||||
|
||||
Args:
|
||||
table_name: Name of table to create
|
||||
filepath: Path to CSV file
|
||||
schema: Optional column definitions
|
||||
if_exists: What to do if table exists ('fail', 'replace', 'append')
|
||||
|
||||
Returns:
|
||||
bool: Success status
|
||||
"""
|
||||
try:
|
||||
conn = self._get_connection()
|
||||
if conn is None:
|
||||
return False
|
||||
|
||||
# Check if table exists
|
||||
exists = conn.execute(f"""
|
||||
SELECT name FROM sqlite_master
|
||||
WHERE type='table' AND name='{table_name}'
|
||||
""").fetchone() is not None
|
||||
|
||||
if exists:
|
||||
if if_exists == 'fail':
|
||||
raise ValueError(f"Table {table_name} already exists")
|
||||
elif if_exists == 'replace':
|
||||
conn.execute(f"DROP TABLE IF EXISTS {table_name}")
|
||||
elif if_exists != 'append':
|
||||
raise ValueError("if_exists must be 'fail', 'replace', or 'append'")
|
||||
|
||||
# Create table if needed
|
||||
if not exists or if_exists == 'replace':
|
||||
if schema:
|
||||
# Create table with schema
|
||||
columns = ', '.join(f"{k} {v}" for k, v in schema.items())
|
||||
conn.execute(f"CREATE TABLE {table_name} ({columns})")
|
||||
else:
|
||||
# Infer schema from CSV
|
||||
conn.execute(f"""
|
||||
CREATE TABLE {table_name} AS
|
||||
SELECT * FROM read_csv_auto('{filepath}')
|
||||
WHERE 1=0
|
||||
""")
|
||||
|
||||
# Load data
|
||||
conn.execute(f"""
|
||||
INSERT INTO {table_name}
|
||||
SELECT * FROM read_csv_auto('{filepath}')
|
||||
""")
|
||||
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
error_msg = f"Error loading CSV file {filepath}: {str(e)}"
|
||||
logging.error(error_msg)
|
||||
return False
|
||||
|
||||
def export_csv(
|
||||
self,
|
||||
query: str,
|
||||
filepath: str,
|
||||
params: Optional[Union[tuple, dict]] = None
|
||||
) -> bool:
|
||||
"""Export query results to CSV.
|
||||
|
||||
Args:
|
||||
query: SQL query to execute
|
||||
filepath: Output file path
|
||||
params: Optional query parameters
|
||||
|
||||
Returns:
|
||||
bool: Success status
|
||||
"""
|
||||
try:
|
||||
# Execute query and get results as DataFrame
|
||||
results = self.execute_query(query, params)
|
||||
if isinstance(results, dict) and 'error' in results:
|
||||
return False
|
||||
|
||||
pd = self._get_pandas()
|
||||
if pd is None:
|
||||
return False
|
||||
|
||||
# Convert to DataFrame and save
|
||||
df = pd.DataFrame(results)
|
||||
df.to_csv(filepath, index=False)
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
error_msg = f"Error exporting to CSV file {filepath}: {str(e)}"
|
||||
logging.error(error_msg)
|
||||
return False
|
||||
|
||||
def close(self):
|
||||
"""Close database connection."""
|
||||
if self._conn:
|
||||
self._conn.close()
|
||||
self._conn = None
|
||||
|
||||
# Create instance for direct function access
|
||||
_duckdb_tools = DuckDBTools()
|
||||
execute_query = _duckdb_tools.execute_query
|
||||
load_csv = _duckdb_tools.load_csv
|
||||
export_csv = _duckdb_tools.export_csv
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("\n==================================================")
|
||||
print("DuckDBTools Demonstration")
|
||||
print("==================================================\n")
|
||||
|
||||
# Create a temporary file for testing
|
||||
import tempfile
|
||||
import os
|
||||
|
||||
with tempfile.NamedTemporaryFile(suffix='.csv', delete=False) as temp:
|
||||
temp_file = temp.name
|
||||
|
||||
# Create sample data
|
||||
with open(temp_file, 'w') as f:
|
||||
f.write("name,age,city\n")
|
||||
f.write("Alice,25,New York\n")
|
||||
f.write("Bob,30,San Francisco\n")
|
||||
f.write("Charlie,35,Chicago\n")
|
||||
|
||||
print("1. Loading CSV File")
|
||||
print("------------------------------")
|
||||
result = load_csv('users', temp_file)
|
||||
print(f"CSV loaded successfully: {result}")
|
||||
print()
|
||||
|
||||
print("2. Executing Query")
|
||||
print("------------------------------")
|
||||
query = "SELECT * FROM users WHERE age > 25"
|
||||
results = execute_query(query)
|
||||
print("Query results:")
|
||||
for row in results:
|
||||
print(row)
|
||||
print()
|
||||
|
||||
print("3. Exporting Query Results")
|
||||
print("------------------------------")
|
||||
with tempfile.NamedTemporaryFile(suffix='.csv', delete=False) as temp2:
|
||||
temp_file2 = temp2.name
|
||||
result = export_csv(query, temp_file2)
|
||||
print(f"Results exported successfully: {result}")
|
||||
if result:
|
||||
print("\nExported file contents:")
|
||||
with open(temp_file2) as f:
|
||||
print(f.read())
|
||||
|
||||
# Clean up temporary files
|
||||
os.unlink(temp_file)
|
||||
os.unlink(temp_file2)
|
||||
|
||||
print("==================================================")
|
||||
print("Demonstration Complete")
|
||||
print("==================================================\n")
|
||||
@@ -0,0 +1,52 @@
|
||||
"""DuckDuckGo search functionality.
|
||||
|
||||
Usage:
|
||||
from praisonaiagents.tools import internet_search
|
||||
results = internet_search("AI news")
|
||||
|
||||
or
|
||||
from praisonaiagents.tools import duckduckgo
|
||||
results = duckduckgo("AI news")
|
||||
"""
|
||||
|
||||
from typing import List, Dict
|
||||
import logging
|
||||
from importlib import util
|
||||
|
||||
def internet_search(query: str) -> List[Dict]:
|
||||
"""Perform an internet search using DuckDuckGo."""
|
||||
# Check if duckduckgo_search is installed
|
||||
if util.find_spec("duckduckgo_search") is None:
|
||||
error_msg = "DuckDuckGo search is not available. Please install duckduckgo_search package using: pip install duckduckgo_search"
|
||||
logging.error(error_msg)
|
||||
return [{"error": error_msg}]
|
||||
|
||||
try:
|
||||
# Import only when needed
|
||||
from duckduckgo_search import DDGS
|
||||
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
|
||||
|
||||
except Exception as e:
|
||||
error_msg = f"Error during DuckDuckGo search: {e}"
|
||||
logging.error(error_msg)
|
||||
return [{"error": error_msg}]
|
||||
|
||||
def duckduckgo(query: str) -> List[Dict]:
|
||||
"""Alias for internet_search function."""
|
||||
return internet_search(query)
|
||||
|
||||
if __name__ == "__main__":
|
||||
# Example usage
|
||||
results = internet_search("Python programming")
|
||||
for result in results:
|
||||
print(f"\nTitle: {result.get('title')}")
|
||||
print(f"URL: {result.get('url')}")
|
||||
print(f"Snippet: {result.get('snippet')}")
|
||||
@@ -0,0 +1,310 @@
|
||||
"""Tools for working with Excel files.
|
||||
|
||||
Usage:
|
||||
from praisonaiagents.tools import excel_tools
|
||||
df = excel_tools.read_excel("data.xlsx")
|
||||
|
||||
or
|
||||
from praisonaiagents.tools import read_excel, write_excel, merge_excel
|
||||
df = read_excel("data.xlsx")
|
||||
"""
|
||||
|
||||
import logging
|
||||
from typing import List, Dict, Union, Optional, Any, TYPE_CHECKING, Tuple
|
||||
from importlib import util
|
||||
import json
|
||||
from pathlib import Path
|
||||
import tempfile
|
||||
import os
|
||||
|
||||
if TYPE_CHECKING:
|
||||
import pandas as pd
|
||||
from openpyxl.styles import Font, PatternFill, Alignment, Border, Side
|
||||
from openpyxl.chart import BarChart, LineChart, PieChart, Reference
|
||||
from openpyxl.chart.label import DataLabelList
|
||||
|
||||
class ExcelTools:
|
||||
"""Tools for working with Excel files."""
|
||||
|
||||
def __init__(self):
|
||||
"""Initialize ExcelTools."""
|
||||
pass
|
||||
|
||||
def _get_pandas(self) -> Optional['pd']:
|
||||
"""Get pandas module, installing if needed"""
|
||||
if util.find_spec('pandas') is None:
|
||||
error_msg = "pandas package is not available. Please install it using: pip install pandas"
|
||||
logging.error(error_msg)
|
||||
return None
|
||||
if util.find_spec('openpyxl') is None:
|
||||
error_msg = "openpyxl package is not available. Please install it using: pip install openpyxl"
|
||||
logging.error(error_msg)
|
||||
return None
|
||||
import pandas as pd
|
||||
return pd
|
||||
|
||||
def read_excel(
|
||||
self,
|
||||
filepath: str,
|
||||
sheet_name: Optional[Union[str, int, List[Union[str, int]]]] = 0,
|
||||
header: Optional[int] = 0,
|
||||
usecols: Optional[List[str]] = None,
|
||||
skiprows: Optional[Union[int, List[int]]] = None,
|
||||
na_values: Optional[List[str]] = None,
|
||||
dtype: Optional[Dict[str, str]] = None
|
||||
) -> Union[Dict[str, List[Dict[str, Any]]], List[Dict[str, Any]]]:
|
||||
"""Read an Excel file with advanced options.
|
||||
|
||||
Args:
|
||||
filepath: Path to Excel file
|
||||
sheet_name: Sheet name(s) or index(es)
|
||||
header: Row number(s) to use as column names
|
||||
usecols: Columns to read
|
||||
skiprows: Line numbers to skip
|
||||
na_values: Additional strings to recognize as NA/NaN
|
||||
dtype: Dict of column dtypes
|
||||
|
||||
Returns:
|
||||
Dict of sheet names to data if multiple sheets, else list of row dicts
|
||||
"""
|
||||
try:
|
||||
pd = self._get_pandas()
|
||||
if pd is None:
|
||||
return {"error": "Required packages not available"}
|
||||
|
||||
# Read Excel file
|
||||
df = pd.read_excel(
|
||||
filepath,
|
||||
sheet_name=sheet_name,
|
||||
header=header,
|
||||
usecols=usecols,
|
||||
skiprows=skiprows,
|
||||
na_values=na_values,
|
||||
dtype=dtype,
|
||||
engine='openpyxl'
|
||||
)
|
||||
|
||||
# Convert to dict format
|
||||
if isinstance(df, dict):
|
||||
return {
|
||||
name: df[name].to_dict('records')
|
||||
for name in df.keys()
|
||||
}
|
||||
else:
|
||||
return df.to_dict('records')
|
||||
|
||||
except Exception as e:
|
||||
error_msg = f"Error reading Excel file {filepath}: {str(e)}"
|
||||
logging.error(error_msg)
|
||||
return {"error": error_msg}
|
||||
|
||||
def write_excel(
|
||||
self,
|
||||
filepath: str,
|
||||
data: Union[Dict[str, List[Dict[str, Any]]], List[Dict[str, Any]]],
|
||||
sheet_name: Optional[str] = None,
|
||||
index: bool = False,
|
||||
header: bool = True,
|
||||
mode: str = 'w'
|
||||
) -> bool:
|
||||
"""Write data to an Excel file.
|
||||
|
||||
Args:
|
||||
filepath: Path to Excel file
|
||||
data: Data to write (dict of sheet names to data or list of row dicts)
|
||||
sheet_name: Sheet name if data is a list
|
||||
index: Whether to write row indices
|
||||
header: Whether to write column headers
|
||||
mode: Write mode ('w' for write, 'a' for append)
|
||||
|
||||
Returns:
|
||||
bool: Success status
|
||||
"""
|
||||
try:
|
||||
pd = self._get_pandas()
|
||||
if pd is None:
|
||||
return False
|
||||
|
||||
# Convert data to DataFrame(s)
|
||||
if isinstance(data, dict):
|
||||
if mode == 'a' and os.path.exists(filepath):
|
||||
book = pd.ExcelFile(filepath)
|
||||
with pd.ExcelWriter(filepath, engine='openpyxl') as writer:
|
||||
# Copy existing sheets
|
||||
for sheet in book.sheet_names:
|
||||
pd.read_excel(filepath, sheet_name=sheet).to_excel(
|
||||
writer, sheet_name=sheet, index=index, header=header
|
||||
)
|
||||
# Add new sheets
|
||||
for name, sheet_data in data.items():
|
||||
df = pd.DataFrame(sheet_data)
|
||||
df.to_excel(
|
||||
writer, sheet_name=name, index=index, header=header
|
||||
)
|
||||
else:
|
||||
with pd.ExcelWriter(filepath, engine='openpyxl') as writer:
|
||||
for name, sheet_data in data.items():
|
||||
df = pd.DataFrame(sheet_data)
|
||||
df.to_excel(
|
||||
writer, sheet_name=name, index=index, header=header
|
||||
)
|
||||
else:
|
||||
if mode == 'a' and os.path.exists(filepath):
|
||||
book = pd.ExcelFile(filepath)
|
||||
with pd.ExcelWriter(filepath, engine='openpyxl') as writer:
|
||||
# Copy existing sheets
|
||||
for sheet in book.sheet_names:
|
||||
pd.read_excel(filepath, sheet_name=sheet).to_excel(
|
||||
writer, sheet_name=sheet, index=index, header=header
|
||||
)
|
||||
# Add new sheet
|
||||
df = pd.DataFrame(data)
|
||||
df.to_excel(
|
||||
writer,
|
||||
sheet_name=sheet_name or 'Sheet1',
|
||||
index=index,
|
||||
header=header
|
||||
)
|
||||
else:
|
||||
df = pd.DataFrame(data)
|
||||
df.to_excel(
|
||||
filepath,
|
||||
sheet_name=sheet_name or 'Sheet1',
|
||||
index=index,
|
||||
header=header,
|
||||
engine='openpyxl'
|
||||
)
|
||||
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
error_msg = f"Error writing Excel file {filepath}: {str(e)}"
|
||||
logging.error(error_msg)
|
||||
return False
|
||||
|
||||
def merge_excel(
|
||||
self,
|
||||
files: List[str],
|
||||
output_file: str,
|
||||
how: str = 'inner',
|
||||
on: Optional[Union[str, List[str]]] = None,
|
||||
suffixes: Optional[Tuple[str, str]] = None
|
||||
) -> bool:
|
||||
"""Merge multiple Excel files.
|
||||
|
||||
Args:
|
||||
files: List of Excel files to merge
|
||||
output_file: Output file path
|
||||
how: Merge method ('inner', 'outer', 'left', 'right')
|
||||
on: Column(s) to merge on
|
||||
suffixes: Suffixes for overlapping columns
|
||||
|
||||
Returns:
|
||||
bool: Success status
|
||||
"""
|
||||
try:
|
||||
if len(files) < 2:
|
||||
error_msg = "At least two files are required for merging"
|
||||
logging.error(error_msg)
|
||||
return False
|
||||
|
||||
# Read first file
|
||||
result = self.read_excel(files[0])
|
||||
|
||||
# Merge with remaining files
|
||||
for file in files[1:]:
|
||||
df = self.read_excel(file)
|
||||
if isinstance(df, dict):
|
||||
df = next(iter(df.values()))
|
||||
|
||||
pd = self._get_pandas()
|
||||
if pd is None:
|
||||
return False
|
||||
|
||||
result = pd.merge(
|
||||
pd.DataFrame(result),
|
||||
pd.DataFrame(df),
|
||||
how=how,
|
||||
on=on,
|
||||
suffixes=suffixes or ('_1', '_2')
|
||||
).to_dict('records')
|
||||
|
||||
# Write merged result
|
||||
return self.write_excel(output_file, result)
|
||||
|
||||
except Exception as e:
|
||||
error_msg = f"Error merging Excel files: {str(e)}"
|
||||
logging.error(error_msg)
|
||||
return False
|
||||
|
||||
# Create instance for direct function access
|
||||
_excel_tools = ExcelTools()
|
||||
read_excel = _excel_tools.read_excel
|
||||
write_excel = _excel_tools.write_excel
|
||||
merge_excel = _excel_tools.merge_excel
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("\n==================================================")
|
||||
print("ExcelTools Demonstration")
|
||||
print("==================================================\n")
|
||||
|
||||
# Create a temporary file for testing
|
||||
with tempfile.NamedTemporaryFile(suffix='.xlsx', delete=False) as temp:
|
||||
temp_file = temp.name
|
||||
|
||||
print("1. Writing Excel File")
|
||||
print("------------------------------")
|
||||
data = [
|
||||
{"name": "Alice", "age": 25, "city": "New York"},
|
||||
{"name": "Bob", "age": 30, "city": "San Francisco"},
|
||||
{"name": "Charlie", "age": 35, "city": "Chicago"}
|
||||
]
|
||||
result = write_excel(temp_file, data, "People")
|
||||
print(f"Data written successfully: {result}")
|
||||
print()
|
||||
|
||||
print("2. Reading Excel File")
|
||||
print("------------------------------")
|
||||
read_data = read_excel(temp_file)
|
||||
print("Contents of Excel file:")
|
||||
for row in read_data:
|
||||
print(row)
|
||||
print()
|
||||
|
||||
print("3. Merging Excel Files")
|
||||
print("------------------------------")
|
||||
# Create a second file for merging
|
||||
with tempfile.NamedTemporaryFile(suffix='.xlsx', delete=False) as temp2:
|
||||
temp_file2 = temp2.name
|
||||
data2 = [
|
||||
{"name": "Alice", "salary": 75000},
|
||||
{"name": "Bob", "salary": 85000},
|
||||
{"name": "Charlie", "salary": 95000}
|
||||
]
|
||||
write_excel(temp_file2, data2, "Salaries")
|
||||
|
||||
# Merge files
|
||||
with tempfile.NamedTemporaryFile(suffix='.xlsx', delete=False) as temp3:
|
||||
temp_file3 = temp3.name
|
||||
result = merge_excel(
|
||||
[temp_file, temp_file2],
|
||||
temp_file3,
|
||||
how='inner',
|
||||
on='name'
|
||||
)
|
||||
print(f"Files merged successfully: {result}")
|
||||
if result:
|
||||
merged_data = read_excel(temp_file3)
|
||||
print("\nMerged contents:")
|
||||
for row in merged_data:
|
||||
print(row)
|
||||
print()
|
||||
|
||||
# Clean up temporary files
|
||||
os.unlink(temp_file)
|
||||
os.unlink(temp_file2)
|
||||
os.unlink(temp_file3)
|
||||
|
||||
print("==================================================")
|
||||
print("Demonstration Complete")
|
||||
print("==================================================\n")
|
||||
@@ -0,0 +1,274 @@
|
||||
"""File handling tools for basic file operations.
|
||||
|
||||
Usage:
|
||||
from praisonaiagents.tools import file_tools
|
||||
content = file_tools.read_file("example.txt")
|
||||
file_tools.write_file("output.txt", "Hello World")
|
||||
|
||||
or
|
||||
from praisonaiagents.tools import read_file, write_file, list_files
|
||||
content = read_file("example.txt")
|
||||
"""
|
||||
|
||||
import os
|
||||
import json
|
||||
from typing import List, Dict, Union, Optional
|
||||
from pathlib import Path
|
||||
import shutil
|
||||
import logging
|
||||
|
||||
class FileTools:
|
||||
"""Tools for file operations including read, write, list, and information."""
|
||||
|
||||
@staticmethod
|
||||
def read_file(filepath: str, encoding: str = 'utf-8') -> str:
|
||||
"""
|
||||
Read content from a file.
|
||||
|
||||
Args:
|
||||
filepath: Path to the file
|
||||
encoding: File encoding (default: utf-8)
|
||||
|
||||
Returns:
|
||||
str: Content of the file
|
||||
"""
|
||||
try:
|
||||
with open(filepath, 'r', encoding=encoding) as f:
|
||||
return f.read()
|
||||
except Exception as e:
|
||||
error_msg = f"Error reading file {filepath}: {str(e)}"
|
||||
logging.error(error_msg)
|
||||
return error_msg
|
||||
|
||||
@staticmethod
|
||||
def write_file(filepath: str, content: str, encoding: str = 'utf-8') -> bool:
|
||||
"""
|
||||
Write content to a file.
|
||||
|
||||
Args:
|
||||
filepath: Path to the file
|
||||
content: Content to write
|
||||
encoding: File encoding (default: utf-8)
|
||||
|
||||
Returns:
|
||||
bool: True if successful, False otherwise
|
||||
"""
|
||||
try:
|
||||
# Create directory if it doesn't exist
|
||||
os.makedirs(os.path.dirname(filepath), exist_ok=True)
|
||||
with open(filepath, 'w', encoding=encoding) as f:
|
||||
f.write(content)
|
||||
return True
|
||||
except Exception as e:
|
||||
error_msg = f"Error writing to file {filepath}: {str(e)}"
|
||||
logging.error(error_msg)
|
||||
return False
|
||||
|
||||
@staticmethod
|
||||
def list_files(directory: str, pattern: Optional[str] = None) -> List[Dict[str, Union[str, int]]]:
|
||||
"""
|
||||
List files in a directory with optional pattern matching.
|
||||
|
||||
Args:
|
||||
directory: Directory path
|
||||
pattern: Optional glob pattern (e.g., "*.txt")
|
||||
|
||||
Returns:
|
||||
List[Dict]: List of file information dictionaries
|
||||
"""
|
||||
try:
|
||||
path = Path(directory)
|
||||
if pattern:
|
||||
files = path.glob(pattern)
|
||||
else:
|
||||
files = path.iterdir()
|
||||
|
||||
result = []
|
||||
for file in files:
|
||||
if file.is_file():
|
||||
stat = file.stat()
|
||||
result.append({
|
||||
'name': file.name,
|
||||
'path': str(file),
|
||||
'size': stat.st_size,
|
||||
'modified': stat.st_mtime,
|
||||
'created': stat.st_ctime
|
||||
})
|
||||
return result
|
||||
except Exception as e:
|
||||
error_msg = f"Error listing files in {directory}: {str(e)}"
|
||||
logging.error(error_msg)
|
||||
return [{'error': error_msg}]
|
||||
|
||||
@staticmethod
|
||||
def get_file_info(filepath: str) -> Dict[str, Union[str, int]]:
|
||||
"""
|
||||
Get detailed information about a file.
|
||||
|
||||
Args:
|
||||
filepath: Path to the file
|
||||
|
||||
Returns:
|
||||
Dict: File information including size, dates, etc.
|
||||
"""
|
||||
try:
|
||||
path = Path(filepath)
|
||||
if not path.exists():
|
||||
return {'error': f'File not found: {filepath}'}
|
||||
|
||||
stat = path.stat()
|
||||
return {
|
||||
'name': path.name,
|
||||
'path': str(path),
|
||||
'size': stat.st_size,
|
||||
'modified': stat.st_mtime,
|
||||
'created': stat.st_ctime,
|
||||
'is_file': path.is_file(),
|
||||
'is_dir': path.is_dir(),
|
||||
'extension': path.suffix,
|
||||
'parent': str(path.parent)
|
||||
}
|
||||
except Exception as e:
|
||||
error_msg = f"Error getting file info for {filepath}: {str(e)}"
|
||||
logging.error(error_msg)
|
||||
return {'error': error_msg}
|
||||
|
||||
@staticmethod
|
||||
def copy_file(src: str, dst: str) -> bool:
|
||||
"""
|
||||
Copy a file from source to destination.
|
||||
|
||||
Args:
|
||||
src: Source file path
|
||||
dst: Destination file path
|
||||
|
||||
Returns:
|
||||
bool: True if successful, False otherwise
|
||||
"""
|
||||
try:
|
||||
# Create destination directory if it doesn't exist
|
||||
os.makedirs(os.path.dirname(dst), exist_ok=True)
|
||||
shutil.copy2(src, dst)
|
||||
return True
|
||||
except Exception as e:
|
||||
error_msg = f"Error copying file from {src} to {dst}: {str(e)}"
|
||||
logging.error(error_msg)
|
||||
return False
|
||||
|
||||
@staticmethod
|
||||
def move_file(src: str, dst: str) -> bool:
|
||||
"""
|
||||
Move a file from source to destination.
|
||||
|
||||
Args:
|
||||
src: Source file path
|
||||
dst: Destination file path
|
||||
|
||||
Returns:
|
||||
bool: True if successful, False otherwise
|
||||
"""
|
||||
try:
|
||||
# Create destination directory if it doesn't exist
|
||||
os.makedirs(os.path.dirname(dst), exist_ok=True)
|
||||
shutil.move(src, dst)
|
||||
return True
|
||||
except Exception as e:
|
||||
error_msg = f"Error moving file from {src} to {dst}: {str(e)}"
|
||||
logging.error(error_msg)
|
||||
return False
|
||||
|
||||
@staticmethod
|
||||
def delete_file(filepath: str) -> bool:
|
||||
"""
|
||||
Delete a file.
|
||||
|
||||
Args:
|
||||
filepath: Path to the file
|
||||
|
||||
Returns:
|
||||
bool: True if successful, False otherwise
|
||||
"""
|
||||
try:
|
||||
os.remove(filepath)
|
||||
return True
|
||||
except Exception as e:
|
||||
error_msg = f"Error deleting file {filepath}: {str(e)}"
|
||||
logging.error(error_msg)
|
||||
return False
|
||||
|
||||
# Create instance for direct function access
|
||||
_file_tools = FileTools()
|
||||
read_file = _file_tools.read_file
|
||||
write_file = _file_tools.write_file
|
||||
list_files = _file_tools.list_files
|
||||
get_file_info = _file_tools.get_file_info
|
||||
copy_file = _file_tools.copy_file
|
||||
move_file = _file_tools.move_file
|
||||
delete_file = _file_tools.delete_file
|
||||
|
||||
if __name__ == "__main__":
|
||||
# Example usage
|
||||
print("\n==================================================")
|
||||
print("FileTools Demonstration")
|
||||
print("==================================================\n")
|
||||
|
||||
# Create a test directory
|
||||
test_dir = os.path.join(os.getcwd(), "test_files")
|
||||
os.makedirs(test_dir, exist_ok=True)
|
||||
|
||||
# Create test files
|
||||
test_file = os.path.join(test_dir, "test_file.txt")
|
||||
test_content = "Hello, this is a test file!"
|
||||
|
||||
print("1. Writing to file")
|
||||
print("------------------------------")
|
||||
success = write_file(test_file, test_content)
|
||||
print(f"Write successful: {success}\n")
|
||||
|
||||
print("2. Reading from file")
|
||||
print("------------------------------")
|
||||
content = read_file(test_file)
|
||||
print(f"Content: {content}\n")
|
||||
|
||||
print("3. File Information")
|
||||
print("------------------------------")
|
||||
info = get_file_info(test_file)
|
||||
print(json.dumps(info, indent=2))
|
||||
print()
|
||||
|
||||
print("4. Listing Files")
|
||||
print("------------------------------")
|
||||
files = list_files(test_dir, "*.txt")
|
||||
for file in files:
|
||||
print(f"Found: {file['name']} ({file['size']} bytes)")
|
||||
print()
|
||||
|
||||
print("5. Copying File")
|
||||
print("------------------------------")
|
||||
copy_file_path = os.path.join(test_dir, "test_file_copy.txt")
|
||||
copy_success = copy_file(test_file, copy_file_path)
|
||||
print(f"Copy successful: {copy_success}\n")
|
||||
|
||||
print("6. Moving File")
|
||||
print("------------------------------")
|
||||
move_file_path = os.path.join(test_dir, "test_file_moved.txt")
|
||||
move_success = move_file(copy_file_path, move_file_path)
|
||||
print(f"Move successful: {move_success}\n")
|
||||
|
||||
print("7. Deleting Files")
|
||||
print("------------------------------")
|
||||
delete_success = delete_file(test_file)
|
||||
print(f"Delete original successful: {delete_success}")
|
||||
delete_success = delete_file(move_file_path)
|
||||
print(f"Delete moved file successful: {delete_success}\n")
|
||||
|
||||
# Clean up test directory
|
||||
try:
|
||||
shutil.rmtree(test_dir)
|
||||
print("Test directory cleaned up successfully")
|
||||
except Exception as e:
|
||||
print(f"Error cleaning up test directory: {str(e)}")
|
||||
|
||||
print("\n==================================================")
|
||||
print("Demonstration Complete")
|
||||
print("==================================================")
|
||||
@@ -0,0 +1,515 @@
|
||||
"""Tools for working with JSON files.
|
||||
|
||||
Usage:
|
||||
from praisonaiagents.tools import json_tools
|
||||
data = json_tools.read_json("data.json")
|
||||
|
||||
or
|
||||
from praisonaiagents.tools import read_json, write_json, merge_json
|
||||
data = read_json("data.json")
|
||||
"""
|
||||
|
||||
import logging
|
||||
from typing import List, Dict, Union, Optional, Any, Tuple
|
||||
from importlib import util
|
||||
import json
|
||||
from datetime import datetime
|
||||
|
||||
class JSONTools:
|
||||
"""Tools for working with JSON files."""
|
||||
|
||||
def __init__(self):
|
||||
"""Initialize JSONTools."""
|
||||
pass
|
||||
|
||||
def read_json(
|
||||
self,
|
||||
filepath: str,
|
||||
encoding: str = 'utf-8',
|
||||
validate_schema: Optional[Dict[str, Any]] = None
|
||||
) -> Dict[str, Any]:
|
||||
"""Read a JSON file with optional schema validation.
|
||||
|
||||
Args:
|
||||
filepath: Path to JSON file
|
||||
encoding: File encoding
|
||||
validate_schema: Optional JSON schema for validation
|
||||
|
||||
Returns:
|
||||
Dict with JSON data
|
||||
"""
|
||||
try:
|
||||
# Read JSON file
|
||||
with open(filepath, 'r', encoding=encoding) as f:
|
||||
data = json.load(f)
|
||||
|
||||
# Validate against schema if provided
|
||||
if validate_schema:
|
||||
if util.find_spec('jsonschema') is None:
|
||||
error_msg = "jsonschema package is not available. Please install it using: pip install jsonschema"
|
||||
logging.error(error_msg)
|
||||
return {"error": error_msg}
|
||||
import jsonschema
|
||||
try:
|
||||
jsonschema.validate(instance=data, schema=validate_schema)
|
||||
except jsonschema.exceptions.ValidationError as e:
|
||||
error_msg = f"JSON validation failed: {str(e)}"
|
||||
logging.error(error_msg)
|
||||
return {"error": error_msg}
|
||||
|
||||
return data
|
||||
|
||||
except Exception as e:
|
||||
error_msg = f"Error reading JSON file {filepath}: {str(e)}"
|
||||
logging.error(error_msg)
|
||||
return {"error": error_msg}
|
||||
|
||||
def write_json(
|
||||
self,
|
||||
data: Union[Dict[str, Any], List[Any]],
|
||||
filepath: str,
|
||||
encoding: str = 'utf-8',
|
||||
indent: int = 2,
|
||||
sort_keys: bool = False,
|
||||
ensure_ascii: bool = False
|
||||
) -> bool:
|
||||
"""Write data to a JSON file.
|
||||
|
||||
Args:
|
||||
data: Data to write
|
||||
filepath: Output file path
|
||||
encoding: File encoding
|
||||
indent: Number of spaces for indentation
|
||||
sort_keys: Sort dictionary keys
|
||||
ensure_ascii: Escape non-ASCII characters
|
||||
|
||||
Returns:
|
||||
True if successful, False otherwise
|
||||
"""
|
||||
try:
|
||||
with open(filepath, 'w', encoding=encoding) as f:
|
||||
json.dump(
|
||||
data,
|
||||
f,
|
||||
indent=indent,
|
||||
sort_keys=sort_keys,
|
||||
ensure_ascii=ensure_ascii
|
||||
)
|
||||
return True
|
||||
except Exception as e:
|
||||
error_msg = f"Error writing JSON file {filepath}: {str(e)}"
|
||||
logging.error(error_msg)
|
||||
return False
|
||||
|
||||
def merge_json(
|
||||
self,
|
||||
files: List[str],
|
||||
output_file: str,
|
||||
merge_arrays: bool = True,
|
||||
overwrite_duplicates: bool = True
|
||||
) -> bool:
|
||||
"""Merge multiple JSON files.
|
||||
|
||||
Args:
|
||||
files: List of JSON files to merge
|
||||
output_file: Output file path
|
||||
merge_arrays: Merge arrays instead of overwriting
|
||||
overwrite_duplicates: Overwrite duplicate keys
|
||||
|
||||
Returns:
|
||||
True if successful, False otherwise
|
||||
"""
|
||||
try:
|
||||
if len(files) < 2:
|
||||
raise ValueError("At least two files are required for merging")
|
||||
|
||||
# Read first file
|
||||
result = self.read_json(files[0])
|
||||
|
||||
# Merge with remaining files
|
||||
for file in files[1:]:
|
||||
data = self.read_json(file)
|
||||
result = self._deep_merge(
|
||||
result,
|
||||
data,
|
||||
merge_arrays=merge_arrays,
|
||||
overwrite_duplicates=overwrite_duplicates
|
||||
)
|
||||
|
||||
# Write merged result
|
||||
return self.write_json(result, output_file)
|
||||
except Exception as e:
|
||||
error_msg = f"Error merging JSON files: {str(e)}"
|
||||
logging.error(error_msg)
|
||||
return False
|
||||
|
||||
def _deep_merge(
|
||||
self,
|
||||
dict1: Dict[str, Any],
|
||||
dict2: Dict[str, Any],
|
||||
merge_arrays: bool = True,
|
||||
overwrite_duplicates: bool = True
|
||||
) -> Dict[str, Any]:
|
||||
"""Deep merge two dictionaries.
|
||||
|
||||
Args:
|
||||
dict1: First dictionary
|
||||
dict2: Second dictionary
|
||||
merge_arrays: Merge arrays instead of overwriting
|
||||
overwrite_duplicates: Overwrite duplicate keys
|
||||
|
||||
Returns:
|
||||
Merged dictionary
|
||||
"""
|
||||
result = dict1.copy()
|
||||
|
||||
for key, value in dict2.items():
|
||||
if key in result:
|
||||
if isinstance(result[key], dict) and isinstance(value, dict):
|
||||
result[key] = self._deep_merge(
|
||||
result[key],
|
||||
value,
|
||||
merge_arrays=merge_arrays,
|
||||
overwrite_duplicates=overwrite_duplicates
|
||||
)
|
||||
elif isinstance(result[key], list) and isinstance(value, list):
|
||||
if merge_arrays:
|
||||
result[key].extend(value)
|
||||
elif overwrite_duplicates:
|
||||
result[key] = value
|
||||
elif overwrite_duplicates:
|
||||
result[key] = value
|
||||
else:
|
||||
result[key] = value
|
||||
|
||||
return result
|
||||
|
||||
def validate_json(
|
||||
self,
|
||||
data: Union[Dict[str, Any], str],
|
||||
schema: Dict[str, Any]
|
||||
) -> Tuple[bool, Optional[str]]:
|
||||
"""Validate JSON data against a schema.
|
||||
|
||||
Args:
|
||||
data: JSON data or filepath
|
||||
schema: JSON schema for validation
|
||||
|
||||
Returns:
|
||||
Tuple of (is_valid, error_message)
|
||||
"""
|
||||
try:
|
||||
if util.find_spec('jsonschema') is None:
|
||||
error_msg = "jsonschema package is not available. Please install it using: pip install jsonschema"
|
||||
logging.error(error_msg)
|
||||
return False, error_msg
|
||||
import jsonschema
|
||||
|
||||
# Load data if filepath provided
|
||||
if isinstance(data, str):
|
||||
with open(data, 'r') as f:
|
||||
data = json.load(f)
|
||||
|
||||
jsonschema.validate(instance=data, schema=schema)
|
||||
return True, None
|
||||
|
||||
except jsonschema.exceptions.ValidationError as e:
|
||||
error_msg = f"JSON validation failed: {str(e)}"
|
||||
logging.error(error_msg)
|
||||
return False, error_msg
|
||||
|
||||
except Exception as e:
|
||||
error_msg = f"Error validating JSON: {str(e)}"
|
||||
logging.error(error_msg)
|
||||
return False, error_msg
|
||||
|
||||
def analyze_json(
|
||||
self,
|
||||
data: Union[Dict[str, Any], str],
|
||||
max_depth: int = 10
|
||||
) -> Dict[str, Any]:
|
||||
"""Analyze JSON data structure.
|
||||
|
||||
Args:
|
||||
data: JSON data or filepath
|
||||
max_depth: Maximum depth to analyze
|
||||
|
||||
Returns:
|
||||
Dict with analysis results
|
||||
"""
|
||||
try:
|
||||
# Load data if filepath provided
|
||||
if isinstance(data, str):
|
||||
data = self.read_json(data)
|
||||
|
||||
def analyze_value(value: Any, depth: int = 0) -> Dict[str, Any]:
|
||||
if depth >= max_depth:
|
||||
return {'type': 'max_depth_reached'}
|
||||
|
||||
result = {'type': type(value).__name__}
|
||||
|
||||
if isinstance(value, dict):
|
||||
result['size'] = len(value)
|
||||
result['keys'] = list(value.keys())
|
||||
if depth < max_depth - 1:
|
||||
result['children'] = {
|
||||
k: analyze_value(v, depth + 1)
|
||||
for k, v in value.items()
|
||||
}
|
||||
|
||||
elif isinstance(value, list):
|
||||
result['length'] = len(value)
|
||||
if value:
|
||||
result['element_types'] = list(set(
|
||||
type(x).__name__ for x in value
|
||||
))
|
||||
if depth < max_depth - 1:
|
||||
result['sample_elements'] = [
|
||||
analyze_value(x, depth + 1)
|
||||
for x in value[:5]
|
||||
]
|
||||
|
||||
elif isinstance(value, (int, float)):
|
||||
result.update({
|
||||
'value': value,
|
||||
'is_integer': isinstance(value, int)
|
||||
})
|
||||
|
||||
elif isinstance(value, str):
|
||||
result.update({
|
||||
'length': len(value),
|
||||
'sample': value[:100] if len(value) > 100 else value
|
||||
})
|
||||
|
||||
return result
|
||||
|
||||
return {
|
||||
'analysis_time': datetime.now().isoformat(),
|
||||
'structure': analyze_value(data)
|
||||
}
|
||||
except Exception as e:
|
||||
error_msg = f"Error analyzing JSON: {str(e)}"
|
||||
logging.error(error_msg)
|
||||
return {}
|
||||
|
||||
def transform_json(
|
||||
self,
|
||||
data: Union[Dict[str, Any], str],
|
||||
transformations: List[Dict[str, Any]]
|
||||
) -> Dict[str, Any]:
|
||||
"""Transform JSON data using a list of operations.
|
||||
|
||||
Args:
|
||||
data: JSON data or filepath
|
||||
transformations: List of transformation operations
|
||||
|
||||
Returns:
|
||||
Transformed JSON data
|
||||
"""
|
||||
try:
|
||||
# Load data if filepath provided
|
||||
if isinstance(data, str):
|
||||
data = self.read_json(data)
|
||||
|
||||
result = data.copy()
|
||||
|
||||
for transform in transformations:
|
||||
op = transform.get('operation')
|
||||
path = transform.get('path', '').split('.')
|
||||
value = transform.get('value')
|
||||
|
||||
if op == 'set':
|
||||
self._set_value(result, path, value)
|
||||
elif op == 'delete':
|
||||
self._delete_value(result, path)
|
||||
elif op == 'rename':
|
||||
old_path = path
|
||||
new_path = value.split('.')
|
||||
self._rename_key(result, old_path, new_path)
|
||||
elif op == 'move':
|
||||
old_path = path
|
||||
new_path = value.split('.')
|
||||
self._move_value(result, old_path, new_path)
|
||||
|
||||
return result
|
||||
except Exception as e:
|
||||
error_msg = f"Error transforming JSON: {str(e)}"
|
||||
logging.error(error_msg)
|
||||
return data
|
||||
|
||||
def _set_value(self, data: Dict[str, Any], path: List[str], value: Any):
|
||||
"""Set a value at the specified path."""
|
||||
current = data
|
||||
for key in path[:-1]:
|
||||
if key not in current:
|
||||
current[key] = {}
|
||||
current = current[key]
|
||||
current[path[-1]] = value
|
||||
|
||||
def _delete_value(self, data: Dict[str, Any], path: List[str]):
|
||||
"""Delete a value at the specified path."""
|
||||
current = data
|
||||
for key in path[:-1]:
|
||||
if key not in current:
|
||||
return
|
||||
current = current[key]
|
||||
if path[-1] in current:
|
||||
del current[path[-1]]
|
||||
|
||||
def _rename_key(
|
||||
self,
|
||||
data: Dict[str, Any],
|
||||
old_path: List[str],
|
||||
new_path: List[str]
|
||||
):
|
||||
"""Rename a key at the specified path."""
|
||||
value = self._get_value(data, old_path)
|
||||
if value is not None:
|
||||
self._delete_value(data, old_path)
|
||||
self._set_value(data, new_path, value)
|
||||
|
||||
def _move_value(
|
||||
self,
|
||||
data: Dict[str, Any],
|
||||
old_path: List[str],
|
||||
new_path: List[str]
|
||||
):
|
||||
"""Move a value from one path to another."""
|
||||
self._rename_key(data, old_path, new_path)
|
||||
|
||||
def _get_value(
|
||||
self,
|
||||
data: Dict[str, Any],
|
||||
path: List[str]
|
||||
) -> Optional[Any]:
|
||||
"""Get a value at the specified path."""
|
||||
current = data
|
||||
for key in path:
|
||||
if key not in current:
|
||||
return None
|
||||
current = current[key]
|
||||
return current
|
||||
|
||||
# Create instance for direct function access
|
||||
_json_tools = JSONTools()
|
||||
read_json = _json_tools.read_json
|
||||
write_json = _json_tools.write_json
|
||||
merge_json = _json_tools.merge_json
|
||||
validate_json = _json_tools.validate_json
|
||||
analyze_json = _json_tools.analyze_json
|
||||
transform_json = _json_tools.transform_json
|
||||
|
||||
if __name__ == "__main__":
|
||||
# Example usage
|
||||
print("\n==================================================")
|
||||
print("JSONTools Demonstration")
|
||||
print("==================================================\n")
|
||||
|
||||
# Sample data
|
||||
data1 = {
|
||||
'id': 1,
|
||||
'name': 'Alice',
|
||||
'scores': [95, 87, 92],
|
||||
'details': {
|
||||
'age': 25,
|
||||
'city': 'New York'
|
||||
}
|
||||
}
|
||||
|
||||
data2 = {
|
||||
'id': 2,
|
||||
'name': 'Bob',
|
||||
'scores': [88, 90, 85],
|
||||
'details': {
|
||||
'age': 30,
|
||||
'country': 'USA'
|
||||
}
|
||||
}
|
||||
|
||||
# 1. Write JSON files
|
||||
print("1. Writing JSON Files")
|
||||
print("------------------------------")
|
||||
success = write_json(data1, 'test1.json')
|
||||
print(f"First file written: {success}")
|
||||
success = write_json(data2, 'test2.json')
|
||||
print(f"Second file written: {success}")
|
||||
print()
|
||||
|
||||
# 2. Read JSON file
|
||||
print("2. Reading JSON File")
|
||||
print("------------------------------")
|
||||
data = read_json('test1.json')
|
||||
print("Contents of test1.json:")
|
||||
print(json.dumps(data, indent=2))
|
||||
print()
|
||||
|
||||
# 3. Merge JSON files
|
||||
print("3. Merging JSON Files")
|
||||
print("------------------------------")
|
||||
success = merge_json(['test1.json', 'test2.json'], 'merged.json')
|
||||
print(f"Files merged: {success}")
|
||||
if success:
|
||||
print("Merged contents:")
|
||||
print(json.dumps(read_json('merged.json'), indent=2))
|
||||
print()
|
||||
|
||||
# 4. Validate JSON
|
||||
print("4. Validating JSON")
|
||||
print("------------------------------")
|
||||
schema = {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'id': {'type': 'integer'},
|
||||
'name': {'type': 'string'},
|
||||
'scores': {
|
||||
'type': 'array',
|
||||
'items': {'type': 'number'}
|
||||
},
|
||||
'details': {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'age': {'type': 'integer'},
|
||||
'city': {'type': 'string'}
|
||||
}
|
||||
}
|
||||
},
|
||||
'required': ['id', 'name']
|
||||
}
|
||||
|
||||
is_valid, error = validate_json(data1, schema)
|
||||
print(f"Validation result: {is_valid}")
|
||||
if error:
|
||||
print(f"Validation error: {error}")
|
||||
print()
|
||||
|
||||
# 5. Analyze JSON
|
||||
print("5. Analyzing JSON")
|
||||
print("------------------------------")
|
||||
analysis = analyze_json(data1)
|
||||
print("Analysis results:")
|
||||
print(json.dumps(analysis, indent=2))
|
||||
print()
|
||||
|
||||
# 6. Transform JSON
|
||||
print("6. Transforming JSON")
|
||||
print("------------------------------")
|
||||
transformations = [
|
||||
{
|
||||
'operation': 'set',
|
||||
'path': 'details.status',
|
||||
'value': 'active'
|
||||
},
|
||||
{
|
||||
'operation': 'rename',
|
||||
'path': 'details.city',
|
||||
'value': 'details.location'
|
||||
}
|
||||
]
|
||||
|
||||
transformed = transform_json(data1, transformations)
|
||||
print("Transformed data:")
|
||||
print(json.dumps(transformed, indent=2))
|
||||
|
||||
print("\n==================================================")
|
||||
print("Demonstration Complete")
|
||||
print("==================================================")
|
||||
@@ -0,0 +1,354 @@
|
||||
"""Newspaper tools for scraping and parsing news articles.
|
||||
|
||||
Usage:
|
||||
from praisonaiagents.tools import newspaper_tools
|
||||
article = newspaper_tools.get_article("https://example.com/article")
|
||||
sources = newspaper_tools.get_news_sources("technology")
|
||||
articles = newspaper_tools.get_articles_from_source("https://techcrunch.com")
|
||||
|
||||
or
|
||||
from praisonaiagents.tools import get_article, get_news_sources
|
||||
article = get_article("https://example.com/article")
|
||||
"""
|
||||
|
||||
import logging
|
||||
from typing import List, Dict, Union, Optional, Any
|
||||
from importlib import util
|
||||
import json
|
||||
from urllib.parse import urlparse
|
||||
|
||||
# Predefined list of popular news sources
|
||||
POPULAR_NEWS_SOURCES = {
|
||||
'technology': [
|
||||
'https://techcrunch.com',
|
||||
'https://www.theverge.com',
|
||||
'https://www.wired.com',
|
||||
'https://www.engadget.com',
|
||||
'https://arstechnica.com'
|
||||
],
|
||||
'business': [
|
||||
'https://www.bloomberg.com',
|
||||
'https://www.reuters.com',
|
||||
'https://www.wsj.com',
|
||||
'https://www.ft.com',
|
||||
'https://www.cnbc.com'
|
||||
],
|
||||
'general': [
|
||||
'https://www.nytimes.com',
|
||||
'https://www.theguardian.com',
|
||||
'https://www.washingtonpost.com',
|
||||
'https://www.bbc.com',
|
||||
'https://www.cnn.com'
|
||||
],
|
||||
'sports': [
|
||||
'https://www.espn.com',
|
||||
'https://sports.yahoo.com',
|
||||
'https://www.cbssports.com',
|
||||
'https://www.skysports.com',
|
||||
'https://www.bleacherreport.com'
|
||||
],
|
||||
'entertainment': [
|
||||
'https://variety.com',
|
||||
'https://www.hollywoodreporter.com',
|
||||
'https://www.ew.com',
|
||||
'https://www.deadline.com',
|
||||
'https://www.imdb.com/news'
|
||||
],
|
||||
'science': [
|
||||
'https://www.scientificamerican.com',
|
||||
'https://www.sciencedaily.com',
|
||||
'https://www.newscientist.com',
|
||||
'https://www.sciencemag.org',
|
||||
'https://www.nature.com/news'
|
||||
]
|
||||
}
|
||||
|
||||
class NewspaperTools:
|
||||
"""Tools for scraping and parsing news articles."""
|
||||
|
||||
def __init__(self):
|
||||
"""Initialize NewspaperTools and check for newspaper package."""
|
||||
self._check_newspaper()
|
||||
|
||||
def _check_newspaper(self):
|
||||
"""Check if newspaper package is installed."""
|
||||
if util.find_spec("newspaper") is None:
|
||||
raise ImportError("newspaper3k package is not available. Please install it using: pip install newspaper3k")
|
||||
global newspaper
|
||||
import newspaper
|
||||
|
||||
def get_article(
|
||||
self,
|
||||
url: str,
|
||||
language: str = 'en'
|
||||
) -> Dict[str, Any]:
|
||||
"""
|
||||
Extract and parse a news article from a URL.
|
||||
|
||||
Args:
|
||||
url: URL of the article
|
||||
language: Language code (e.g., 'en' for English)
|
||||
|
||||
Returns:
|
||||
Dict: Article information including title, text, authors, etc.
|
||||
"""
|
||||
try:
|
||||
from newspaper import Article, Config
|
||||
|
||||
# Configure article download
|
||||
config = Config()
|
||||
config.browser_user_agent = 'Mozilla/5.0'
|
||||
config.language = language
|
||||
|
||||
# Download and parse article
|
||||
article = Article(url, config=config)
|
||||
article.download()
|
||||
article.parse()
|
||||
|
||||
# Try to extract additional information
|
||||
try:
|
||||
article.nlp()
|
||||
except Exception as e:
|
||||
logging.warning(f"NLP processing failed: {str(e)}")
|
||||
|
||||
# Build response
|
||||
response = {
|
||||
"url": url,
|
||||
"title": article.title,
|
||||
"text": article.text,
|
||||
"authors": article.authors,
|
||||
"publish_date": article.publish_date.isoformat() if article.publish_date else None,
|
||||
"top_image": article.top_image,
|
||||
"images": list(article.images),
|
||||
"movies": list(article.movies),
|
||||
"source_domain": urlparse(url).netloc,
|
||||
}
|
||||
|
||||
# Add NLP results if available
|
||||
if hasattr(article, 'keywords') and article.keywords:
|
||||
response["keywords"] = article.keywords
|
||||
if hasattr(article, 'summary') and article.summary:
|
||||
response["summary"] = article.summary
|
||||
|
||||
return response
|
||||
except Exception as e:
|
||||
error_msg = f"Error extracting article from {url}: {str(e)}"
|
||||
logging.error(error_msg)
|
||||
return {"error": error_msg}
|
||||
|
||||
def get_news_sources(
|
||||
self,
|
||||
category: Optional[str] = None,
|
||||
language: str = 'en',
|
||||
country: Optional[str] = None
|
||||
) -> Union[List[Dict[str, str]], Dict[str, str]]:
|
||||
"""
|
||||
Get a list of news sources, optionally filtered by category.
|
||||
|
||||
Args:
|
||||
category: Category to filter by (e.g., 'technology', 'sports')
|
||||
language: Language code
|
||||
country: Country code
|
||||
|
||||
Returns:
|
||||
List[Dict] or Dict: List of news sources or error dict
|
||||
"""
|
||||
try:
|
||||
sources = []
|
||||
|
||||
# Get sources for the specified category or all categories
|
||||
if category:
|
||||
category = category.lower()
|
||||
if category in POPULAR_NEWS_SOURCES:
|
||||
urls = POPULAR_NEWS_SOURCES[category]
|
||||
else:
|
||||
urls = []
|
||||
for cat_urls in POPULAR_NEWS_SOURCES.values():
|
||||
urls.extend(cat_urls)
|
||||
else:
|
||||
urls = []
|
||||
for cat_urls in POPULAR_NEWS_SOURCES.values():
|
||||
urls.extend(cat_urls)
|
||||
|
||||
# Create source objects
|
||||
for url in urls:
|
||||
domain = urlparse(url).netloc
|
||||
source = {
|
||||
"url": url,
|
||||
"domain": domain,
|
||||
"name": domain.replace("www.", "").split(".")[0].title(),
|
||||
"category": category if category else "general"
|
||||
}
|
||||
sources.append(source)
|
||||
|
||||
return sources
|
||||
except Exception as e:
|
||||
error_msg = f"Error getting news sources: {str(e)}"
|
||||
logging.error(error_msg)
|
||||
return {"error": error_msg}
|
||||
|
||||
def get_articles_from_source(
|
||||
self,
|
||||
source_url: str,
|
||||
limit: int = 10,
|
||||
language: str = 'en'
|
||||
) -> Union[List[Dict[str, Any]], Dict[str, str]]:
|
||||
"""
|
||||
Get recent articles from a news source.
|
||||
|
||||
Args:
|
||||
source_url: URL of the news source
|
||||
limit: Maximum number of articles to return
|
||||
language: Language code
|
||||
|
||||
Returns:
|
||||
List[Dict] or Dict: List of articles or error dict
|
||||
"""
|
||||
try:
|
||||
from newspaper import Source, Config
|
||||
|
||||
# Configure source scraping
|
||||
config = Config()
|
||||
config.browser_user_agent = 'Mozilla/5.0'
|
||||
config.language = language
|
||||
config.fetch_images = False # Speed up processing
|
||||
|
||||
# Build news source
|
||||
source = Source(source_url, config=config)
|
||||
source.build()
|
||||
|
||||
# Get articles
|
||||
articles = []
|
||||
for article_url in source.article_urls()[:limit]:
|
||||
try:
|
||||
article = self.get_article(article_url, language)
|
||||
if "error" not in article:
|
||||
articles.append(article)
|
||||
except Exception as e:
|
||||
logging.warning(f"Error processing article {article_url}: {str(e)}")
|
||||
continue
|
||||
|
||||
if len(articles) >= limit:
|
||||
break
|
||||
|
||||
return articles
|
||||
except Exception as e:
|
||||
error_msg = f"Error getting articles from {source_url}: {str(e)}"
|
||||
logging.error(error_msg)
|
||||
return {"error": error_msg}
|
||||
|
||||
def get_trending_topics(
|
||||
self,
|
||||
sources: Optional[List[str]] = None,
|
||||
limit: int = 10,
|
||||
language: str = 'en'
|
||||
) -> Union[List[str], Dict[str, str]]:
|
||||
"""
|
||||
Get trending topics across news sources.
|
||||
|
||||
Args:
|
||||
sources: List of source URLs to analyze
|
||||
limit: Maximum number of trending topics to return
|
||||
language: Language code
|
||||
|
||||
Returns:
|
||||
List[str] or Dict: List of trending topics or error dict
|
||||
"""
|
||||
try:
|
||||
from collections import Counter
|
||||
|
||||
# Use default sources if none provided
|
||||
if not sources:
|
||||
sources_data = self.get_news_sources(language=language)
|
||||
if isinstance(sources_data, dict) and "error" in sources_data:
|
||||
return sources_data
|
||||
sources = [s["url"] for s in sources_data[:5]] # Use top 5 sources
|
||||
|
||||
# Collect keywords from articles
|
||||
all_keywords = []
|
||||
for source_url in sources:
|
||||
try:
|
||||
articles = self.get_articles_from_source(source_url, limit=5, language=language)
|
||||
if isinstance(articles, list):
|
||||
for article in articles:
|
||||
if "keywords" in article:
|
||||
all_keywords.extend(article["keywords"])
|
||||
except Exception as e:
|
||||
logging.warning(f"Error processing source {source_url}: {str(e)}")
|
||||
continue
|
||||
|
||||
# Get most common keywords
|
||||
trending = Counter(all_keywords).most_common(limit)
|
||||
return [topic for topic, count in trending]
|
||||
except Exception as e:
|
||||
error_msg = f"Error getting trending topics: {str(e)}"
|
||||
logging.error(error_msg)
|
||||
return {"error": error_msg}
|
||||
|
||||
# Create instance for direct function access
|
||||
_newspaper_tools = NewspaperTools()
|
||||
get_article = _newspaper_tools.get_article
|
||||
get_news_sources = _newspaper_tools.get_news_sources
|
||||
get_articles_from_source = _newspaper_tools.get_articles_from_source
|
||||
get_trending_topics = _newspaper_tools.get_trending_topics
|
||||
|
||||
if __name__ == "__main__":
|
||||
# Example usage
|
||||
print("\n==================================================")
|
||||
print("NewspaperTools Demonstration")
|
||||
print("==================================================\n")
|
||||
|
||||
# 1. Get news sources
|
||||
print("1. Getting News Sources")
|
||||
print("------------------------------")
|
||||
tech_sources = get_news_sources("technology")
|
||||
print("Technology news sources:")
|
||||
if isinstance(tech_sources, list):
|
||||
print(json.dumps(tech_sources[:3], indent=2)) # Show first 3 sources
|
||||
else:
|
||||
print(tech_sources) # Show error
|
||||
print()
|
||||
|
||||
if isinstance(tech_sources, list) and tech_sources:
|
||||
source_url = tech_sources[0]["url"]
|
||||
|
||||
# 2. Get articles from a source
|
||||
print("2. Getting Articles from Source")
|
||||
print("------------------------------")
|
||||
articles = get_articles_from_source(source_url, limit=2)
|
||||
print(f"Articles from {source_url}:")
|
||||
if isinstance(articles, list):
|
||||
for article in articles:
|
||||
print(f"- {article['title']}")
|
||||
if "summary" in article:
|
||||
print(f" Summary: {article['summary'][:200]}...")
|
||||
else:
|
||||
print(articles) # Show error
|
||||
print()
|
||||
|
||||
# 3. Get a single article
|
||||
print("3. Getting Single Article")
|
||||
print("------------------------------")
|
||||
if isinstance(articles, list) and articles:
|
||||
article_url = articles[0]["url"]
|
||||
article = get_article(article_url)
|
||||
if "error" not in article:
|
||||
print(f"Article: {article['title']}")
|
||||
if "summary" in article:
|
||||
print(f"Summary: {article['summary'][:200]}...")
|
||||
print(f"Authors: {', '.join(article['authors'])}")
|
||||
print(f"Date: {article['publish_date']}")
|
||||
else:
|
||||
print(article) # Show error
|
||||
print()
|
||||
|
||||
# 4. Get trending topics
|
||||
print("4. Getting Trending Topics")
|
||||
print("------------------------------")
|
||||
topics = get_trending_topics([source_url], limit=5)
|
||||
print("Trending topics:")
|
||||
print(json.dumps(topics, indent=2))
|
||||
|
||||
print("\n==================================================")
|
||||
print("Demonstration Complete")
|
||||
print("==================================================")
|
||||
@@ -0,0 +1,326 @@
|
||||
"""Pandas tools for data manipulation and analysis.
|
||||
|
||||
Usage:
|
||||
from praisonaiagents.tools import pandas_tools
|
||||
df = pandas_tools.read_csv("data.csv")
|
||||
df = pandas_tools.filter_data(df, "column > 5")
|
||||
summary = pandas_tools.get_summary(df)
|
||||
|
||||
or
|
||||
from praisonaiagents.tools import read_csv, filter_data, get_summary
|
||||
df = read_csv("data.csv")
|
||||
"""
|
||||
|
||||
import logging
|
||||
from typing import List, Dict, Union, Optional, Any
|
||||
from importlib import util
|
||||
import json
|
||||
import os
|
||||
|
||||
# Import pandas for type hints, but don't use it until we check it's installed
|
||||
if util.find_spec("pandas") is not None:
|
||||
import pandas as pd
|
||||
import numpy as np
|
||||
else:
|
||||
# Create a placeholder for type hints
|
||||
class pd:
|
||||
DataFrame = None
|
||||
|
||||
def _convert_to_serializable(obj: Any) -> Any:
|
||||
"""Convert numpy/pandas types to JSON serializable Python types."""
|
||||
if isinstance(obj, (np.integer, np.floating)):
|
||||
return obj.item()
|
||||
elif isinstance(obj, np.ndarray):
|
||||
return obj.tolist()
|
||||
elif isinstance(obj, pd.Series):
|
||||
return obj.to_list()
|
||||
elif isinstance(obj, pd.DataFrame):
|
||||
return obj.to_dict(orient='records')
|
||||
return obj
|
||||
|
||||
class PandasTools:
|
||||
"""Tools for data manipulation and analysis using pandas."""
|
||||
|
||||
def __init__(self):
|
||||
"""Initialize PandasTools and check for pandas installation."""
|
||||
self._check_pandas()
|
||||
|
||||
def _check_pandas(self):
|
||||
"""Check if pandas is installed."""
|
||||
if util.find_spec("pandas") is None:
|
||||
raise ImportError("pandas is not available. Please install it using: pip install pandas")
|
||||
global pd, np
|
||||
import pandas as pd
|
||||
import numpy as np
|
||||
|
||||
def read_csv(self, filepath: str, **kwargs) -> Union[pd.DataFrame, Dict[str, str]]:
|
||||
"""
|
||||
Read a CSV file into a pandas DataFrame.
|
||||
|
||||
Args:
|
||||
filepath: Path to the CSV file
|
||||
**kwargs: Additional arguments to pass to pd.read_csv()
|
||||
|
||||
Returns:
|
||||
pd.DataFrame or Dict: DataFrame if successful, error dict if failed
|
||||
"""
|
||||
try:
|
||||
return pd.read_csv(filepath, **kwargs)
|
||||
except Exception as e:
|
||||
error_msg = f"Error reading CSV file {filepath}: {str(e)}"
|
||||
logging.error(error_msg)
|
||||
return {"error": error_msg}
|
||||
|
||||
def read_excel(self, filepath: str, **kwargs) -> Union[pd.DataFrame, Dict[str, str]]:
|
||||
"""
|
||||
Read an Excel file into a pandas DataFrame.
|
||||
|
||||
Args:
|
||||
filepath: Path to the Excel file
|
||||
**kwargs: Additional arguments to pass to pd.read_excel()
|
||||
|
||||
Returns:
|
||||
pd.DataFrame or Dict: DataFrame if successful, error dict if failed
|
||||
"""
|
||||
try:
|
||||
return pd.read_excel(filepath, **kwargs)
|
||||
except Exception as e:
|
||||
error_msg = f"Error reading Excel file {filepath}: {str(e)}"
|
||||
logging.error(error_msg)
|
||||
return {"error": error_msg}
|
||||
|
||||
def write_csv(self, df: pd.DataFrame, filepath: str, **kwargs) -> bool:
|
||||
"""
|
||||
Write DataFrame to a CSV file.
|
||||
|
||||
Args:
|
||||
df: DataFrame to write
|
||||
filepath: Output file path
|
||||
**kwargs: Additional arguments to pass to df.to_csv()
|
||||
|
||||
Returns:
|
||||
bool: True if successful, False otherwise
|
||||
"""
|
||||
try:
|
||||
os.makedirs(os.path.dirname(filepath), exist_ok=True)
|
||||
df.to_csv(filepath, **kwargs)
|
||||
return True
|
||||
except Exception as e:
|
||||
error_msg = f"Error writing CSV file {filepath}: {str(e)}"
|
||||
logging.error(error_msg)
|
||||
return False
|
||||
|
||||
def write_excel(self, df: pd.DataFrame, filepath: str, **kwargs) -> bool:
|
||||
"""
|
||||
Write DataFrame to an Excel file.
|
||||
|
||||
Args:
|
||||
df: DataFrame to write
|
||||
filepath: Output file path
|
||||
**kwargs: Additional arguments to pass to df.to_excel()
|
||||
|
||||
Returns:
|
||||
bool: True if successful, False otherwise
|
||||
"""
|
||||
try:
|
||||
os.makedirs(os.path.dirname(filepath), exist_ok=True)
|
||||
df.to_excel(filepath, **kwargs)
|
||||
return True
|
||||
except Exception as e:
|
||||
error_msg = f"Error writing Excel file {filepath}: {str(e)}"
|
||||
logging.error(error_msg)
|
||||
return False
|
||||
|
||||
def filter_data(self, df: pd.DataFrame, query: str) -> Union[pd.DataFrame, Dict[str, str]]:
|
||||
"""
|
||||
Filter DataFrame using a query string.
|
||||
|
||||
Args:
|
||||
df: Input DataFrame
|
||||
query: Query string (e.g., "column > 5 and other_column == 'value'")
|
||||
|
||||
Returns:
|
||||
pd.DataFrame or Dict: Filtered DataFrame if successful, error dict if failed
|
||||
"""
|
||||
try:
|
||||
return df.query(query)
|
||||
except Exception as e:
|
||||
error_msg = f"Error filtering data with query '{query}': {str(e)}"
|
||||
logging.error(error_msg)
|
||||
return {"error": error_msg}
|
||||
|
||||
def get_summary(self, df: pd.DataFrame) -> Dict[str, Any]:
|
||||
"""
|
||||
Get a summary of the DataFrame including basic statistics and info.
|
||||
|
||||
Args:
|
||||
df: Input DataFrame
|
||||
|
||||
Returns:
|
||||
Dict: Summary statistics and information
|
||||
"""
|
||||
try:
|
||||
numeric_summary = df.describe().to_dict()
|
||||
# Convert numpy types to native Python types
|
||||
for col in numeric_summary:
|
||||
numeric_summary[col] = {k: _convert_to_serializable(v)
|
||||
for k, v in numeric_summary[col].items()}
|
||||
|
||||
summary = {
|
||||
"shape": list(df.shape),
|
||||
"columns": list(df.columns),
|
||||
"dtypes": df.dtypes.astype(str).to_dict(),
|
||||
"null_counts": df.isnull().sum().to_dict(),
|
||||
"numeric_summary": numeric_summary,
|
||||
"memory_usage": int(df.memory_usage(deep=True).sum()),
|
||||
}
|
||||
return summary
|
||||
except Exception as e:
|
||||
error_msg = f"Error getting data summary: {str(e)}"
|
||||
logging.error(error_msg)
|
||||
return {"error": error_msg}
|
||||
|
||||
def group_by(
|
||||
self,
|
||||
df: pd.DataFrame,
|
||||
columns: Union[str, List[str]],
|
||||
agg_dict: Dict[str, Union[str, List[str]]]
|
||||
) -> Union[pd.DataFrame, Dict[str, str]]:
|
||||
"""
|
||||
Group DataFrame by columns and apply aggregation functions.
|
||||
|
||||
Args:
|
||||
df: Input DataFrame
|
||||
columns: Column(s) to group by
|
||||
agg_dict: Dictionary of column:function pairs for aggregation
|
||||
|
||||
Returns:
|
||||
pd.DataFrame or Dict: Grouped DataFrame if successful, error dict if failed
|
||||
"""
|
||||
try:
|
||||
return df.groupby(columns).agg(agg_dict).reset_index()
|
||||
except Exception as e:
|
||||
error_msg = f"Error grouping data: {str(e)}"
|
||||
logging.error(error_msg)
|
||||
return {"error": error_msg}
|
||||
|
||||
def pivot_table(
|
||||
self,
|
||||
df: pd.DataFrame,
|
||||
index: Union[str, List[str]],
|
||||
columns: Optional[Union[str, List[str]]] = None,
|
||||
values: Optional[Union[str, List[str]]] = None,
|
||||
aggfunc: str = "mean"
|
||||
) -> Union[pd.DataFrame, Dict[str, str]]:
|
||||
"""
|
||||
Create a pivot table from DataFrame.
|
||||
|
||||
Args:
|
||||
df: Input DataFrame
|
||||
index: Column(s) to use as index
|
||||
columns: Column(s) to use as columns
|
||||
values: Column(s) to aggregate
|
||||
aggfunc: Aggregation function to use
|
||||
|
||||
Returns:
|
||||
pd.DataFrame or Dict: Pivot table if successful, error dict if failed
|
||||
"""
|
||||
try:
|
||||
return pd.pivot_table(
|
||||
df,
|
||||
index=index,
|
||||
columns=columns,
|
||||
values=values,
|
||||
aggfunc=aggfunc
|
||||
).reset_index()
|
||||
except Exception as e:
|
||||
error_msg = f"Error creating pivot table: {str(e)}"
|
||||
logging.error(error_msg)
|
||||
return {"error": error_msg}
|
||||
|
||||
# Create instance for direct function access
|
||||
_pandas_tools = PandasTools()
|
||||
read_csv = _pandas_tools.read_csv
|
||||
read_excel = _pandas_tools.read_excel
|
||||
write_csv = _pandas_tools.write_csv
|
||||
write_excel = _pandas_tools.write_excel
|
||||
filter_data = _pandas_tools.filter_data
|
||||
get_summary = _pandas_tools.get_summary
|
||||
group_by = _pandas_tools.group_by
|
||||
pivot_table = _pandas_tools.pivot_table
|
||||
|
||||
if __name__ == "__main__":
|
||||
# Example usage
|
||||
print("\n==================================================")
|
||||
print("PandasTools Demonstration")
|
||||
print("==================================================\n")
|
||||
|
||||
# Create a test directory
|
||||
test_dir = os.path.join(os.getcwd(), "test_files")
|
||||
os.makedirs(test_dir, exist_ok=True)
|
||||
|
||||
# Create a sample DataFrame
|
||||
df = pd.DataFrame({
|
||||
'name': ['John', 'Jane', 'Bob', 'Alice', 'Charlie'],
|
||||
'age': [25, 30, 35, 28, 32],
|
||||
'city': ['New York', 'London', 'Paris', 'Tokyo', 'London'],
|
||||
'salary': [50000, 60000, 75000, 65000, 55000]
|
||||
})
|
||||
|
||||
# 1. Write to CSV
|
||||
print("1. Writing to CSV")
|
||||
print("------------------------------")
|
||||
csv_file = os.path.join(test_dir, "sample.csv")
|
||||
success = write_csv(df, csv_file, index=False)
|
||||
print(f"Write successful: {success}\n")
|
||||
|
||||
# 2. Read from CSV
|
||||
print("2. Reading from CSV")
|
||||
print("------------------------------")
|
||||
df_read = read_csv(csv_file)
|
||||
print("First few rows:")
|
||||
print(df_read.head())
|
||||
print()
|
||||
|
||||
# 3. Filter Data
|
||||
print("3. Filtering Data")
|
||||
print("------------------------------")
|
||||
filtered_df = filter_data(df, "age > 30 and salary > 60000")
|
||||
print("People over 30 with salary > 60000:")
|
||||
print(filtered_df)
|
||||
print()
|
||||
|
||||
# 4. Get Summary
|
||||
print("4. Data Summary")
|
||||
print("------------------------------")
|
||||
summary = get_summary(df)
|
||||
print(json.dumps(summary, indent=2))
|
||||
print()
|
||||
|
||||
# 5. Group By
|
||||
print("5. Group By")
|
||||
print("------------------------------")
|
||||
grouped = group_by(df, "city", {"salary": ["mean", "count"], "age": "mean"})
|
||||
print("Statistics by city:")
|
||||
print(grouped)
|
||||
print()
|
||||
|
||||
# 6. Pivot Table
|
||||
print("6. Pivot Table")
|
||||
print("------------------------------")
|
||||
pivoted = pivot_table(df, index="city", values=["salary", "age"])
|
||||
print("Pivot table by city:")
|
||||
print(pivoted)
|
||||
print()
|
||||
|
||||
# Clean up test directory
|
||||
try:
|
||||
import shutil
|
||||
shutil.rmtree(test_dir)
|
||||
print("Test directory cleaned up successfully")
|
||||
except Exception as e:
|
||||
print(f"Error cleaning up test directory: {str(e)}")
|
||||
|
||||
print("\n==================================================")
|
||||
print("Demonstration Complete")
|
||||
print("==================================================")
|
||||
@@ -0,0 +1,423 @@
|
||||
"""Tools for Python code execution and analysis.
|
||||
|
||||
Usage:
|
||||
from praisonaiagents.tools import python_tools
|
||||
result = python_tools.execute_code("print('Hello, World!')")
|
||||
|
||||
or
|
||||
from praisonaiagents.tools import execute_code, analyze_code, format_code
|
||||
result = execute_code("print('Hello, World!')")
|
||||
"""
|
||||
|
||||
import logging
|
||||
from typing import Dict, List, Optional, Any
|
||||
from importlib import util
|
||||
import io
|
||||
from contextlib import redirect_stdout, redirect_stderr
|
||||
import traceback
|
||||
|
||||
class PythonTools:
|
||||
"""Tools for Python code execution and analysis."""
|
||||
|
||||
def __init__(self):
|
||||
"""Initialize PythonTools."""
|
||||
self._check_dependencies()
|
||||
|
||||
def _check_dependencies(self):
|
||||
"""Check if required packages are installed."""
|
||||
missing = []
|
||||
for package in ['black', 'pylint', 'autopep8']:
|
||||
if util.find_spec(package) is None:
|
||||
missing.append(package)
|
||||
|
||||
if missing:
|
||||
raise ImportError(
|
||||
f"Required packages not available. Please install: {', '.join(missing)}\n"
|
||||
f"Run: pip install {' '.join(missing)}"
|
||||
)
|
||||
|
||||
def execute_code(
|
||||
self,
|
||||
code: str,
|
||||
globals_dict: Optional[Dict[str, Any]] = None,
|
||||
locals_dict: Optional[Dict[str, Any]] = None,
|
||||
timeout: int = 30,
|
||||
max_output_size: int = 10000
|
||||
) -> Dict[str, Any]:
|
||||
"""Execute Python code safely."""
|
||||
try:
|
||||
# Set up execution environment
|
||||
if globals_dict is None:
|
||||
globals_dict = {'__builtins__': __builtins__}
|
||||
if locals_dict is None:
|
||||
locals_dict = {}
|
||||
|
||||
# Capture output
|
||||
stdout_buffer = io.StringIO()
|
||||
stderr_buffer = io.StringIO()
|
||||
|
||||
try:
|
||||
# Compile code
|
||||
compiled_code = compile(code, '<string>', 'exec')
|
||||
|
||||
# Execute with output capture
|
||||
with redirect_stdout(stdout_buffer), redirect_stderr(stderr_buffer):
|
||||
exec(compiled_code, globals_dict, locals_dict)
|
||||
|
||||
# Get last expression value if any
|
||||
import ast
|
||||
tree = ast.parse(code)
|
||||
if tree.body and isinstance(tree.body[-1], ast.Expr):
|
||||
result = eval(
|
||||
compile(ast.Expression(tree.body[-1].value), '<string>', 'eval'),
|
||||
globals_dict,
|
||||
locals_dict
|
||||
)
|
||||
else:
|
||||
result = None
|
||||
|
||||
# Get output
|
||||
stdout = stdout_buffer.getvalue()
|
||||
stderr = stderr_buffer.getvalue()
|
||||
|
||||
# Truncate output if too large
|
||||
if len(stdout) > max_output_size:
|
||||
stdout = stdout[:max_output_size] + "...[truncated]"
|
||||
if len(stderr) > max_output_size:
|
||||
stderr = stderr[:max_output_size] + "...[truncated]"
|
||||
|
||||
return {
|
||||
'result': result,
|
||||
'stdout': stdout,
|
||||
'stderr': stderr,
|
||||
'success': True
|
||||
}
|
||||
|
||||
except Exception as e:
|
||||
error_msg = f"Error executing code: {str(e)}"
|
||||
logging.error(error_msg)
|
||||
return {
|
||||
'result': None,
|
||||
'stdout': stdout_buffer.getvalue(),
|
||||
'stderr': error_msg,
|
||||
'success': False
|
||||
}
|
||||
|
||||
except Exception as e:
|
||||
error_msg = f"Error executing code: {str(e)}"
|
||||
logging.error(error_msg)
|
||||
return {
|
||||
'result': None,
|
||||
'stdout': '',
|
||||
'stderr': error_msg,
|
||||
'success': False
|
||||
}
|
||||
|
||||
def analyze_code(
|
||||
self,
|
||||
code: str
|
||||
) -> Optional[Dict[str, Any]]:
|
||||
"""Analyze Python code structure and quality.
|
||||
|
||||
Args:
|
||||
code: Python code to analyze
|
||||
|
||||
Returns:
|
||||
Dictionary with analysis results
|
||||
"""
|
||||
try:
|
||||
# Import ast only when needed
|
||||
import ast
|
||||
|
||||
# Parse code
|
||||
tree = ast.parse(code)
|
||||
|
||||
# Analyze structure
|
||||
analysis = {
|
||||
'imports': [],
|
||||
'functions': [],
|
||||
'classes': [],
|
||||
'variables': [],
|
||||
'complexity': {
|
||||
'lines': len(code.splitlines()),
|
||||
'functions': 0,
|
||||
'classes': 0,
|
||||
'branches': 0
|
||||
}
|
||||
}
|
||||
|
||||
# Analyze nodes
|
||||
for node in ast.walk(tree):
|
||||
if isinstance(node, ast.Import):
|
||||
for name in node.names:
|
||||
analysis['imports'].append(name.name)
|
||||
elif isinstance(node, ast.ImportFrom):
|
||||
module = node.module or ''
|
||||
for name in node.names:
|
||||
analysis['imports'].append(f"{module}.{name.name}")
|
||||
elif isinstance(node, ast.FunctionDef):
|
||||
analysis['functions'].append({
|
||||
'name': node.name,
|
||||
'args': [
|
||||
arg.arg for arg in node.args.args
|
||||
],
|
||||
'decorators': [
|
||||
ast.unparse(d) for d in node.decorator_list
|
||||
]
|
||||
})
|
||||
analysis['complexity']['functions'] += 1
|
||||
elif isinstance(node, ast.ClassDef):
|
||||
analysis['classes'].append({
|
||||
'name': node.name,
|
||||
'bases': [
|
||||
ast.unparse(base) for base in node.bases
|
||||
],
|
||||
'decorators': [
|
||||
ast.unparse(d) for d in node.decorator_list
|
||||
]
|
||||
})
|
||||
analysis['complexity']['classes'] += 1
|
||||
elif isinstance(node, ast.Assign):
|
||||
for target in node.targets:
|
||||
if isinstance(target, ast.Name):
|
||||
analysis['variables'].append(target.id)
|
||||
elif isinstance(node, (ast.If, ast.While, ast.For)):
|
||||
analysis['complexity']['branches'] += 1
|
||||
|
||||
return analysis
|
||||
except Exception as e:
|
||||
error_msg = f"Error analyzing code: {str(e)}"
|
||||
logging.error(error_msg)
|
||||
return None
|
||||
|
||||
def format_code(
|
||||
self,
|
||||
code: str,
|
||||
style: str = 'black',
|
||||
line_length: int = 88
|
||||
) -> Optional[str]:
|
||||
"""Format Python code according to style guide.
|
||||
|
||||
Args:
|
||||
code: Python code to format
|
||||
style: Formatting style ('black' or 'pep8')
|
||||
line_length: Maximum line length
|
||||
|
||||
Returns:
|
||||
Formatted code
|
||||
"""
|
||||
try:
|
||||
if util.find_spec(style) is None:
|
||||
error_msg = f"{style} package is not available. Please install it using: pip install {style}"
|
||||
logging.error(error_msg)
|
||||
return None
|
||||
|
||||
if style == 'black':
|
||||
import black
|
||||
return black.format_str(
|
||||
code,
|
||||
mode=black.FileMode(
|
||||
line_length=line_length
|
||||
)
|
||||
)
|
||||
else: # pep8
|
||||
import autopep8
|
||||
return autopep8.fix_code(
|
||||
code,
|
||||
options={
|
||||
'max_line_length': line_length
|
||||
}
|
||||
)
|
||||
except Exception as e:
|
||||
error_msg = f"Error formatting code: {str(e)}"
|
||||
logging.error(error_msg)
|
||||
return None
|
||||
|
||||
def lint_code(
|
||||
self,
|
||||
code: str
|
||||
) -> Optional[Dict[str, List[Dict[str, Any]]]]:
|
||||
"""Lint Python code for potential issues.
|
||||
|
||||
Args:
|
||||
code: Python code to lint
|
||||
|
||||
Returns:
|
||||
Dictionary with linting results
|
||||
"""
|
||||
try:
|
||||
if util.find_spec('pylint') is None:
|
||||
error_msg = "pylint package is not available. Please install it using: pip install pylint"
|
||||
logging.error(error_msg)
|
||||
return None
|
||||
|
||||
# Import pylint only when needed
|
||||
from pylint.reporters import JSONReporter
|
||||
from pylint.lint.run import Run
|
||||
|
||||
# Create temporary file for pylint
|
||||
import tempfile
|
||||
with tempfile.NamedTemporaryFile(
|
||||
mode='w',
|
||||
suffix='.py',
|
||||
delete=False
|
||||
) as f:
|
||||
f.write(code)
|
||||
temp_path = f.name
|
||||
|
||||
# Run pylint
|
||||
reporter = JSONReporter()
|
||||
Run(
|
||||
[temp_path],
|
||||
reporter=reporter,
|
||||
exit=False
|
||||
)
|
||||
|
||||
# Process results
|
||||
results = {
|
||||
'errors': [],
|
||||
'warnings': [],
|
||||
'conventions': []
|
||||
}
|
||||
|
||||
for msg in reporter.messages:
|
||||
item = {
|
||||
'type': msg.category,
|
||||
'module': msg.module,
|
||||
'obj': msg.obj,
|
||||
'line': msg.line,
|
||||
'column': msg.column,
|
||||
'path': msg.path,
|
||||
'symbol': msg.symbol,
|
||||
'message': msg.msg,
|
||||
'message-id': msg.msg_id
|
||||
}
|
||||
|
||||
if msg.category in ['error', 'fatal']:
|
||||
results['errors'].append(item)
|
||||
elif msg.category == 'warning':
|
||||
results['warnings'].append(item)
|
||||
else:
|
||||
results['conventions'].append(item)
|
||||
|
||||
# Clean up
|
||||
import os
|
||||
os.unlink(temp_path)
|
||||
|
||||
return results
|
||||
except Exception as e:
|
||||
error_msg = f"Error linting code: {str(e)}"
|
||||
logging.error(error_msg)
|
||||
return {
|
||||
'errors': [],
|
||||
'warnings': [],
|
||||
'conventions': []
|
||||
}
|
||||
|
||||
def disassemble_code(
|
||||
self,
|
||||
code: str
|
||||
) -> Optional[str]:
|
||||
"""Disassemble Python code to bytecode.
|
||||
|
||||
Args:
|
||||
code: Python code to disassemble
|
||||
|
||||
Returns:
|
||||
Disassembled bytecode as string
|
||||
"""
|
||||
try:
|
||||
# Import dis only when needed
|
||||
import dis
|
||||
|
||||
# Compile code
|
||||
compiled_code = compile(code, '<string>', 'exec')
|
||||
|
||||
# Capture disassembly
|
||||
output = io.StringIO()
|
||||
with redirect_stdout(output):
|
||||
dis.dis(compiled_code)
|
||||
|
||||
return output.getvalue()
|
||||
except Exception as e:
|
||||
error_msg = f"Error disassembling code: {str(e)}"
|
||||
logging.error(error_msg)
|
||||
return None
|
||||
|
||||
# Create instance for direct function access
|
||||
_python_tools = PythonTools()
|
||||
execute_code = _python_tools.execute_code
|
||||
analyze_code = _python_tools.analyze_code
|
||||
format_code = _python_tools.format_code
|
||||
lint_code = _python_tools.lint_code
|
||||
disassemble_code = _python_tools.disassemble_code
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("\n==================================================")
|
||||
print("PythonTools Demonstration")
|
||||
print("==================================================\n")
|
||||
|
||||
print("1. Execute Python Code")
|
||||
print("------------------------------")
|
||||
code = """
|
||||
def greet(name):
|
||||
return f"Hello, {name}!"
|
||||
|
||||
result = greet("World")
|
||||
print(result)
|
||||
"""
|
||||
print("Code to execute:")
|
||||
print(code)
|
||||
print("\nOutput:")
|
||||
result = execute_code(code)
|
||||
print(result["stdout"])
|
||||
print()
|
||||
|
||||
print("2. Format Python Code")
|
||||
print("------------------------------")
|
||||
code = """
|
||||
def messy_function(x,y, z):
|
||||
if x>0:
|
||||
return y+z
|
||||
else:
|
||||
return y-z
|
||||
"""
|
||||
print("Before formatting:")
|
||||
print(code)
|
||||
print("\nAfter formatting:")
|
||||
result = format_code(code)
|
||||
print(result)
|
||||
print()
|
||||
|
||||
print("3. Lint Python Code")
|
||||
print("------------------------------")
|
||||
code = """
|
||||
def bad_function():
|
||||
unused_var = 42
|
||||
return 'result'
|
||||
"""
|
||||
print("Code to lint:")
|
||||
print(code)
|
||||
print("\nLinting results:")
|
||||
result = lint_code(code)
|
||||
print(result)
|
||||
print()
|
||||
|
||||
print("4. Execute Code with Variables")
|
||||
print("------------------------------")
|
||||
code = """
|
||||
x = 10
|
||||
y = 20
|
||||
result = x + y
|
||||
print(f"The sum of {x} and {y} is {result}")
|
||||
"""
|
||||
print("Code to execute:")
|
||||
print(code)
|
||||
print("\nOutput:")
|
||||
result = execute_code(code)
|
||||
print(result["stdout"])
|
||||
print()
|
||||
|
||||
print("==================================================")
|
||||
print("Demonstration Complete")
|
||||
print("==================================================")
|
||||
@@ -0,0 +1,278 @@
|
||||
"""Tools for executing shell commands safely.
|
||||
|
||||
This module provides a safe interface for executing shell commands with:
|
||||
- Timeout control
|
||||
- Output capture
|
||||
- Error handling
|
||||
- Resource limits
|
||||
"""
|
||||
|
||||
import subprocess
|
||||
import shlex
|
||||
import logging
|
||||
import os
|
||||
import time
|
||||
from typing import Dict, List, Optional, Union
|
||||
|
||||
class ShellTools:
|
||||
"""Tools for executing shell commands safely."""
|
||||
|
||||
def __init__(self):
|
||||
"""Initialize ShellTools."""
|
||||
self._check_dependencies()
|
||||
|
||||
def _check_dependencies(self):
|
||||
"""Check if required packages are installed."""
|
||||
try:
|
||||
import psutil
|
||||
except ImportError:
|
||||
raise ImportError(
|
||||
"Required package not available. Please install: psutil\n"
|
||||
"Run: pip install psutil"
|
||||
)
|
||||
|
||||
def execute_command(
|
||||
self,
|
||||
command: str,
|
||||
cwd: Optional[str] = None,
|
||||
timeout: int = 30,
|
||||
shell: bool = False,
|
||||
env: Optional[Dict[str, str]] = None,
|
||||
max_output_size: int = 10000
|
||||
) -> Dict[str, Union[str, int, bool]]:
|
||||
"""Execute a shell command safely.
|
||||
|
||||
Args:
|
||||
command: Command to execute
|
||||
cwd: Working directory
|
||||
timeout: Maximum execution time in seconds
|
||||
shell: Whether to run command in shell
|
||||
env: Environment variables
|
||||
max_output_size: Maximum output size in bytes
|
||||
|
||||
Returns:
|
||||
Dictionary with execution results
|
||||
"""
|
||||
try:
|
||||
# Split command if not using shell
|
||||
if not shell:
|
||||
command = shlex.split(command)
|
||||
|
||||
# Set up process environment
|
||||
process_env = os.environ.copy()
|
||||
if env:
|
||||
process_env.update(env)
|
||||
|
||||
# Start process
|
||||
start_time = time.time()
|
||||
process = subprocess.Popen(
|
||||
command,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
cwd=cwd,
|
||||
shell=shell,
|
||||
env=process_env,
|
||||
text=True
|
||||
)
|
||||
|
||||
try:
|
||||
# Wait for process with timeout
|
||||
stdout, stderr = process.communicate(timeout=timeout)
|
||||
|
||||
# Truncate output if too large
|
||||
if len(stdout) > max_output_size:
|
||||
stdout = stdout[:max_output_size] + "...[truncated]"
|
||||
if len(stderr) > max_output_size:
|
||||
stderr = stderr[:max_output_size] + "...[truncated]"
|
||||
|
||||
return {
|
||||
'stdout': stdout,
|
||||
'stderr': stderr,
|
||||
'exit_code': process.returncode,
|
||||
'success': process.returncode == 0,
|
||||
'execution_time': time.time() - start_time
|
||||
}
|
||||
|
||||
except subprocess.TimeoutExpired:
|
||||
# Kill process on timeout
|
||||
parent = psutil.Process(process.pid)
|
||||
children = parent.children(recursive=True)
|
||||
for child in children:
|
||||
child.kill()
|
||||
parent.kill()
|
||||
|
||||
return {
|
||||
'stdout': '',
|
||||
'stderr': f'Command timed out after {timeout} seconds',
|
||||
'exit_code': -1,
|
||||
'success': False,
|
||||
'execution_time': timeout
|
||||
}
|
||||
|
||||
except Exception as e:
|
||||
error_msg = f"Error executing command: {str(e)}"
|
||||
logging.error(error_msg)
|
||||
return {
|
||||
'stdout': '',
|
||||
'stderr': error_msg,
|
||||
'exit_code': -1,
|
||||
'success': False,
|
||||
'execution_time': 0
|
||||
}
|
||||
|
||||
def list_processes(self) -> List[Dict[str, Union[int, str, float]]]:
|
||||
"""List running processes with their details.
|
||||
|
||||
Returns:
|
||||
List of process information dictionaries
|
||||
"""
|
||||
try:
|
||||
processes = []
|
||||
for proc in psutil.process_iter(['pid', 'name', 'username', 'memory_percent', 'cpu_percent']):
|
||||
try:
|
||||
pinfo = proc.info
|
||||
processes.append({
|
||||
'pid': pinfo['pid'],
|
||||
'name': pinfo['name'],
|
||||
'username': pinfo['username'],
|
||||
'memory_percent': round(pinfo['memory_percent'], 2),
|
||||
'cpu_percent': round(pinfo['cpu_percent'], 2)
|
||||
})
|
||||
except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
|
||||
pass
|
||||
return processes
|
||||
except Exception as e:
|
||||
error_msg = f"Error listing processes: {str(e)}"
|
||||
logging.error(error_msg)
|
||||
return []
|
||||
|
||||
def kill_process(
|
||||
self,
|
||||
pid: int,
|
||||
force: bool = False
|
||||
) -> Dict[str, Union[bool, str]]:
|
||||
"""Kill a process by its PID.
|
||||
|
||||
Args:
|
||||
pid: Process ID to kill
|
||||
force: Whether to force kill (-9)
|
||||
|
||||
Returns:
|
||||
Dictionary with operation results
|
||||
"""
|
||||
try:
|
||||
process = psutil.Process(pid)
|
||||
if force:
|
||||
process.kill() # SIGKILL
|
||||
else:
|
||||
process.terminate() # SIGTERM
|
||||
|
||||
return {
|
||||
'success': True,
|
||||
'message': f'Process {pid} killed successfully'
|
||||
}
|
||||
except psutil.NoSuchProcess:
|
||||
return {
|
||||
'success': False,
|
||||
'message': f'No process found with PID {pid}'
|
||||
}
|
||||
except psutil.AccessDenied:
|
||||
return {
|
||||
'success': False,
|
||||
'message': f'Access denied to kill process {pid}'
|
||||
}
|
||||
except Exception as e:
|
||||
error_msg = f"Error killing process: {str(e)}"
|
||||
logging.error(error_msg)
|
||||
return {
|
||||
'success': False,
|
||||
'message': error_msg
|
||||
}
|
||||
|
||||
def get_system_info(self) -> Dict[str, Union[float, int, str, Dict]]:
|
||||
"""Get system information.
|
||||
|
||||
Returns:
|
||||
Dictionary with system information
|
||||
"""
|
||||
try:
|
||||
cpu_percent = psutil.cpu_percent(interval=1)
|
||||
memory = psutil.virtual_memory()
|
||||
disk = psutil.disk_usage('/')
|
||||
|
||||
return {
|
||||
'cpu': {
|
||||
'percent': cpu_percent,
|
||||
'cores': psutil.cpu_count(),
|
||||
'physical_cores': psutil.cpu_count(logical=False)
|
||||
},
|
||||
'memory': {
|
||||
'total': memory.total,
|
||||
'available': memory.available,
|
||||
'percent': memory.percent,
|
||||
'used': memory.used,
|
||||
'free': memory.free
|
||||
},
|
||||
'disk': {
|
||||
'total': disk.total,
|
||||
'used': disk.used,
|
||||
'free': disk.free,
|
||||
'percent': disk.percent
|
||||
},
|
||||
'boot_time': psutil.boot_time(),
|
||||
'platform': os.uname().sysname
|
||||
}
|
||||
except Exception as e:
|
||||
error_msg = f"Error getting system info: {str(e)}"
|
||||
logging.error(error_msg)
|
||||
return {}
|
||||
|
||||
# Create instance for direct function access
|
||||
_shell_tools = ShellTools()
|
||||
execute_command = _shell_tools.execute_command
|
||||
list_processes = _shell_tools.list_processes
|
||||
kill_process = _shell_tools.kill_process
|
||||
get_system_info = _shell_tools.get_system_info
|
||||
|
||||
if __name__ == "__main__":
|
||||
# Example usage
|
||||
print("\n==================================================")
|
||||
print("ShellTools Demonstration")
|
||||
print("==================================================\n")
|
||||
|
||||
# 1. Execute command
|
||||
print("1. Command Execution")
|
||||
print("------------------------------")
|
||||
result = execute_command("ls -la")
|
||||
print(f"Success: {result['success']}")
|
||||
print(f"Output:\n{result['stdout']}")
|
||||
if result['stderr']:
|
||||
print(f"Errors:\n{result['stderr']}")
|
||||
print(f"Execution time: {result['execution_time']:.2f}s")
|
||||
print()
|
||||
|
||||
# 2. System Information
|
||||
print("2. System Information")
|
||||
print("------------------------------")
|
||||
info = get_system_info()
|
||||
print(f"CPU Usage: {info['cpu']['percent']}%")
|
||||
print(f"Memory Usage: {info['memory']['percent']}%")
|
||||
print(f"Disk Usage: {info['disk']['percent']}%")
|
||||
print(f"Platform: {info['platform']}")
|
||||
print()
|
||||
|
||||
# 3. Process List
|
||||
print("3. Process List (top 5 by CPU)")
|
||||
print("------------------------------")
|
||||
processes = sorted(
|
||||
list_processes(),
|
||||
key=lambda x: x['cpu_percent'],
|
||||
reverse=True
|
||||
)[:5]
|
||||
for proc in processes:
|
||||
print(f"PID: {proc['pid']}, Name: {proc['name']}, CPU: {proc['cpu_percent']}%")
|
||||
print()
|
||||
|
||||
print("\n==================================================")
|
||||
print("Demonstration Complete")
|
||||
print("==================================================")
|
||||
@@ -0,0 +1,431 @@
|
||||
"""Tools for web scraping and crawling.
|
||||
|
||||
Usage:
|
||||
from praisonaiagents.tools import spider_tools
|
||||
content = spider_tools.scrape_page("https://example.com")
|
||||
links = spider_tools.extract_links("https://example.com")
|
||||
|
||||
or
|
||||
from praisonaiagents.tools import scrape_page, extract_links
|
||||
content = scrape_page("https://example.com")
|
||||
"""
|
||||
|
||||
import logging
|
||||
from typing import List, Dict, Union, Optional, Any
|
||||
from importlib import util
|
||||
import json
|
||||
from urllib.parse import urljoin, urlparse
|
||||
import re
|
||||
import os
|
||||
import hashlib
|
||||
import time
|
||||
|
||||
class SpiderTools:
|
||||
"""Tools for web scraping and crawling."""
|
||||
|
||||
def __init__(self):
|
||||
"""Initialize SpiderTools and check for required packages."""
|
||||
self._session = None
|
||||
|
||||
def _get_session(self):
|
||||
"""Get or create requests session with common headers."""
|
||||
if util.find_spec('requests') is None:
|
||||
error_msg = "requests package is not available. Please install it using: pip install requests"
|
||||
logging.error(error_msg)
|
||||
return None
|
||||
|
||||
if self._session is None:
|
||||
import requests
|
||||
self._session = requests.Session()
|
||||
self._session.headers.update({
|
||||
'User-Agent': 'Mozilla/5.0 (compatible; PraisonAI/1.0; +http://praisonai.com/bot)',
|
||||
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
|
||||
'Accept-Language': 'en-US,en;q=0.5',
|
||||
'Accept-Encoding': 'gzip, deflate, br',
|
||||
'Connection': 'keep-alive',
|
||||
})
|
||||
return self._session
|
||||
|
||||
def scrape_page(
|
||||
self,
|
||||
url: str,
|
||||
selector: Optional[str] = None,
|
||||
extract_images: bool = False,
|
||||
extract_links: bool = False,
|
||||
timeout: int = 30,
|
||||
verify_ssl: bool = True
|
||||
) -> Union[Dict[str, Any], Dict[str, str]]:
|
||||
"""
|
||||
Scrape content from a webpage.
|
||||
|
||||
Args:
|
||||
url: URL to scrape
|
||||
selector: Optional CSS selector to extract specific content
|
||||
extract_images: Whether to extract image URLs
|
||||
extract_links: Whether to extract links
|
||||
timeout: Request timeout in seconds
|
||||
verify_ssl: Whether to verify SSL certificates
|
||||
|
||||
Returns:
|
||||
Dict: Scraped content or error dict
|
||||
"""
|
||||
try:
|
||||
session = self._get_session()
|
||||
if session is None:
|
||||
return {"error": "requests package not available"}
|
||||
|
||||
# Import BeautifulSoup only when needed
|
||||
if util.find_spec('bs4') is None:
|
||||
error_msg = "bs4 package is not available. Please install it using: pip install beautifulsoup4"
|
||||
logging.error(error_msg)
|
||||
return {"error": error_msg}
|
||||
from bs4 import BeautifulSoup
|
||||
|
||||
# Make request
|
||||
response = session.get(
|
||||
url,
|
||||
timeout=timeout,
|
||||
verify=verify_ssl
|
||||
)
|
||||
response.raise_for_status()
|
||||
|
||||
# Parse HTML
|
||||
soup = BeautifulSoup(response.text, 'lxml')
|
||||
|
||||
# Remove unwanted elements
|
||||
for element in soup(['script', 'style']):
|
||||
element.decompose()
|
||||
|
||||
# Initialize result
|
||||
result = {
|
||||
'url': url,
|
||||
'status_code': response.status_code,
|
||||
'encoding': response.encoding,
|
||||
'headers': dict(response.headers),
|
||||
}
|
||||
|
||||
# Extract content based on selector
|
||||
if selector:
|
||||
elements = soup.select(selector)
|
||||
result['content'] = [elem.get_text(strip=True) for elem in elements]
|
||||
result['html'] = [str(elem) for elem in elements]
|
||||
else:
|
||||
result['title'] = soup.title.string if soup.title else None
|
||||
result['content'] = soup.get_text(separator=' ', strip=True)
|
||||
result['html'] = str(soup)
|
||||
|
||||
# Extract metadata
|
||||
meta_tags = {}
|
||||
for meta in soup.find_all('meta'):
|
||||
name = meta.get('name') or meta.get('property')
|
||||
if name:
|
||||
meta_tags[name] = meta.get('content')
|
||||
result['meta_tags'] = meta_tags
|
||||
|
||||
# Extract images if requested
|
||||
if extract_images:
|
||||
images = []
|
||||
for img in soup.find_all('img'):
|
||||
src = img.get('src')
|
||||
if src:
|
||||
images.append({
|
||||
'src': urljoin(url, src),
|
||||
'alt': img.get('alt', ''),
|
||||
'title': img.get('title', '')
|
||||
})
|
||||
result['images'] = images
|
||||
|
||||
# Extract links if requested
|
||||
if extract_links:
|
||||
links = []
|
||||
for link in soup.find_all('a'):
|
||||
href = link.get('href')
|
||||
if href:
|
||||
links.append({
|
||||
'url': urljoin(url, href),
|
||||
'text': link.get_text(strip=True),
|
||||
'title': link.get('title', '')
|
||||
})
|
||||
result['links'] = links
|
||||
|
||||
return result
|
||||
except Exception as e:
|
||||
error_msg = f"Error scraping {url}: {str(e)}"
|
||||
logging.error(error_msg)
|
||||
return {"error": error_msg}
|
||||
|
||||
def extract_links(
|
||||
self,
|
||||
url: str,
|
||||
same_domain: bool = True,
|
||||
exclude_patterns: Optional[List[str]] = None,
|
||||
timeout: int = 30,
|
||||
verify_ssl: bool = True
|
||||
) -> Union[List[Dict[str, str]], Dict[str, str]]:
|
||||
"""
|
||||
Extract all links from a webpage.
|
||||
|
||||
Args:
|
||||
url: URL to extract links from
|
||||
same_domain: Only return links from the same domain
|
||||
exclude_patterns: List of regex patterns to exclude
|
||||
timeout: Request timeout in seconds
|
||||
verify_ssl: Whether to verify SSL certificates
|
||||
|
||||
Returns:
|
||||
List[Dict] or Dict: List of links or error dict
|
||||
"""
|
||||
try:
|
||||
# Compile exclude patterns
|
||||
if exclude_patterns:
|
||||
exclude_patterns = [re.compile(p) for p in exclude_patterns]
|
||||
|
||||
# Get base domain
|
||||
base_domain = urlparse(url).netloc
|
||||
|
||||
# Scrape page
|
||||
result = self.scrape_page(
|
||||
url,
|
||||
extract_links=True,
|
||||
timeout=timeout,
|
||||
verify_ssl=verify_ssl
|
||||
)
|
||||
|
||||
if "error" in result:
|
||||
return result
|
||||
|
||||
# Filter and clean links
|
||||
links = []
|
||||
seen_urls = set()
|
||||
|
||||
for link in result.get('links', []):
|
||||
link_url = link['url']
|
||||
|
||||
# Skip if already seen
|
||||
if link_url in seen_urls:
|
||||
continue
|
||||
|
||||
# Parse URL
|
||||
parsed = urlparse(link_url)
|
||||
|
||||
# Skip if not same domain and same_domain is True
|
||||
if same_domain and parsed.netloc != base_domain:
|
||||
continue
|
||||
|
||||
# Skip if matches exclude patterns
|
||||
if exclude_patterns and any(p.search(link_url) for p in exclude_patterns):
|
||||
continue
|
||||
|
||||
# Add to results
|
||||
links.append(link)
|
||||
seen_urls.add(link_url)
|
||||
|
||||
return links
|
||||
except Exception as e:
|
||||
error_msg = f"Error extracting links from {url}: {str(e)}"
|
||||
logging.error(error_msg)
|
||||
return {"error": error_msg}
|
||||
|
||||
def crawl(
|
||||
self,
|
||||
start_url: str,
|
||||
max_pages: int = 10,
|
||||
same_domain: bool = True,
|
||||
exclude_patterns: Optional[List[str]] = None,
|
||||
delay: float = 1.0,
|
||||
timeout: int = 30,
|
||||
verify_ssl: bool = True,
|
||||
output_dir: Optional[str] = None
|
||||
) -> Union[List[Dict[str, Any]], Dict[str, str]]:
|
||||
"""
|
||||
Crawl multiple pages starting from a URL.
|
||||
|
||||
Args:
|
||||
start_url: Starting URL
|
||||
max_pages: Maximum number of pages to crawl
|
||||
same_domain: Only crawl pages from the same domain
|
||||
exclude_patterns: List of regex patterns to exclude
|
||||
delay: Delay between requests in seconds
|
||||
timeout: Request timeout in seconds
|
||||
verify_ssl: Whether to verify SSL certificates
|
||||
output_dir: Directory to save crawled pages
|
||||
|
||||
Returns:
|
||||
List[Dict] or Dict: Crawled pages or error dict
|
||||
"""
|
||||
try:
|
||||
# Create output directory if needed
|
||||
if output_dir:
|
||||
os.makedirs(output_dir, exist_ok=True)
|
||||
|
||||
# Initialize crawl state
|
||||
to_visit = {start_url}
|
||||
visited = set()
|
||||
results = []
|
||||
|
||||
while to_visit and len(visited) < max_pages:
|
||||
# Get next URL
|
||||
url = to_visit.pop()
|
||||
|
||||
# Skip if already visited
|
||||
if url in visited:
|
||||
continue
|
||||
|
||||
# Add to visited
|
||||
visited.add(url)
|
||||
|
||||
# Delay if not first request
|
||||
if len(visited) > 1:
|
||||
time.sleep(delay)
|
||||
|
||||
# Scrape page
|
||||
result = self.scrape_page(
|
||||
url,
|
||||
extract_links=True,
|
||||
timeout=timeout,
|
||||
verify_ssl=verify_ssl
|
||||
)
|
||||
|
||||
if "error" in result:
|
||||
logging.warning(f"Error crawling {url}: {result['error']}")
|
||||
continue
|
||||
|
||||
# Save result
|
||||
results.append(result)
|
||||
|
||||
# Save to file if requested
|
||||
if output_dir:
|
||||
filename = hashlib.md5(url.encode()).hexdigest() + '.json'
|
||||
filepath = os.path.join(output_dir, filename)
|
||||
with open(filepath, 'w', encoding='utf-8') as f:
|
||||
json.dump(result, f, indent=2, ensure_ascii=False)
|
||||
|
||||
# Add new links to visit
|
||||
for link in result.get('links', []):
|
||||
link_url = link['url']
|
||||
parsed = urlparse(link_url)
|
||||
|
||||
# Skip if not same domain and same_domain is True
|
||||
if same_domain and parsed.netloc != urlparse(start_url).netloc:
|
||||
continue
|
||||
|
||||
# Skip if matches exclude patterns
|
||||
if exclude_patterns and any(
|
||||
re.compile(p).search(link_url) for p in exclude_patterns
|
||||
):
|
||||
continue
|
||||
|
||||
# Add to visit if not visited
|
||||
if link_url not in visited:
|
||||
to_visit.add(link_url)
|
||||
|
||||
return results
|
||||
except Exception as e:
|
||||
error_msg = f"Error crawling from {start_url}: {str(e)}"
|
||||
logging.error(error_msg)
|
||||
return {"error": error_msg}
|
||||
|
||||
def extract_text(
|
||||
self,
|
||||
url: str,
|
||||
selector: Optional[str] = None,
|
||||
timeout: int = 30,
|
||||
verify_ssl: bool = True
|
||||
) -> Union[str, Dict[str, str]]:
|
||||
"""
|
||||
Extract clean text content from a webpage.
|
||||
|
||||
Args:
|
||||
url: URL to extract text from
|
||||
selector: Optional CSS selector to extract specific content
|
||||
timeout: Request timeout in seconds
|
||||
verify_ssl: Whether to verify SSL certificates
|
||||
|
||||
Returns:
|
||||
str or Dict: Extracted text or error dict
|
||||
"""
|
||||
try:
|
||||
result = self.scrape_page(
|
||||
url,
|
||||
selector=selector,
|
||||
timeout=timeout,
|
||||
verify_ssl=verify_ssl
|
||||
)
|
||||
|
||||
if "error" in result:
|
||||
return result
|
||||
|
||||
if selector:
|
||||
return '\n'.join(result['content'])
|
||||
return result['content']
|
||||
except Exception as e:
|
||||
error_msg = f"Error extracting text from {url}: {str(e)}"
|
||||
logging.error(error_msg)
|
||||
return {"error": error_msg}
|
||||
|
||||
# Create instance for direct function access
|
||||
_spider_tools = SpiderTools()
|
||||
scrape_page = _spider_tools.scrape_page
|
||||
extract_links = _spider_tools.extract_links
|
||||
crawl = _spider_tools.crawl
|
||||
extract_text = _spider_tools.extract_text
|
||||
|
||||
if __name__ == "__main__":
|
||||
# Example usage
|
||||
print("\n==================================================")
|
||||
print("SpiderTools Demonstration")
|
||||
print("==================================================\n")
|
||||
|
||||
# 1. Scrape a webpage
|
||||
print("1. Scraping Webpage")
|
||||
print("------------------------------")
|
||||
url = "https://example.com"
|
||||
result = scrape_page(url, extract_images=True, extract_links=True)
|
||||
print(f"Content from {url}:")
|
||||
if "error" not in result:
|
||||
print(f"Title: {result['title']}")
|
||||
print(f"Content length: {len(result['content'])} characters")
|
||||
print(f"Number of images: {len(result.get('images', []))}")
|
||||
print(f"Number of links: {len(result.get('links', []))}")
|
||||
else:
|
||||
print(result) # Show error
|
||||
print()
|
||||
|
||||
# 2. Extract links
|
||||
print("2. Extracting Links")
|
||||
print("------------------------------")
|
||||
links = extract_links(url)
|
||||
print(f"Links from {url}:")
|
||||
if isinstance(links, list):
|
||||
for link in links:
|
||||
print(f"- {link['url']} ({link['text']})")
|
||||
else:
|
||||
print(links) # Show error
|
||||
print()
|
||||
|
||||
# 3. Extract text
|
||||
print("3. Extracting Text")
|
||||
print("------------------------------")
|
||||
text = extract_text(url)
|
||||
print(f"Text from {url}:")
|
||||
if isinstance(text, str):
|
||||
print(text[:500] + "..." if len(text) > 500 else text)
|
||||
else:
|
||||
print(text) # Show error
|
||||
print()
|
||||
|
||||
# 4. Crawl multiple pages
|
||||
print("4. Crawling Multiple Pages")
|
||||
print("------------------------------")
|
||||
results = crawl(url, max_pages=2, delay=1.0)
|
||||
print(f"Crawl results from {url}:")
|
||||
if isinstance(results, list):
|
||||
print(f"Crawled {len(results)} pages")
|
||||
for result in results:
|
||||
print(f"- {result['url']}: {result['title']}")
|
||||
else:
|
||||
print(results) # Show error
|
||||
|
||||
print("\n==================================================")
|
||||
print("Demonstration Complete")
|
||||
print("==================================================")
|
||||
@@ -0,0 +1,56 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Test runner for all tools."""
|
||||
|
||||
import os
|
||||
import glob
|
||||
import logging
|
||||
import subprocess
|
||||
|
||||
# Set up logging
|
||||
logging.basicConfig(
|
||||
level=logging.INFO,
|
||||
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
|
||||
)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
def main():
|
||||
"""Run all tool files."""
|
||||
logger.info("Starting tests...")
|
||||
|
||||
# Get all *_tools.py files
|
||||
tools_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
tool_files = glob.glob(os.path.join(tools_dir, "*_tools.py"))
|
||||
|
||||
# Run each tool file
|
||||
for tool_file in sorted(tool_files):
|
||||
module_name = os.path.basename(tool_file)
|
||||
logger.info(f"\nRunning {module_name}...")
|
||||
|
||||
try:
|
||||
# Run the tool file directly
|
||||
result = subprocess.run(
|
||||
["python3", tool_file],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
cwd=tools_dir
|
||||
)
|
||||
|
||||
# Log output
|
||||
if result.stdout:
|
||||
logger.info(f"Output:\n{result.stdout}")
|
||||
if result.stderr:
|
||||
logger.error(f"Errors:\n{result.stderr}")
|
||||
|
||||
if result.returncode == 0:
|
||||
logger.info(f" {module_name} completed successfully")
|
||||
else:
|
||||
logger.error(f" {module_name} failed with return code {result.returncode}")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error running {module_name}: {str(e)}")
|
||||
continue
|
||||
|
||||
logger.info("\nAll tests completed!")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,9 @@
|
||||
"""Tools module for PraisonAI Agents"""
|
||||
from .duckduckgo_tools import internet_search
|
||||
|
||||
class Tools:
|
||||
"""Tools class for backward compatibility"""
|
||||
internet_search = staticmethod(internet_search)
|
||||
|
||||
# Re-export the function
|
||||
__all__ = ['Tools', 'internet_search']
|
||||
@@ -0,0 +1,272 @@
|
||||
"""Wikipedia tools for accessing and searching Wikipedia content.
|
||||
|
||||
Usage:
|
||||
from praisonaiagents.tools import wikipedia_tools
|
||||
summary = wikipedia_tools.wiki_summary("Python programming language")
|
||||
page = wikipedia_tools.wiki_page("Python programming language")
|
||||
results = wikipedia_tools.wiki_search("Python programming")
|
||||
|
||||
or
|
||||
from praisonaiagents.tools import wiki_search, wiki_summary, wiki_page
|
||||
summary = wiki_summary("Python programming language")
|
||||
"""
|
||||
|
||||
import logging
|
||||
from typing import List, Dict, Union, Any
|
||||
from importlib import util
|
||||
import json
|
||||
|
||||
class WikipediaTools:
|
||||
"""Tools for accessing and searching Wikipedia content."""
|
||||
|
||||
def __init__(self):
|
||||
"""Initialize WikipediaTools and check for wikipedia package."""
|
||||
self._check_wikipedia()
|
||||
|
||||
def _check_wikipedia(self):
|
||||
"""Check if wikipedia package is installed."""
|
||||
if util.find_spec("wikipedia") is None:
|
||||
raise ImportError("wikipedia package is not available. Please install it using: pip install wikipedia")
|
||||
global wikipedia
|
||||
import wikipedia
|
||||
# Set default language to English
|
||||
wikipedia.set_lang("en")
|
||||
|
||||
def wiki_search(
|
||||
self,
|
||||
query: str,
|
||||
results: int = 10,
|
||||
suggestion: bool = True
|
||||
) -> Union[List[str], Dict[str, str]]:
|
||||
"""
|
||||
Search Wikipedia for a query.
|
||||
|
||||
Args:
|
||||
query: Search query
|
||||
results: Maximum number of results to return
|
||||
suggestion: Whether to suggest similar queries
|
||||
|
||||
Returns:
|
||||
List[str] or Dict: List of search results or error dict
|
||||
"""
|
||||
try:
|
||||
search_results = wikipedia.search(query, results=results, suggestion=suggestion)
|
||||
if isinstance(search_results, tuple):
|
||||
# If suggestion is True, returns (results, suggestion)
|
||||
return {
|
||||
"results": search_results[0],
|
||||
"suggestion": search_results[1] if search_results[1] else None
|
||||
}
|
||||
return {"results": search_results, "suggestion": None}
|
||||
except Exception as e:
|
||||
error_msg = f"Error searching Wikipedia for '{query}': {str(e)}"
|
||||
logging.error(error_msg)
|
||||
return {"error": error_msg}
|
||||
|
||||
def wiki_summary(
|
||||
self,
|
||||
title: str,
|
||||
sentences: int = 5,
|
||||
auto_suggest: bool = True
|
||||
) -> Union[str, Dict[str, str]]:
|
||||
"""
|
||||
Get a summary of a Wikipedia page.
|
||||
|
||||
Args:
|
||||
title: Title of the Wikipedia page
|
||||
sentences: Number of sentences to return
|
||||
auto_suggest: Whether to auto-suggest similar titles
|
||||
|
||||
Returns:
|
||||
str or Dict: Page summary if successful, error dict if failed
|
||||
"""
|
||||
try:
|
||||
return wikipedia.summary(title, sentences=sentences, auto_suggest=auto_suggest)
|
||||
except wikipedia.exceptions.DisambiguationError as e:
|
||||
return {
|
||||
"error": "Disambiguation page",
|
||||
"options": e.options[:10] # Limit to first 10 options
|
||||
}
|
||||
except Exception as e:
|
||||
error_msg = f"Error getting summary for '{title}': {str(e)}"
|
||||
logging.error(error_msg)
|
||||
return {"error": error_msg}
|
||||
|
||||
def wiki_page(
|
||||
self,
|
||||
title: str,
|
||||
auto_suggest: bool = True
|
||||
) -> Union[Dict[str, Any], Dict[str, str]]:
|
||||
"""
|
||||
Get detailed information about a Wikipedia page.
|
||||
|
||||
Args:
|
||||
title: Title of the Wikipedia page
|
||||
auto_suggest: Whether to auto-suggest similar titles
|
||||
|
||||
Returns:
|
||||
Dict: Page information if successful, error dict if failed
|
||||
"""
|
||||
try:
|
||||
page = wikipedia.page(title, auto_suggest=auto_suggest)
|
||||
return {
|
||||
"title": page.title,
|
||||
"url": page.url,
|
||||
"content": page.content,
|
||||
"summary": page.summary,
|
||||
"references": page.references,
|
||||
"categories": page.categories,
|
||||
"links": page.links,
|
||||
"images": page.images,
|
||||
"sections": self.get_sections(page)
|
||||
}
|
||||
except wikipedia.exceptions.DisambiguationError as e:
|
||||
return {
|
||||
"error": "Disambiguation page",
|
||||
"options": e.options[:10] # Limit to first 10 options
|
||||
}
|
||||
except Exception as e:
|
||||
error_msg = f"Error getting page for '{title}': {str(e)}"
|
||||
logging.error(error_msg)
|
||||
return {"error": error_msg}
|
||||
|
||||
def get_sections(self, page: Any) -> List[Dict[str, Any]]:
|
||||
"""
|
||||
Extract sections and their content from a Wikipedia page.
|
||||
|
||||
Args:
|
||||
page: Wikipedia page object
|
||||
|
||||
Returns:
|
||||
List[Dict]: List of sections with their titles and content
|
||||
"""
|
||||
sections = []
|
||||
content = page.content
|
||||
section_titles = [s.strip() for s in content.split("==")[1::2]]
|
||||
section_contents = [s.strip() for s in content.split("==")[2::2]]
|
||||
|
||||
# Add introduction section
|
||||
intro = content.split("==")[0].strip()
|
||||
if intro:
|
||||
sections.append({
|
||||
"title": "Introduction",
|
||||
"level": 0,
|
||||
"content": intro
|
||||
})
|
||||
|
||||
# Process remaining sections
|
||||
for title, content in zip(section_titles, section_contents):
|
||||
# Count leading '=' to determine section level
|
||||
level = title.count("=") // 2
|
||||
clean_title = title.strip("= ")
|
||||
|
||||
sections.append({
|
||||
"title": clean_title,
|
||||
"level": level,
|
||||
"content": content.strip()
|
||||
})
|
||||
|
||||
return sections
|
||||
|
||||
def wiki_random(self, pages: int = 1) -> Union[List[str], Dict[str, str]]:
|
||||
"""
|
||||
Get random Wikipedia page titles.
|
||||
|
||||
Args:
|
||||
pages: Number of random pages to return
|
||||
|
||||
Returns:
|
||||
List[str] or Dict: List of random page titles or error dict
|
||||
"""
|
||||
try:
|
||||
return wikipedia.random(pages)
|
||||
except Exception as e:
|
||||
error_msg = f"Error getting random pages: {str(e)}"
|
||||
logging.error(error_msg)
|
||||
return {"error": error_msg}
|
||||
|
||||
def wiki_language(self, language: str) -> bool:
|
||||
"""
|
||||
Set the language for Wikipedia searches.
|
||||
|
||||
Args:
|
||||
language: Language code (e.g., 'en' for English, 'es' for Spanish)
|
||||
|
||||
Returns:
|
||||
bool: True if successful, False if failed
|
||||
"""
|
||||
try:
|
||||
wikipedia.set_lang(language)
|
||||
return True
|
||||
except Exception as e:
|
||||
error_msg = f"Error setting language to '{language}': {str(e)}"
|
||||
logging.error(error_msg)
|
||||
return False
|
||||
|
||||
# Create instance for direct function access
|
||||
_wikipedia_tools = WikipediaTools()
|
||||
wiki_search = _wikipedia_tools.wiki_search
|
||||
wiki_summary = _wikipedia_tools.wiki_summary
|
||||
wiki_page = _wikipedia_tools.wiki_page
|
||||
wiki_random = _wikipedia_tools.wiki_random
|
||||
wiki_language = _wikipedia_tools.wiki_language
|
||||
|
||||
if __name__ == "__main__":
|
||||
# Example usage
|
||||
print("\n==================================================")
|
||||
print("WikipediaTools Demonstration")
|
||||
print("==================================================\n")
|
||||
|
||||
# 1. Search for a topic
|
||||
print("1. Searching Wikipedia")
|
||||
print("------------------------------")
|
||||
search_results = wiki_search("Python programming language")
|
||||
print("Search results:")
|
||||
print(json.dumps(search_results, indent=2))
|
||||
print()
|
||||
|
||||
# 2. Get a page summary
|
||||
print("2. Getting Page Summary")
|
||||
print("------------------------------")
|
||||
summary = wiki_summary("Python programming language", sentences=3)
|
||||
print("Summary:")
|
||||
print(summary)
|
||||
print()
|
||||
|
||||
# 3. Get detailed page information
|
||||
print("3. Getting Full Page Information")
|
||||
print("------------------------------")
|
||||
page = wiki_page("Python programming language")
|
||||
if isinstance(page, dict) and "error" not in page:
|
||||
print("Page sections:")
|
||||
for section in page["sections"]:
|
||||
print(f"- {section['title']} (Level {section['level']})")
|
||||
print(f"\nNumber of references: {len(page['references'])}")
|
||||
print(f"Number of categories: {len(page['categories'])}")
|
||||
print(f"Number of links: {len(page['links'])}")
|
||||
print(f"Number of images: {len(page['images'])}")
|
||||
else:
|
||||
print("Error getting page:", page.get("error"))
|
||||
print()
|
||||
|
||||
# 4. Get random pages
|
||||
print("4. Getting Random Pages")
|
||||
print("------------------------------")
|
||||
random_pages = wiki_random(3)
|
||||
print("Random page titles:")
|
||||
print(json.dumps(random_pages, indent=2))
|
||||
print()
|
||||
|
||||
# 5. Try different language
|
||||
print("5. Changing Language")
|
||||
print("------------------------------")
|
||||
success = wiki_language("es")
|
||||
if success:
|
||||
summary = wiki_summary("Python (lenguaje de programación)", sentences=1)
|
||||
print("Spanish summary:")
|
||||
print(summary)
|
||||
print()
|
||||
|
||||
print("\n==================================================")
|
||||
print("Demonstration Complete")
|
||||
print("==================================================")
|
||||
@@ -0,0 +1,498 @@
|
||||
"""Tools for working with XML files.
|
||||
|
||||
Usage:
|
||||
from praisonaiagents.tools import xml_tools
|
||||
tree = xml_tools.read_xml("data.xml")
|
||||
|
||||
or
|
||||
from praisonaiagents.tools import read_xml, write_xml, transform_xml
|
||||
tree = read_xml("data.xml")
|
||||
"""
|
||||
|
||||
import logging
|
||||
from typing import List, Dict, Union, Optional, Any, Tuple
|
||||
from importlib import util
|
||||
import xml.etree.ElementTree as ET
|
||||
import xml.dom.minidom as minidom
|
||||
from io import StringIO
|
||||
import json
|
||||
|
||||
class XMLTools:
|
||||
"""Tools for working with XML files."""
|
||||
|
||||
def __init__(self):
|
||||
"""Initialize XMLTools."""
|
||||
pass
|
||||
|
||||
def read_xml(
|
||||
self,
|
||||
filepath: str,
|
||||
encoding: str = 'utf-8',
|
||||
validate_schema: Optional[str] = None,
|
||||
parser: str = 'lxml'
|
||||
) -> ET.Element:
|
||||
"""Read an XML file with optional schema validation.
|
||||
|
||||
Args:
|
||||
filepath: Path to XML file
|
||||
encoding: File encoding
|
||||
validate_schema: Optional path to XSD schema file
|
||||
parser: XML parser to use ('lxml' or 'etree')
|
||||
|
||||
Returns:
|
||||
ElementTree root element
|
||||
"""
|
||||
try:
|
||||
if parser == 'lxml':
|
||||
if util.find_spec('lxml') is None:
|
||||
error_msg = "lxml package is not available. Please install it using: pip install lxml"
|
||||
logging.error(error_msg)
|
||||
return None
|
||||
import lxml.etree as lxml_etree
|
||||
tree = lxml_etree.parse(filepath)
|
||||
root = tree.getroot()
|
||||
else:
|
||||
tree = ET.parse(filepath)
|
||||
root = tree.getroot()
|
||||
|
||||
if validate_schema:
|
||||
if util.find_spec('xmlschema') is None:
|
||||
error_msg = "xmlschema package is not available. Please install it using: pip install xmlschema"
|
||||
logging.error(error_msg)
|
||||
return None
|
||||
import xmlschema
|
||||
schema = xmlschema.XMLSchema(validate_schema)
|
||||
if not schema.is_valid(filepath):
|
||||
error_msg = f"XML file does not validate against schema: {schema.validate(filepath)}"
|
||||
logging.error(error_msg)
|
||||
return None
|
||||
|
||||
return root
|
||||
|
||||
except Exception as e:
|
||||
error_msg = f"Error reading XML file {filepath}: {str(e)}"
|
||||
logging.error(error_msg)
|
||||
return None
|
||||
|
||||
def write_xml(
|
||||
self,
|
||||
root: ET.Element,
|
||||
filepath: str,
|
||||
encoding: str = 'utf-8',
|
||||
pretty: bool = True,
|
||||
xml_declaration: bool = True
|
||||
) -> bool:
|
||||
"""Write XML Element tree to file.
|
||||
|
||||
Args:
|
||||
root: XML Element tree root
|
||||
filepath: Output file path
|
||||
encoding: File encoding
|
||||
pretty: Format output with proper indentation
|
||||
xml_declaration: Include XML declaration
|
||||
|
||||
Returns:
|
||||
True if successful, False otherwise
|
||||
"""
|
||||
try:
|
||||
# Convert to string
|
||||
if pretty:
|
||||
xml_str = minidom.parseString(
|
||||
ET.tostring(root, encoding='unicode')
|
||||
).toprettyxml(indent=' ')
|
||||
else:
|
||||
xml_str = ET.tostring(
|
||||
root,
|
||||
encoding='unicode'
|
||||
)
|
||||
|
||||
# Add declaration if requested
|
||||
if xml_declaration:
|
||||
if not xml_str.startswith('<?xml'):
|
||||
xml_str = (
|
||||
f'<?xml version="1.0" encoding="{encoding}"?>\n'
|
||||
+ xml_str
|
||||
)
|
||||
|
||||
# Write to file
|
||||
with open(filepath, 'w', encoding=encoding) as f:
|
||||
f.write(xml_str)
|
||||
|
||||
return True
|
||||
except Exception as e:
|
||||
error_msg = f"Error writing XML file {filepath}: {str(e)}"
|
||||
logging.error(error_msg)
|
||||
return False
|
||||
|
||||
def transform_xml(
|
||||
self,
|
||||
xml_file: str,
|
||||
xslt_file: str,
|
||||
output_file: str,
|
||||
params: Optional[Dict[str, str]] = None
|
||||
) -> bool:
|
||||
"""Transform XML using XSLT stylesheet.
|
||||
|
||||
Args:
|
||||
xml_file: Input XML file
|
||||
xslt_file: XSLT stylesheet file
|
||||
output_file: Output file path
|
||||
params: Optional parameters for transformation
|
||||
|
||||
Returns:
|
||||
True if successful, False otherwise
|
||||
"""
|
||||
try:
|
||||
# Parse XML and XSLT
|
||||
if util.find_spec('lxml') is None:
|
||||
error_msg = "lxml package is not available. Please install it using: pip install lxml"
|
||||
logging.error(error_msg)
|
||||
return False
|
||||
import lxml.etree as lxml_etree
|
||||
xml_doc = lxml_etree.parse(xml_file)
|
||||
xslt_doc = lxml_etree.parse(xslt_file)
|
||||
transform = lxml_etree.XSLT(xslt_doc)
|
||||
|
||||
# Apply transformation
|
||||
if params:
|
||||
result = transform(xml_doc, **params)
|
||||
else:
|
||||
result = transform(xml_doc)
|
||||
|
||||
# Write result
|
||||
result.write(
|
||||
output_file,
|
||||
pretty_print=True,
|
||||
xml_declaration=True,
|
||||
encoding='utf-8'
|
||||
)
|
||||
|
||||
return True
|
||||
except Exception as e:
|
||||
error_msg = f"Error transforming XML: {str(e)}"
|
||||
logging.error(error_msg)
|
||||
return False
|
||||
|
||||
def validate_xml(
|
||||
self,
|
||||
xml_file: str,
|
||||
schema_file: str
|
||||
) -> Tuple[bool, Optional[str]]:
|
||||
"""Validate XML against XSD schema.
|
||||
|
||||
Args:
|
||||
xml_file: XML file to validate
|
||||
schema_file: XSD schema file
|
||||
|
||||
Returns:
|
||||
Tuple of (is_valid, error_message)
|
||||
"""
|
||||
try:
|
||||
if util.find_spec('xmlschema') is None:
|
||||
error_msg = "xmlschema package is not available. Please install it using: pip install xmlschema"
|
||||
logging.error(error_msg)
|
||||
return False, error_msg
|
||||
import xmlschema
|
||||
schema = xmlschema.XMLSchema(schema_file)
|
||||
schema.validate(xml_file)
|
||||
return True, None
|
||||
except xmlschema.validators.exceptions.XMLSchemaValidationError as e:
|
||||
return False, str(e)
|
||||
except Exception as e:
|
||||
error_msg = f"Error validating XML: {str(e)}"
|
||||
logging.error(error_msg)
|
||||
return False, error_msg
|
||||
|
||||
def xml_to_dict(
|
||||
self,
|
||||
root: Union[str, ET.Element],
|
||||
preserve_attrs: bool = True
|
||||
) -> Dict[str, Any]:
|
||||
"""Convert XML to dictionary.
|
||||
|
||||
Args:
|
||||
root: XML string or Element tree root
|
||||
preserve_attrs: Keep XML attributes in result
|
||||
|
||||
Returns:
|
||||
Dict representation of XML
|
||||
"""
|
||||
try:
|
||||
# Parse XML if string
|
||||
if isinstance(root, str):
|
||||
if root.startswith('<'):
|
||||
root = ET.fromstring(root)
|
||||
else:
|
||||
root = ET.parse(root).getroot()
|
||||
|
||||
result = {}
|
||||
|
||||
# Add attributes if present and requested
|
||||
if preserve_attrs and root.attrib:
|
||||
result['@attributes'] = dict(root.attrib)
|
||||
|
||||
# Add children
|
||||
children = list(root)
|
||||
if not children:
|
||||
text = root.text
|
||||
if text is not None and text.strip():
|
||||
result = text.strip()
|
||||
else:
|
||||
for child in children:
|
||||
child_data = self.xml_to_dict(child, preserve_attrs)
|
||||
if child.tag in result:
|
||||
if not isinstance(result[child.tag], list):
|
||||
result[child.tag] = [result[child.tag]]
|
||||
result[child.tag].append(child_data)
|
||||
else:
|
||||
result[child.tag] = child_data
|
||||
|
||||
return result
|
||||
except Exception as e:
|
||||
error_msg = f"Error converting XML to dict: {str(e)}"
|
||||
logging.error(error_msg)
|
||||
return {}
|
||||
|
||||
def dict_to_xml(
|
||||
self,
|
||||
data: Dict[str, Any],
|
||||
root_tag: str = 'root'
|
||||
) -> Optional[ET.Element]:
|
||||
"""Convert dictionary to XML.
|
||||
|
||||
Args:
|
||||
data: Dictionary to convert
|
||||
root_tag: Tag for root element
|
||||
|
||||
Returns:
|
||||
XML Element tree root
|
||||
"""
|
||||
try:
|
||||
def _create_element(
|
||||
parent: ET.Element,
|
||||
key: str,
|
||||
value: Any
|
||||
):
|
||||
"""Create XML element from key-value pair."""
|
||||
if key == '@attributes':
|
||||
for attr_key, attr_val in value.items():
|
||||
parent.set(attr_key, str(attr_val))
|
||||
elif isinstance(value, dict):
|
||||
child = ET.SubElement(parent, key)
|
||||
for k, v in value.items():
|
||||
_create_element(child, k, v)
|
||||
elif isinstance(value, list):
|
||||
for item in value:
|
||||
child = ET.SubElement(parent, key)
|
||||
if isinstance(item, dict):
|
||||
for k, v in item.items():
|
||||
_create_element(child, k, v)
|
||||
else:
|
||||
child.text = str(item)
|
||||
else:
|
||||
child = ET.SubElement(parent, key)
|
||||
child.text = str(value)
|
||||
|
||||
root = ET.Element(root_tag)
|
||||
for key, value in data.items():
|
||||
_create_element(root, key, value)
|
||||
|
||||
return root
|
||||
except Exception as e:
|
||||
error_msg = f"Error converting dict to XML: {str(e)}"
|
||||
logging.error(error_msg)
|
||||
return None
|
||||
|
||||
def xpath_query(
|
||||
self,
|
||||
root: Union[str, ET.Element],
|
||||
query: str,
|
||||
namespaces: Optional[Dict[str, str]] = None
|
||||
) -> List[ET.Element]:
|
||||
"""Execute XPath query on XML.
|
||||
|
||||
Args:
|
||||
root: XML string or Element tree root
|
||||
query: XPath query string
|
||||
namespaces: Optional namespace mappings
|
||||
|
||||
Returns:
|
||||
List of matching elements
|
||||
"""
|
||||
try:
|
||||
# Parse XML if string
|
||||
if isinstance(root, str):
|
||||
if root.startswith('<'):
|
||||
if util.find_spec('lxml') is None:
|
||||
error_msg = "lxml package is not available. Please install it using: pip install lxml"
|
||||
logging.error(error_msg)
|
||||
return []
|
||||
import lxml.etree as lxml_etree
|
||||
tree = lxml_etree.fromstring(root)
|
||||
else:
|
||||
tree = ET.parse(root)
|
||||
else:
|
||||
if util.find_spec('lxml') is None:
|
||||
error_msg = "lxml package is not available. Please install it using: pip install lxml"
|
||||
logging.error(error_msg)
|
||||
return []
|
||||
import lxml.etree as lxml_etree
|
||||
tree = lxml_etree.fromstring(
|
||||
ET.tostring(root, encoding='unicode')
|
||||
)
|
||||
|
||||
# Execute query
|
||||
results = tree.xpath(
|
||||
query,
|
||||
namespaces=namespaces or {}
|
||||
)
|
||||
|
||||
# Convert results to standard ElementTree elements
|
||||
return [
|
||||
ET.fromstring(lxml_etree.tostring(elem, encoding='unicode'))
|
||||
for elem in results
|
||||
]
|
||||
except Exception as e:
|
||||
error_msg = f"Error executing XPath query: {str(e)}"
|
||||
logging.error(error_msg)
|
||||
return []
|
||||
|
||||
# Create instance for direct function access
|
||||
_xml_tools = XMLTools()
|
||||
read_xml = _xml_tools.read_xml
|
||||
write_xml = _xml_tools.write_xml
|
||||
transform_xml = _xml_tools.transform_xml
|
||||
validate_xml = _xml_tools.validate_xml
|
||||
xml_to_dict = _xml_tools.xml_to_dict
|
||||
dict_to_xml = _xml_tools.dict_to_xml
|
||||
xpath_query = _xml_tools.xpath_query
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("\n==================================================")
|
||||
print("XMLTools Demonstration")
|
||||
print("==================================================\n")
|
||||
|
||||
# Create temporary files
|
||||
import tempfile
|
||||
import os
|
||||
|
||||
temp_file = tempfile.mktemp(suffix='.xml')
|
||||
try:
|
||||
print("1. Creating XML Document")
|
||||
print("------------------------------")
|
||||
xml_content = """<?xml version="1.0" encoding="UTF-8"?>
|
||||
<bookstore>
|
||||
<book category="fiction">
|
||||
<title>The Great Gatsby</title>
|
||||
<author>F. Scott Fitzgerald</author>
|
||||
<year>1925</year>
|
||||
<price>10.99</price>
|
||||
</book>
|
||||
<book category="non-fiction">
|
||||
<title>A Brief History of Time</title>
|
||||
<author>Stephen Hawking</author>
|
||||
<year>1988</year>
|
||||
<price>15.99</price>
|
||||
</book>
|
||||
</bookstore>"""
|
||||
|
||||
with open(temp_file, 'w') as f:
|
||||
f.write(xml_content)
|
||||
print("Sample XML file created")
|
||||
print()
|
||||
|
||||
print("2. Parsing XML")
|
||||
print("------------------------------")
|
||||
result = read_xml(temp_file)
|
||||
print("XML structure:")
|
||||
print(minidom.parseString(ET.tostring(result, encoding='unicode')).toprettyxml(indent=' '))
|
||||
print()
|
||||
|
||||
print("3. Querying XML")
|
||||
print("------------------------------")
|
||||
xpath = "//book[@category='fiction']/title/text()"
|
||||
result = xpath_query(result, xpath)
|
||||
print(f"Fiction book titles (XPath: {xpath}):")
|
||||
for title in result:
|
||||
print(title.text)
|
||||
print()
|
||||
|
||||
print("4. Validating XML")
|
||||
print("------------------------------")
|
||||
schema_file = tempfile.mktemp(suffix='.xsd')
|
||||
schema_content = """<?xml version="1.0" encoding="UTF-8"?>
|
||||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
||||
<xs:element name="bookstore">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element name="book" maxOccurs="unbounded">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element name="title" type="xs:string"/>
|
||||
<xs:element name="author" type="xs:string"/>
|
||||
<xs:element name="year" type="xs:integer"/>
|
||||
<xs:element name="price" type="xs:decimal"/>
|
||||
</xs:sequence>
|
||||
<xs:attribute name="category" type="xs:string"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:schema>"""
|
||||
with open(schema_file, 'w') as f:
|
||||
f.write(schema_content)
|
||||
result, error = validate_xml(temp_file, schema_file)
|
||||
print(f"XML validation result: {result}")
|
||||
if error:
|
||||
print(f"Error: {error}")
|
||||
print()
|
||||
|
||||
print("5. Transforming XML")
|
||||
print("------------------------------")
|
||||
xslt_content = """<?xml version="1.0" encoding="UTF-8"?>
|
||||
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
|
||||
<xsl:template match="/">
|
||||
<html>
|
||||
<body>
|
||||
<h2>Bookstore Inventory</h2>
|
||||
<table>
|
||||
<tr>
|
||||
<th>Title</th>
|
||||
<th>Author</th>
|
||||
<th>Price</th>
|
||||
</tr>
|
||||
<xsl:for-each select="bookstore/book">
|
||||
<tr>
|
||||
<td><xsl:value-of select="title"/></td>
|
||||
<td><xsl:value-of select="author"/></td>
|
||||
<td><xsl:value-of select="price"/></td>
|
||||
</tr>
|
||||
</xsl:for-each>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
</xsl:template>
|
||||
</xsl:stylesheet>"""
|
||||
|
||||
xslt_file = tempfile.mktemp(suffix='.xslt')
|
||||
with open(xslt_file, 'w') as f:
|
||||
f.write(xslt_content)
|
||||
|
||||
output_file = tempfile.mktemp(suffix='.html')
|
||||
result = transform_xml(temp_file, xslt_file, output_file)
|
||||
print(f"XML transformation result: {result}")
|
||||
if result and os.path.exists(output_file):
|
||||
print("\nTransformed HTML content:")
|
||||
with open(output_file, 'r') as f:
|
||||
print(f.read())
|
||||
|
||||
finally:
|
||||
# Clean up temporary files
|
||||
for file in [temp_file, schema_file, xslt_file, output_file]:
|
||||
if os.path.exists(file):
|
||||
os.unlink(file)
|
||||
|
||||
print("\n==================================================")
|
||||
print("Demonstration Complete")
|
||||
print("==================================================")
|
||||
@@ -0,0 +1,417 @@
|
||||
"""Tools for working with YAML files.
|
||||
|
||||
Usage:
|
||||
from praisonaiagents.tools import yaml_tools
|
||||
data = yaml_tools.read_yaml("config.yaml")
|
||||
|
||||
or
|
||||
from praisonaiagents.tools import read_yaml, write_yaml, merge_yaml
|
||||
data = read_yaml("config.yaml")
|
||||
"""
|
||||
|
||||
import logging
|
||||
from typing import List, Dict, Union, Optional, Any
|
||||
from importlib import util
|
||||
import os
|
||||
from copy import deepcopy
|
||||
|
||||
class YAMLTools:
|
||||
"""Tools for working with YAML files."""
|
||||
|
||||
def __init__(self):
|
||||
"""Initialize YAMLTools."""
|
||||
self._check_dependencies()
|
||||
|
||||
def _check_dependencies(self):
|
||||
"""Check if required packages are installed."""
|
||||
missing = []
|
||||
for package, module in [('pyyaml', 'yaml'), ('jsonschema', 'jsonschema')]:
|
||||
if util.find_spec(module) is None:
|
||||
missing.append(package)
|
||||
|
||||
if missing:
|
||||
raise ImportError(
|
||||
f"Required packages not available. Please install: {', '.join(missing)}\n"
|
||||
f"Run: pip install {' '.join(missing)}"
|
||||
)
|
||||
|
||||
def read_yaml(
|
||||
self,
|
||||
filepath: str,
|
||||
safe_load: bool = True,
|
||||
encoding: str = 'utf-8'
|
||||
) -> Optional[Union[Dict[str, Any], List[Any]]]:
|
||||
"""Read a YAML file."""
|
||||
try:
|
||||
if util.find_spec('yaml') is None:
|
||||
error_msg = "pyyaml package is not available. Please install it using: pip install pyyaml"
|
||||
logging.error(error_msg)
|
||||
return None
|
||||
|
||||
# Import yaml only when needed
|
||||
import yaml
|
||||
|
||||
with open(filepath, 'r', encoding=encoding) as f:
|
||||
if safe_load:
|
||||
return yaml.safe_load(f)
|
||||
return yaml.load(f, Loader=yaml.FullLoader)
|
||||
except Exception as e:
|
||||
error_msg = f"Error reading YAML file {filepath}: {str(e)}"
|
||||
logging.error(error_msg)
|
||||
return None
|
||||
|
||||
def write_yaml(
|
||||
self,
|
||||
data: Union[Dict[str, Any], List[Any]],
|
||||
filepath: str,
|
||||
default_flow_style: bool = False,
|
||||
encoding: str = 'utf-8',
|
||||
sort_keys: bool = False,
|
||||
allow_unicode: bool = True
|
||||
) -> bool:
|
||||
"""Write data to YAML file."""
|
||||
try:
|
||||
if util.find_spec('yaml') is None:
|
||||
error_msg = "pyyaml package is not available. Please install it using: pip install pyyaml"
|
||||
logging.error(error_msg)
|
||||
return False
|
||||
|
||||
# Import yaml only when needed
|
||||
import yaml
|
||||
|
||||
with open(filepath, 'w', encoding=encoding) as f:
|
||||
yaml.dump(
|
||||
data,
|
||||
f,
|
||||
default_flow_style=default_flow_style,
|
||||
sort_keys=sort_keys,
|
||||
allow_unicode=allow_unicode
|
||||
)
|
||||
return True
|
||||
except Exception as e:
|
||||
error_msg = f"Error writing YAML file {filepath}: {str(e)}"
|
||||
logging.error(error_msg)
|
||||
return False
|
||||
|
||||
def merge_yaml(
|
||||
self,
|
||||
files: List[str],
|
||||
output_file: Optional[str] = None,
|
||||
strategy: str = 'deep'
|
||||
) -> Union[Dict[str, Any], List[Any], None]:
|
||||
"""Merge multiple YAML files."""
|
||||
try:
|
||||
if util.find_spec('yaml') is None:
|
||||
error_msg = "pyyaml package is not available. Please install it using: pip install pyyaml"
|
||||
logging.error(error_msg)
|
||||
return None
|
||||
|
||||
def deep_merge(source: dict, destination: dict) -> dict:
|
||||
"""Deep merge two dictionaries."""
|
||||
for key, value in source.items():
|
||||
if key in destination:
|
||||
if isinstance(value, dict) and isinstance(destination[key], dict):
|
||||
destination[key] = deep_merge(value, destination[key])
|
||||
elif isinstance(value, list) and isinstance(destination[key], list):
|
||||
destination[key].extend(value)
|
||||
else:
|
||||
destination[key] = value
|
||||
else:
|
||||
destination[key] = value
|
||||
return destination
|
||||
|
||||
result = {}
|
||||
for file in files:
|
||||
data = self.read_yaml(file)
|
||||
if data is None:
|
||||
continue
|
||||
|
||||
if strategy == 'deep':
|
||||
if isinstance(data, dict):
|
||||
result = deep_merge(data, result)
|
||||
elif isinstance(data, list):
|
||||
if not result:
|
||||
result = []
|
||||
result.extend(data)
|
||||
else: # shallow
|
||||
if isinstance(data, dict):
|
||||
result.update(data)
|
||||
elif isinstance(data, list):
|
||||
if not result:
|
||||
result = []
|
||||
result.extend(data)
|
||||
|
||||
if output_file:
|
||||
self.write_yaml(result, output_file)
|
||||
|
||||
return result
|
||||
except Exception as e:
|
||||
error_msg = f"Error merging YAML files: {str(e)}"
|
||||
logging.error(error_msg)
|
||||
return None
|
||||
|
||||
def validate_yaml(
|
||||
self,
|
||||
data: Union[Dict[str, Any], List[Any], str],
|
||||
schema: Dict[str, Any]
|
||||
) -> bool:
|
||||
"""Validate YAML data against a schema."""
|
||||
try:
|
||||
if util.find_spec('jsonschema') is None:
|
||||
error_msg = "jsonschema package is not available. Please install it using: pip install jsonschema"
|
||||
logging.error(error_msg)
|
||||
return False
|
||||
|
||||
# Import jsonschema only when needed
|
||||
from jsonschema import validate, ValidationError
|
||||
|
||||
# Load data if file path
|
||||
if isinstance(data, str):
|
||||
data = self.read_yaml(data)
|
||||
if data is None:
|
||||
return False
|
||||
|
||||
try:
|
||||
validate(instance=data, schema=schema)
|
||||
return True
|
||||
except ValidationError as e:
|
||||
logging.error(f"YAML validation error: {str(e)}")
|
||||
return False
|
||||
except Exception as e:
|
||||
error_msg = f"Error validating YAML: {str(e)}"
|
||||
logging.error(error_msg)
|
||||
return False
|
||||
|
||||
def analyze_yaml(
|
||||
self,
|
||||
data: Union[Dict[str, Any], List[Any], str]
|
||||
) -> Optional[Dict[str, Any]]:
|
||||
"""Analyze YAML data structure."""
|
||||
try:
|
||||
# Load data if file path
|
||||
if isinstance(data, str):
|
||||
data = self.read_yaml(data)
|
||||
if data is None:
|
||||
return None
|
||||
|
||||
def analyze_value(value: Any) -> Dict[str, Any]:
|
||||
"""Analyze a single value."""
|
||||
result = {
|
||||
'type': type(value).__name__,
|
||||
'size': len(value) if hasattr(value, '__len__') else 1
|
||||
}
|
||||
|
||||
if isinstance(value, dict):
|
||||
result['keys'] = list(value.keys())
|
||||
result['nested_types'] = {
|
||||
k: type(v).__name__
|
||||
for k, v in value.items()
|
||||
}
|
||||
elif isinstance(value, list):
|
||||
result['element_types'] = list(set(
|
||||
type(x).__name__ for x in value
|
||||
))
|
||||
|
||||
return result
|
||||
|
||||
result = {
|
||||
'structure': analyze_value(data),
|
||||
'stats': {
|
||||
'total_keys': sum(1 for _ in self._walk_dict(data))
|
||||
if isinstance(data, dict) else len(data)
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
except Exception as e:
|
||||
error_msg = f"Error analyzing YAML: {str(e)}"
|
||||
logging.error(error_msg)
|
||||
return None
|
||||
|
||||
def _walk_dict(self, d: Dict[str, Any]) -> Any:
|
||||
"""Walk through nested dictionary."""
|
||||
for k, v in d.items():
|
||||
yield k
|
||||
if isinstance(v, dict):
|
||||
yield from self._walk_dict(v)
|
||||
|
||||
def transform_yaml(
|
||||
self,
|
||||
data: Union[Dict[str, Any], List[Any], str],
|
||||
operations: List[Dict[str, Any]]
|
||||
) -> Optional[Union[Dict[str, Any], List[Any]]]:
|
||||
"""Transform YAML data using specified operations."""
|
||||
try:
|
||||
# Load data if file path
|
||||
if isinstance(data, str):
|
||||
data = self.read_yaml(data)
|
||||
if data is None:
|
||||
return None
|
||||
|
||||
result = deepcopy(data)
|
||||
|
||||
for op in operations:
|
||||
op_type = op.get('type')
|
||||
path = op.get('path', '')
|
||||
value = op.get('value')
|
||||
|
||||
if not op_type:
|
||||
continue
|
||||
|
||||
# Split path into parts
|
||||
parts = [p for p in path.split('/') if p]
|
||||
|
||||
# Get reference to target location
|
||||
target = result
|
||||
parent = None
|
||||
last_key = None
|
||||
|
||||
for part in parts[:-1]:
|
||||
if isinstance(target, dict):
|
||||
if part not in target:
|
||||
target[part] = {}
|
||||
parent = target
|
||||
target = target[part]
|
||||
last_key = part
|
||||
elif isinstance(target, list):
|
||||
idx = int(part)
|
||||
while len(target) <= idx:
|
||||
target.append({})
|
||||
parent = target
|
||||
target = target[idx]
|
||||
last_key = idx
|
||||
|
||||
if parts:
|
||||
last_part = parts[-1]
|
||||
if isinstance(target, dict):
|
||||
if op_type == 'set':
|
||||
target[last_part] = value
|
||||
elif op_type == 'delete':
|
||||
target.pop(last_part, None)
|
||||
elif op_type == 'append' and isinstance(target.get(last_part), list):
|
||||
target[last_part].append(value)
|
||||
elif isinstance(target, list):
|
||||
idx = int(last_part)
|
||||
if op_type == 'set':
|
||||
while len(target) <= idx:
|
||||
target.append(None)
|
||||
target[idx] = value
|
||||
elif op_type == 'delete' and idx < len(target):
|
||||
del target[idx]
|
||||
elif op_type == 'append':
|
||||
target.append(value)
|
||||
else:
|
||||
if op_type == 'set':
|
||||
result = value
|
||||
elif op_type == 'append' and isinstance(result, list):
|
||||
result.append(value)
|
||||
|
||||
return result
|
||||
except Exception as e:
|
||||
error_msg = f"Error transforming YAML: {str(e)}"
|
||||
logging.error(error_msg)
|
||||
return None
|
||||
|
||||
# Create instance for direct function access
|
||||
_yaml_tools = YAMLTools()
|
||||
read_yaml = _yaml_tools.read_yaml
|
||||
write_yaml = _yaml_tools.write_yaml
|
||||
merge_yaml = _yaml_tools.merge_yaml
|
||||
validate_yaml = _yaml_tools.validate_yaml
|
||||
analyze_yaml = _yaml_tools.analyze_yaml
|
||||
transform_yaml = _yaml_tools.transform_yaml
|
||||
|
||||
if __name__ == "__main__":
|
||||
# Example usage
|
||||
print("\n==================================================")
|
||||
print("YAMLTools Demonstration")
|
||||
print("==================================================\n")
|
||||
|
||||
# Sample data
|
||||
data1 = {
|
||||
'server': {
|
||||
'host': 'localhost',
|
||||
'port': 8080,
|
||||
'debug': True
|
||||
},
|
||||
'database': {
|
||||
'url': 'postgresql://localhost:5432/db',
|
||||
'pool_size': 5
|
||||
}
|
||||
}
|
||||
|
||||
data2 = {
|
||||
'server': {
|
||||
'workers': 4,
|
||||
'timeout': 30
|
||||
},
|
||||
'logging': {
|
||||
'level': 'INFO',
|
||||
'file': 'app.log'
|
||||
}
|
||||
}
|
||||
|
||||
# 1. Write YAML files
|
||||
print("1. Writing YAML Files")
|
||||
print("------------------------------")
|
||||
success1 = write_yaml(data1, 'config1.yaml')
|
||||
success2 = write_yaml(data2, 'config2.yaml')
|
||||
print(f"First file written: {success1}")
|
||||
print(f"Second file written: {success2}")
|
||||
print()
|
||||
|
||||
# 2. Read YAML file
|
||||
print("2. Reading YAML File")
|
||||
print("------------------------------")
|
||||
config = read_yaml('config1.yaml')
|
||||
print("YAML content:")
|
||||
print(config)
|
||||
print()
|
||||
|
||||
# 3. Merge YAML files
|
||||
print("3. Merging YAML Files")
|
||||
print("------------------------------")
|
||||
merged = merge_yaml(['config1.yaml', 'config2.yaml'])
|
||||
print("Merged content:")
|
||||
print(merged)
|
||||
print()
|
||||
|
||||
# 4. Analyze YAML
|
||||
print("4. Analyzing YAML")
|
||||
print("------------------------------")
|
||||
analysis = analyze_yaml(merged)
|
||||
print("Analysis results:")
|
||||
print(analysis)
|
||||
print()
|
||||
|
||||
# 5. Transform YAML
|
||||
print("5. Transforming YAML")
|
||||
print("------------------------------")
|
||||
operations = [
|
||||
{
|
||||
'type': 'set',
|
||||
'path': 'server/host',
|
||||
'value': '0.0.0.0'
|
||||
},
|
||||
{
|
||||
'type': 'delete',
|
||||
'path': 'server/debug'
|
||||
},
|
||||
{
|
||||
'type': 'set',
|
||||
'path': 'logging/handlers',
|
||||
'value': ['console', 'file']
|
||||
}
|
||||
]
|
||||
transformed = transform_yaml(merged, operations)
|
||||
print("Transformed content:")
|
||||
print(transformed)
|
||||
|
||||
print("\n==================================================")
|
||||
print("Demonstration Complete")
|
||||
print("==================================================")
|
||||
|
||||
# Cleanup
|
||||
for file in ['config1.yaml', 'config2.yaml']:
|
||||
if os.path.exists(file):
|
||||
os.remove(file)
|
||||
@@ -0,0 +1,213 @@
|
||||
"""YFinance tools for stock market data.
|
||||
|
||||
Usage:
|
||||
from praisonaiagents.tools import get_stock_price, get_stock_info
|
||||
price = get_stock_price("AAPL")
|
||||
info = get_stock_info("AAPL")
|
||||
|
||||
or
|
||||
from praisonaiagents.tools import yfinance
|
||||
price = yfinance.get_stock_price("AAPL")
|
||||
info = yfinance.get_stock_info("AAPL")
|
||||
"""
|
||||
|
||||
from typing import List, Dict, Optional, Any
|
||||
import logging
|
||||
from importlib import util
|
||||
from datetime import datetime
|
||||
|
||||
class YFinanceTools:
|
||||
"""A comprehensive tool for financial data analysis using yfinance"""
|
||||
|
||||
def __init__(self):
|
||||
"""Initialize YFinanceTools"""
|
||||
self._tickers = {}
|
||||
|
||||
def _get_yfinance(self):
|
||||
"""Get yfinance module, installing if needed"""
|
||||
if util.find_spec('yfinance') is None:
|
||||
error_msg = "yfinance package is not available. Please install it using: pip install yfinance"
|
||||
logging.error(error_msg)
|
||||
return None
|
||||
import yfinance as yf
|
||||
return yf
|
||||
|
||||
def _get_ticker(self, symbol: str):
|
||||
"""Get or create ticker instance"""
|
||||
if symbol not in self._tickers:
|
||||
yf = self._get_yfinance()
|
||||
if yf is None:
|
||||
return None
|
||||
self._tickers[symbol] = yf.Ticker(symbol)
|
||||
return self._tickers[symbol]
|
||||
|
||||
def get_stock_price(self, symbol: str) -> Dict[str, float]:
|
||||
"""
|
||||
Get current stock price and related price metrics
|
||||
|
||||
Args:
|
||||
symbol (str): Stock ticker symbol
|
||||
|
||||
Returns:
|
||||
Dict[str, float]: Current price information
|
||||
"""
|
||||
try:
|
||||
ticker = self._get_ticker(symbol)
|
||||
if ticker is None:
|
||||
return {"error": "yfinance package not available"}
|
||||
|
||||
info = ticker.info
|
||||
return {
|
||||
'symbol': symbol,
|
||||
'price': info.get('regularMarketPrice', 0.0),
|
||||
'open': info.get('regularMarketOpen', 0.0),
|
||||
'high': info.get('regularMarketDayHigh', 0.0),
|
||||
'low': info.get('regularMarketDayLow', 0.0),
|
||||
'volume': info.get('regularMarketVolume', 0),
|
||||
'previous_close': info.get('regularMarketPreviousClose', 0.0),
|
||||
'change': info.get('regularMarketChange', 0.0),
|
||||
'change_percent': info.get('regularMarketChangePercent', 0.0)
|
||||
}
|
||||
except Exception as e:
|
||||
error_msg = f"Error getting stock price for {symbol}: {str(e)}"
|
||||
logging.error(error_msg)
|
||||
return {"error": error_msg}
|
||||
|
||||
def get_stock_info(self, symbol: str) -> Dict:
|
||||
"""
|
||||
Get detailed information about a stock
|
||||
|
||||
Args:
|
||||
symbol (str): Stock ticker symbol
|
||||
|
||||
Returns:
|
||||
Dict: Stock information including company details and key metrics
|
||||
"""
|
||||
try:
|
||||
ticker = self._get_ticker(symbol)
|
||||
if ticker is None:
|
||||
return {"error": "yfinance package not available"}
|
||||
|
||||
info = ticker.info
|
||||
|
||||
relevant_info = {
|
||||
"longName": info.get("longName"),
|
||||
"symbol": info.get("symbol"),
|
||||
"sector": info.get("sector"),
|
||||
"industry": info.get("industry"),
|
||||
"country": info.get("country"),
|
||||
"marketCap": info.get("marketCap"),
|
||||
"currentPrice": info.get("currentPrice"),
|
||||
"currency": info.get("currency"),
|
||||
"exchange": info.get("exchange"),
|
||||
"fiftyTwoWeekHigh": info.get("fiftyTwoWeekHigh"),
|
||||
"fiftyTwoWeekLow": info.get("fiftyTwoWeekLow"),
|
||||
"trailingPE": info.get("trailingPE"),
|
||||
"forwardPE": info.get("forwardPE"),
|
||||
"dividendYield": info.get("dividendYield"),
|
||||
"beta": info.get("beta"),
|
||||
"volume": info.get("volume"),
|
||||
"averageVolume": info.get("averageVolume"),
|
||||
"sharesOutstanding": info.get("sharesOutstanding"),
|
||||
"website": info.get("website"),
|
||||
"longBusinessSummary": info.get("longBusinessSummary")
|
||||
}
|
||||
return {k: v for k, v in relevant_info.items() if v is not None}
|
||||
except Exception as e:
|
||||
error_msg = f"Error fetching stock info: {str(e)}"
|
||||
logging.error(error_msg)
|
||||
return {"error": error_msg}
|
||||
|
||||
def get_historical_data(
|
||||
self,
|
||||
symbol: str,
|
||||
period: str = "1y",
|
||||
interval: str = "1d",
|
||||
start: Optional[datetime] = None,
|
||||
end: Optional[datetime] = None
|
||||
) -> List[Dict[str, Any]]:
|
||||
"""
|
||||
Get historical price data for a stock
|
||||
|
||||
Args:
|
||||
symbol (str): Stock ticker symbol
|
||||
period (str): Data period e.g. 1d, 5d, 1mo, 3mo, 6mo, 1y, 2y, 5y, 10y, ytd, max
|
||||
interval (str): Data interval e.g. 1m, 2m, 5m, 15m, 30m, 60m, 90m, 1h, 1d, 5d, 1wk, 1mo, 3mo
|
||||
start (datetime, optional): Start date for data
|
||||
end (datetime, optional): End date for data
|
||||
|
||||
Returns:
|
||||
List[Dict[str, Any]]: List of historical price data points
|
||||
"""
|
||||
try:
|
||||
ticker = self._get_ticker(symbol)
|
||||
if ticker is None:
|
||||
return [{"error": "yfinance package not available"}]
|
||||
|
||||
hist = ticker.history(period=period, interval=interval, start=start, end=end)
|
||||
return hist.reset_index().to_dict('records')
|
||||
except Exception as e:
|
||||
error_msg = f"Error fetching historical data: {str(e)}"
|
||||
logging.error(error_msg)
|
||||
return [{"error": error_msg}]
|
||||
|
||||
if __name__ == "__main__":
|
||||
# Example usage
|
||||
print("\n==================================================")
|
||||
print("YFinanceTools Demonstration")
|
||||
print("==================================================\n")
|
||||
|
||||
try:
|
||||
yf_tools = YFinanceTools()
|
||||
|
||||
# 1. Basic Stock Information
|
||||
print("1. Basic Stock Information for AAPL")
|
||||
print("------------------------------")
|
||||
info = yf_tools.get_stock_info("AAPL")
|
||||
if "error" not in info:
|
||||
print(f"Company: {info.get('longName')}")
|
||||
print(f"Sector: {info.get('sector')}")
|
||||
print(f"Industry: {info.get('industry')}")
|
||||
print(f"Country: {info.get('country')}\n")
|
||||
else:
|
||||
print(f"Error: {info['error']}\n")
|
||||
|
||||
# 2. Current Price Data
|
||||
print("2. Current Price Data")
|
||||
print("------------------------------")
|
||||
price_data = yf_tools.get_stock_price("AAPL")
|
||||
if "error" not in price_data:
|
||||
print(f"Current Price: ${price_data.get('price', 'N/A')}")
|
||||
print(f"Previous Close: ${price_data.get('previous_close', 'N/A')}")
|
||||
print(f"Day Range: ${price_data.get('low', 'N/A')} - ${price_data.get('high', 'N/A')}\n")
|
||||
else:
|
||||
print(f"Error: {price_data['error']}\n")
|
||||
|
||||
# 3. Historical Data
|
||||
print("3. Historical Data (Last 5 Days)")
|
||||
print("------------------------------")
|
||||
hist_data = yf_tools.get_historical_data("AAPL", period="5d")
|
||||
if not any("error" in d for d in hist_data):
|
||||
for day in hist_data:
|
||||
print(f"Date: {day.get('Date')}, Close: ${day.get('Close', 'N/A'):.2f}")
|
||||
print()
|
||||
else:
|
||||
print(f"{hist_data[0]['error']}\n")
|
||||
|
||||
# 4. Multi-Stock Example
|
||||
print("5. Multi-Stock Current Prices")
|
||||
print("------------------------------")
|
||||
for symbol in ["AAPL", "MSFT", "GOOGL"]:
|
||||
price_data = yf_tools.get_stock_price(symbol)
|
||||
if "error" not in price_data:
|
||||
print(f"{symbol}: ${price_data.get('price', 'N/A')}")
|
||||
else:
|
||||
print(f"{symbol}: Error fetching price")
|
||||
print()
|
||||
|
||||
except Exception as e:
|
||||
print(f"Error: {str(e)}")
|
||||
|
||||
print("==================================================")
|
||||
print("Analysis Complete")
|
||||
print("==================================================")
|
||||
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
||||
|
||||
[project]
|
||||
name = "praisonaiagents"
|
||||
version = "0.0.20"
|
||||
version = "0.0.27"
|
||||
description = "Praison AI agents for completing complex tasks with Self Reflection Agents"
|
||||
authors = [
|
||||
{ name="Mervin Praison" }
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
from praisonaiagents import Agent, Task, PraisonAIAgents, Tools
|
||||
from pydantic import BaseModel
|
||||
|
||||
class AnalysisReport(BaseModel):
|
||||
title: str
|
||||
findings: str
|
||||
summary: str
|
||||
|
||||
# Create a researcher agent
|
||||
researcher = Agent(
|
||||
name="AIResearcher",
|
||||
role="Technology Research Analyst",
|
||||
goal="Analyze and structure information about AI developments",
|
||||
backstory="Expert analyst specializing in AI technology trends",
|
||||
verbose=True,
|
||||
llm="gpt-4o-mini",
|
||||
tools=[Tools.internet_search],
|
||||
self_reflect=False
|
||||
)
|
||||
|
||||
# Create an analyst agent
|
||||
analyst = Agent(
|
||||
name="DataAnalyst",
|
||||
role="Data Insights Specialist",
|
||||
goal="Structure and analyze research findings",
|
||||
backstory="Senior data analyst with expertise in pattern recognition",
|
||||
verbose=True,
|
||||
llm="gpt-4o-mini",
|
||||
self_reflect=False
|
||||
)
|
||||
|
||||
# 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. No additional text or explanation.",
|
||||
agent=analyst,
|
||||
output_json=AnalysisReport,
|
||||
expected_output="JSON object"
|
||||
)
|
||||
|
||||
# Initialize and run agents
|
||||
agents = PraisonAIAgents(
|
||||
agents=[researcher, analyst],
|
||||
tasks=[research_task, analysis_task],
|
||||
process="sequential",
|
||||
verbose=True
|
||||
)
|
||||
result = agents.start()
|
||||
print(result)
|
||||
@@ -0,0 +1,30 @@
|
||||
from praisonaiagents import Agent, Task, PraisonAIAgents
|
||||
from praisonaiagents.tools import get_article, get_news_sources, get_articles_from_source, get_trending_topics
|
||||
|
||||
# Create Wikipedia agent
|
||||
news_agent = Agent(
|
||||
name="NewsAgent",
|
||||
role="News Analyst",
|
||||
goal="Collect and analyze news articles from various sources.",
|
||||
backstory="Expert in news gathering and content analysis.",
|
||||
tools=[get_article, get_news_sources, get_articles_from_source, get_trending_topics],
|
||||
self_reflect=False
|
||||
)
|
||||
|
||||
|
||||
# Define research task
|
||||
news_task = Task(
|
||||
description="Analyze news articles about 'AI developments' from major tech news sources.",
|
||||
expected_output="Summary of key AI developments with source articles.",
|
||||
agent=news_agent,
|
||||
name="ai_news"
|
||||
)
|
||||
|
||||
|
||||
# Run agent
|
||||
agents = PraisonAIAgents(
|
||||
agents=[news_agent],
|
||||
tasks=[news_task],
|
||||
process="sequential"
|
||||
)
|
||||
agents.start()
|
||||
Generated
+2
-2
@@ -186,7 +186,7 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "praisonaiagents"
|
||||
version = "0.0.20"
|
||||
version = "0.0.27"
|
||||
source = { editable = "." }
|
||||
dependencies = [
|
||||
{ name = "openai" },
|
||||
@@ -304,7 +304,7 @@ name = "tqdm"
|
||||
version = "4.67.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "colorama", marker = "platform_system == 'Windows'" },
|
||||
{ name = "colorama", marker = "sys_platform == 'win32'" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/a8/4b/29b4ef32e036bb34e4ab51796dd745cdba7ed47ad142a9f4a1eb8e0c744d/tqdm-4.67.1.tar.gz", hash = "sha256:f8aef9c52c08c13a65f30ea34f4e5aac3fd1a34959879d7e59e63027286627f2", size = 169737 }
|
||||
wheels = [
|
||||
|
||||
@@ -110,7 +110,7 @@ Loads environment variables from .env file or system and sets them.</p>
|
||||
file.write("FROM python:3.11-slim\n")
|
||||
file.write("WORKDIR /app\n")
|
||||
file.write("COPY . .\n")
|
||||
file.write("RUN pip install flask praisonai==2.0.28 gunicorn markdown\n")
|
||||
file.write("RUN pip install flask praisonai==2.0.36 gunicorn markdown\n")
|
||||
file.write("EXPOSE 8080\n")
|
||||
file.write('CMD ["gunicorn", "-b", "0.0.0.0:8080", "api:app"]\n')
|
||||
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
---
|
||||
title: "Callbacks"
|
||||
title: "AI Agents with Callbacks"
|
||||
sidebarTitle: "Callbacks"
|
||||
description: "Learn how to implement callbacks to monitor and log AI agent interactions, errors, and task completions."
|
||||
icon: "bell"
|
||||
---
|
||||
|
||||
<Note>
|
||||
**Prerequisites**
|
||||
- Python 3.8 or higher
|
||||
- Python 3.10 or higher
|
||||
- PraisonAI Agents package installed
|
||||
- Basic understanding of Python functions
|
||||
</Note>
|
||||
|
||||
@@ -0,0 +1,287 @@
|
||||
---
|
||||
title: "Code Execution AI Agent"
|
||||
sidebarTitle: "Code Agent"
|
||||
description: "Learn how to create AI agents that can write and execute Python code safely using e2b code interpreter."
|
||||
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!
|
||||
|
||||
<Steps>
|
||||
<Step title="Install Packages">
|
||||
First, install the required packages:
|
||||
```bash
|
||||
pip install praisonaiagents e2b_code_interpreter
|
||||
```
|
||||
</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="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))
|
||||
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>
|
||||
|
||||
<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
|
||||
)
|
||||
|
||||
execution_agent = Agent(
|
||||
name="execution_agent",
|
||||
backstory="Expert in executing Python scripts",
|
||||
self_reflect=False,
|
||||
tools=[code_interpreter]
|
||||
)
|
||||
```
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
## Understanding Code Agents
|
||||
|
||||
<Card title="What are Code Agents?" icon="question">
|
||||
Code agents are specialized AI agents that can:
|
||||
- Write Python code based on requirements
|
||||
- Execute code safely in a sandboxed environment
|
||||
- Handle code execution results and errors
|
||||
- Work together in a pipeline (writer → executor)
|
||||
</Card>
|
||||
|
||||
## Key Components
|
||||
|
||||
<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>
|
||||
<Card title="Code Executor Agent" icon="play">
|
||||
Executes code using sandbox
|
||||
```python
|
||||
Agent(
|
||||
name="execution_agent",
|
||||
tools=[code_interpreter]
|
||||
)
|
||||
```
|
||||
</Card>
|
||||
<Card title="Sandbox Environment" icon="box">
|
||||
Safe code execution environment using e2b
|
||||
</Card>
|
||||
<Card title="Execution Results" icon="output">
|
||||
Structured output with results and logs
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
## Examples
|
||||
|
||||
### Simple Hello World Example
|
||||
|
||||
```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
|
||||
)
|
||||
```
|
||||
|
||||
## 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>
|
||||
<Card title="Code Generation" icon="code">
|
||||
Provide clear requirements and constraints in task description
|
||||
</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>
|
||||
<Card title="Custom Tools" icon="wrench" href="./custom-tools">
|
||||
Create custom code execution tools
|
||||
</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.
|
||||
</Note>
|
||||
@@ -0,0 +1,279 @@
|
||||
---
|
||||
title: "Math AI Agent"
|
||||
sidebarTitle: "Math Agent"
|
||||
description: "Learn how to create AI agents that can perform complex mathematical calculations, unit conversions, and financial computations."
|
||||
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!
|
||||
|
||||
<Steps>
|
||||
<Step title="Install Package">
|
||||
First, install the required package:
|
||||
```bash
|
||||
pip install praisonaiagents
|
||||
```
|
||||
</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 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>
|
||||
|
||||
## Understanding Math Agents
|
||||
|
||||
<Card title="What are Math Agents?" icon="question">
|
||||
Math agents are specialized AI agents that can:
|
||||
- Evaluate mathematical expressions
|
||||
- Solve equations and systems of equations
|
||||
- Perform unit conversions
|
||||
- Calculate statistical metrics
|
||||
- Handle financial calculations
|
||||
</Card>
|
||||
|
||||
## Key Components
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Expression Evaluator" icon="function">
|
||||
Evaluates mathematical expressions
|
||||
```python
|
||||
evaluate("2 + 2 * 3")
|
||||
evaluate("sin(pi/2) + sqrt(16)")
|
||||
```
|
||||
</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")
|
||||
```
|
||||
</Card>
|
||||
<Card title="Unit Converter" icon="arrows-rotate">
|
||||
Converts between different units
|
||||
```python
|
||||
convert_units(100, "meters", "kilometers")
|
||||
```
|
||||
</Card>
|
||||
<Card title="Statistical Calculator" icon="chart-simple">
|
||||
Calculates statistical metrics
|
||||
```python
|
||||
calculate_statistics([1, 2, 3, 4, 5])
|
||||
```
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
## Examples
|
||||
|
||||
### Basic Calculations Example
|
||||
|
||||
```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
|
||||
)
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
<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'")
|
||||
```
|
||||
</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>
|
||||
</CardGroup>
|
||||
|
||||
## Next Steps
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Advanced Mathematics" icon="graduation-cap" href="./advanced-math">
|
||||
Learn about complex mathematical operations
|
||||
</Card>
|
||||
<Card title="Custom Math Tools" icon="wrench" href="./custom-tools">
|
||||
Create custom mathematical computation tools
|
||||
</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.
|
||||
</Note>
|
||||
@@ -0,0 +1,258 @@
|
||||
---
|
||||
title: "Mini AI Agents"
|
||||
description: "Learn how to create simple yet powerful AI agents in just a few lines of code."
|
||||
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!
|
||||
|
||||
<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>
|
||||
|
||||
<div className="relative w-full aspect-video">
|
||||
<iframe
|
||||
className="absolute top-0 left-0 w-full h-full"
|
||||
src="https://www.youtube.com/embed/OkvYp5aAGSg"
|
||||
title="YouTube video player"
|
||||
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
|
||||
allowFullScreen
|
||||
></iframe>
|
||||
</div>
|
||||
|
||||
## Understanding Mini AI Agents
|
||||
|
||||
<Card title="What are Mini AI Agents?" icon="question">
|
||||
Mini AI Agents are simplified yet powerful AI agents that can:
|
||||
- Work together to accomplish tasks
|
||||
- Use tools like internet search
|
||||
- Process and summarize information
|
||||
- Execute tasks sequentially
|
||||
</Card>
|
||||
|
||||
## Key Components
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Agent" icon="user-robot">
|
||||
Individual AI agents with specific roles and capabilities
|
||||
```python
|
||||
Agent(instructions="Your agent's role description")
|
||||
```
|
||||
</Card>
|
||||
<Card title="Tools" icon="wrench">
|
||||
Built-in tools that agents can use
|
||||
```python
|
||||
tools=[Tools.internet_search]
|
||||
```
|
||||
</Card>
|
||||
<Card title="Agents Manager" icon="users">
|
||||
Coordinates multiple agents
|
||||
```python
|
||||
Agents(agents=[agent1, agent2])
|
||||
```
|
||||
</Card>
|
||||
<Card title="Sequential Flow" icon="arrow-right">
|
||||
Agents work in sequence, passing results to each other
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
## Available Tools
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Internet Search" icon="search">
|
||||
```python
|
||||
Tools.internet_search
|
||||
```
|
||||
Search the internet using DuckDuckGo
|
||||
<Note>
|
||||
Requires: `pip install duckduckgo_search`
|
||||
</Note>
|
||||
</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
|
||||
|
||||
<CodeGroup>
|
||||
```python Basic
|
||||
# Simple instructions
|
||||
research_agent = Agent(
|
||||
instructions="Research about climate change"
|
||||
)
|
||||
```
|
||||
|
||||
```python Advanced
|
||||
# Detailed instructions
|
||||
research_agent = Agent(
|
||||
instructions="""
|
||||
You are a research agent focused on gathering information about:
|
||||
1. Latest AI developments in 2024
|
||||
2. Major breakthroughs in machine learning
|
||||
3. New AI applications in industry
|
||||
|
||||
Provide detailed and accurate information from reliable sources.
|
||||
"""
|
||||
)
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
## Best Practices
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="Agent Instructions">
|
||||
Write clear and specific instructions:
|
||||
```python
|
||||
# Good
|
||||
Agent(instructions="Research and analyze the latest AI developments in 2024")
|
||||
|
||||
# Too vague
|
||||
Agent(instructions="Research AI")
|
||||
```
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Tool Usage">
|
||||
Provide tools only to agents that need them:
|
||||
```python
|
||||
# Research agent needs search
|
||||
research_agent = Agent(
|
||||
instructions="Research AI",
|
||||
tools=[Tools.internet_search]
|
||||
)
|
||||
|
||||
# Summary agent doesn't need search
|
||||
summary_agent = Agent(
|
||||
instructions="Summarize findings"
|
||||
)
|
||||
```
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
## Common Patterns
|
||||
|
||||
### Research and Analysis
|
||||
```python
|
||||
# Research agent
|
||||
researcher = Agent(
|
||||
instructions="Research latest developments in quantum computing",
|
||||
tools=[Tools.internet_search]
|
||||
)
|
||||
|
||||
# Analysis agent
|
||||
analyst = Agent(
|
||||
instructions="Analyze and explain the research findings in simple terms"
|
||||
)
|
||||
|
||||
agents = Agents(agents=[researcher, analyst])
|
||||
```
|
||||
|
||||
### Information Processing
|
||||
```python
|
||||
# Data collector
|
||||
collector = Agent(
|
||||
instructions="Collect information about renewable energy",
|
||||
tools=[Tools.internet_search]
|
||||
)
|
||||
|
||||
# Summarizer
|
||||
summarizer = Agent(
|
||||
instructions="Create a concise summary of the collected information"
|
||||
)
|
||||
|
||||
# Report writer
|
||||
writer = Agent(
|
||||
instructions="Write a detailed report based on the summary"
|
||||
)
|
||||
|
||||
agents = Agents(agents=[collector, summarizer, writer])
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Tool Not Available" icon="triangle-exclamation">
|
||||
If using `Tools.internet_search`, install required package:
|
||||
```bash
|
||||
pip install duckduckgo_search
|
||||
```
|
||||
</Card>
|
||||
<Card title="Agent Communication" icon="comments">
|
||||
Ensure agent instructions are clear and complementary
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
## Next Steps
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Advanced Agents" icon="graduation-cap" href="./advanced">
|
||||
Learn about advanced agent configurations
|
||||
</Card>
|
||||
<Card title="Custom Tools" icon="screwdriver-wrench" href="./tools">
|
||||
Create your own agent tools
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
<Note>
|
||||
Mini AI Agents are designed to be simple yet powerful. They're perfect for quick prototypes and straightforward automation tasks.
|
||||
</Note>
|
||||
@@ -0,0 +1,322 @@
|
||||
---
|
||||
title: "Structured AI Agents"
|
||||
description: "Learn how to create AI agents that return structured, type-safe outputs using Pydantic models and JSON."
|
||||
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!
|
||||
|
||||
<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, Task, PraisonAIAgents, Tools
|
||||
from pydantic import BaseModel
|
||||
```
|
||||
</Step>
|
||||
|
||||
<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>
|
||||
|
||||
<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"
|
||||
)
|
||||
|
||||
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>
|
||||
|
||||
## Understanding Structured Outputs
|
||||
|
||||
<Card title="What are Structured Outputs?" icon="question">
|
||||
Structured outputs allow you to:
|
||||
- Define exact shape of data using Pydantic models
|
||||
- Get type-safe, validated responses
|
||||
- Choose between Pydantic objects or JSON
|
||||
- Ensure consistent output format across agent responses
|
||||
</Card>
|
||||
|
||||
## Key Components
|
||||
|
||||
<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
|
||||
</Card>
|
||||
<Card title="JSON Output" icon="brackets-curly">
|
||||
```python
|
||||
task = Task(
|
||||
output_json=AnalysisReport
|
||||
)
|
||||
# Returns JSON dict
|
||||
```
|
||||
Get JSON dictionary matching model schema
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
## Examples
|
||||
|
||||
### Research Analysis with Structured Output
|
||||
|
||||
```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]
|
||||
)
|
||||
|
||||
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
|
||||
)
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
<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())
|
||||
```
|
||||
</Card>
|
||||
<Card title="Output Format" icon="code">
|
||||
Verify you're accessing the right output field:
|
||||
- `result.pydantic` for Pydantic
|
||||
- `result.json_dict` for JSON
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
## Next Steps
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Advanced Models" icon="graduation-cap" href="./advanced-models">
|
||||
Learn about advanced Pydantic model configurations
|
||||
</Card>
|
||||
<Card title="Custom Validation" icon="check-double" href="./validation">
|
||||
Add custom validation to your models
|
||||
</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.
|
||||
</Note>
|
||||
+53
-25
@@ -76,6 +76,20 @@
|
||||
"concepts/tools"
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "Features",
|
||||
"pages": [
|
||||
"features/selfreflection",
|
||||
"features/reasoning",
|
||||
"framework/multimodalagents",
|
||||
"features/async",
|
||||
"features/mini",
|
||||
"features/codeagent",
|
||||
"features/mathagent",
|
||||
"features/structured",
|
||||
"features/callbacks"
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "Getting Started (No Code)",
|
||||
"pages": [
|
||||
@@ -87,29 +101,6 @@
|
||||
"auto"
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "User Interface",
|
||||
"pages": [
|
||||
"ui/ui",
|
||||
"ui/chat",
|
||||
"ui/code",
|
||||
"ui/realtime"
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "Features",
|
||||
"pages": [
|
||||
"features/selfreflection",
|
||||
"features/reasoning",
|
||||
"framework/multimodalagents",
|
||||
"features/async",
|
||||
"features/callbacks",
|
||||
"train",
|
||||
"framework/praisonaiagents",
|
||||
"framework/crewai",
|
||||
"framework/autogen"
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "Models",
|
||||
"pages": [
|
||||
@@ -126,8 +117,25 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "Tools (No Code)",
|
||||
"group": "Tools",
|
||||
"pages": [
|
||||
"tools/duckduckgo_tools",
|
||||
"tools/arxiv_tools",
|
||||
"tools/calculator_tools",
|
||||
"tools/csv_tools",
|
||||
"tools/duckdb_tools",
|
||||
"tools/excel_tools",
|
||||
"tools/file_tools",
|
||||
"tools/json_tools",
|
||||
"tools/newspaper_tools",
|
||||
"tools/pandas_tools",
|
||||
"tools/python_tools",
|
||||
"tools/shell_tools",
|
||||
"tools/spider_tools",
|
||||
"tools/wikipedia_tools",
|
||||
"tools/xml_tools",
|
||||
"tools/yaml_tools",
|
||||
"tools/yfinance_tools",
|
||||
"tools",
|
||||
"tools/custom",
|
||||
"tools/gpt",
|
||||
@@ -140,7 +148,27 @@
|
||||
"tools/reddit",
|
||||
"tools/you.com",
|
||||
"tools/crawl4ai",
|
||||
"tools/mem0"
|
||||
"tools/mem0",
|
||||
"tools/composio",
|
||||
"tools/googlecalendar"
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "Other Features",
|
||||
"pages": [
|
||||
"train",
|
||||
"framework/crewai",
|
||||
"framework/autogen",
|
||||
"framework/praisonaiagents"
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "User Interface",
|
||||
"pages": [
|
||||
"ui/ui",
|
||||
"ui/chat",
|
||||
"ui/code",
|
||||
"ui/realtime"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
@@ -0,0 +1,429 @@
|
||||
---
|
||||
title: "arXiv Agent"
|
||||
description: "arXiv research paper search and analysis tools for AI agents."
|
||||
icon: "book-open"
|
||||
---
|
||||
|
||||
<Note>
|
||||
**Prerequisites**
|
||||
- Python 3.10 or higher
|
||||
- PraisonAI Agents package installed
|
||||
- `arxiv` package installed
|
||||
</Note>
|
||||
|
||||
## arXiv Tools
|
||||
|
||||
Use arXiv Tools to search and analyze research papers with AI agents.
|
||||
|
||||
<Steps>
|
||||
<Step title="Install Dependencies">
|
||||
First, install the required packages:
|
||||
```bash
|
||||
pip install praisonaiagents arxiv
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Import Components">
|
||||
Import the necessary components:
|
||||
```python
|
||||
from praisonaiagents import Agent, Task, PraisonAIAgents
|
||||
from praisonaiagents.tools import search_arxiv, get_arxiv_paper, get_papers_by_author, get_papers_by_category
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Create Agent">
|
||||
Create a research agent:
|
||||
```python
|
||||
research_agent = Agent(
|
||||
name="ResearchAgent",
|
||||
role="Scientific Literature Specialist",
|
||||
goal="Find and analyze relevant scientific papers.",
|
||||
backstory="Expert in academic research and literature review.",
|
||||
tools=[search_arxiv, get_arxiv_paper, get_papers_by_author, get_papers_by_category],
|
||||
self_reflect=False
|
||||
)
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Define Task">
|
||||
Define the research task:
|
||||
```python
|
||||
research_task = Task(
|
||||
description="Search for recent papers on 'quantum machine learning' and summarize key findings.",
|
||||
expected_output="List of relevant papers with summaries.",
|
||||
agent=research_agent,
|
||||
name="quantum_research"
|
||||
)
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Run Agent">
|
||||
Initialize and run the agent:
|
||||
```python
|
||||
agents = PraisonAIAgents(
|
||||
agents=[research_agent],
|
||||
tasks=[research_task],
|
||||
process="sequential"
|
||||
)
|
||||
agents.start()
|
||||
```
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
## Understanding arXiv Tools
|
||||
|
||||
<Card title="What are arXiv Tools?" icon="question">
|
||||
arXiv Tools provide scientific paper search capabilities for AI agents:
|
||||
- Paper search functionality
|
||||
- Author-based search
|
||||
- Category filtering
|
||||
- Abstract retrieval
|
||||
- PDF download options
|
||||
</Card>
|
||||
|
||||
## Available Functions
|
||||
|
||||
```python
|
||||
from praisonaiagents.tools import search_arxiv
|
||||
from praisonaiagents.tools import get_arxiv_paper
|
||||
from praisonaiagents.tools import get_papers_by_author
|
||||
from praisonaiagents.tools import get_papers_by_category
|
||||
```
|
||||
|
||||
## Function Details
|
||||
|
||||
### search_arxiv(query: str, max_results: int = 10, sort_by: str = "relevance", sort_order: str = "descending", include_fields: Optional[List[str]] = None)
|
||||
|
||||
Search arXiv for papers:
|
||||
- Flexible query support
|
||||
- Customizable results
|
||||
- Multiple sorting options
|
||||
- Field selection
|
||||
- Error handling
|
||||
|
||||
```python
|
||||
# Basic search
|
||||
papers = search_arxiv("quantum computing")
|
||||
|
||||
# Advanced search
|
||||
papers = search_arxiv(
|
||||
query="quantum computing",
|
||||
max_results=5,
|
||||
sort_by="submittedDate",
|
||||
sort_order="descending",
|
||||
include_fields=["title", "authors", "summary"]
|
||||
)
|
||||
|
||||
# Returns: List[Dict[str, Any]]
|
||||
# Example output:
|
||||
# [
|
||||
# {
|
||||
# "arxiv_id": "2401.00123",
|
||||
# "title": "Quantum Computing: A Survey",
|
||||
# "authors": ["John Doe", "Jane Smith"],
|
||||
# "summary": "This paper reviews...",
|
||||
# "published": "2024-01-01T00:00:00",
|
||||
# "updated": "2024-01-02T00:00:00"
|
||||
# },
|
||||
# ...
|
||||
# ]
|
||||
```
|
||||
|
||||
### get_arxiv_paper(paper_id: str, include_fields: Optional[List[str]] = None)
|
||||
|
||||
Get specific paper details:
|
||||
- Direct ID lookup
|
||||
- Full paper metadata
|
||||
- Customizable fields
|
||||
- PDF/Abstract links
|
||||
|
||||
```python
|
||||
# Get paper by ID
|
||||
paper = get_arxiv_paper("2401.00123")
|
||||
|
||||
# Get specific fields
|
||||
paper = get_arxiv_paper(
|
||||
paper_id="2401.00123",
|
||||
include_fields=["title", "authors", "pdf_url"]
|
||||
)
|
||||
|
||||
# Returns: Dict[str, Any]
|
||||
# Example output:
|
||||
# {
|
||||
# "arxiv_id": "2401.00123",
|
||||
# "title": "Quantum Computing: A Survey",
|
||||
# "authors": ["John Doe", "Jane Smith"],
|
||||
# "pdf_url": "https://arxiv.org/pdf/2401.00123",
|
||||
# "abstract_url": "https://arxiv.org/abs/2401.00123",
|
||||
# "published": "2024-01-01T00:00:00",
|
||||
# "updated": "2024-01-02T00:00:00"
|
||||
# }
|
||||
```
|
||||
|
||||
### get_papers_by_author(author: str, max_results: int = 10, sort_by: str = "submittedDate", sort_order: str = "descending", include_fields: Optional[List[str]] = None)
|
||||
|
||||
Search papers by author:
|
||||
- Author-specific search
|
||||
- Publication timeline
|
||||
- Sort options
|
||||
- Field selection
|
||||
|
||||
```python
|
||||
# Get author's papers
|
||||
papers = get_papers_by_author("Yoshua Bengio")
|
||||
|
||||
# Recent papers first
|
||||
papers = get_papers_by_author(
|
||||
author="Yoshua Bengio",
|
||||
max_results=5,
|
||||
sort_by="submittedDate",
|
||||
sort_order="descending"
|
||||
)
|
||||
|
||||
# Returns: List[Dict[str, Any]]
|
||||
# Example output:
|
||||
# [
|
||||
# {
|
||||
# "arxiv_id": "2401.00124",
|
||||
# "title": "Deep Learning Advances",
|
||||
# "authors": ["Yoshua Bengio", "Other Author"],
|
||||
# "published": "2024-01-01T00:00:00"
|
||||
# },
|
||||
# ...
|
||||
# ]
|
||||
```
|
||||
|
||||
### get_papers_by_category(category: str, max_results: int = 10, sort_by: str = "submittedDate", sort_order: str = "descending", include_fields: Optional[List[str]] = None)
|
||||
|
||||
Search papers by category:
|
||||
- Category-specific search
|
||||
- Latest publications
|
||||
- Sort options
|
||||
- Field selection
|
||||
|
||||
```python
|
||||
# Get papers in category
|
||||
papers = get_papers_by_category("cs.AI")
|
||||
|
||||
# Recent machine learning papers
|
||||
papers = get_papers_by_category(
|
||||
category="cs.LG",
|
||||
max_results=5,
|
||||
sort_by="submittedDate",
|
||||
sort_order="descending"
|
||||
)
|
||||
|
||||
# Returns: List[Dict[str, Any]]
|
||||
# Example output:
|
||||
# [
|
||||
# {
|
||||
# "arxiv_id": "2401.00125",
|
||||
# "title": "New ML Algorithm",
|
||||
# "categories": ["cs.LG", "cs.AI"],
|
||||
# "published": "2024-01-01T00:00:00"
|
||||
# },
|
||||
# ...
|
||||
# ]
|
||||
```
|
||||
|
||||
## Dependencies
|
||||
|
||||
The arXiv tools require the following package:
|
||||
- arxiv: For accessing the arXiv API
|
||||
|
||||
This will be automatically installed when needed.
|
||||
|
||||
## Available Fields
|
||||
|
||||
When using `include_fields`, you can select from:
|
||||
- title: Paper title
|
||||
- authors: List of authors
|
||||
- summary: Abstract text
|
||||
- comment: Author comments
|
||||
- journal_ref: Journal reference
|
||||
- doi: Digital Object Identifier
|
||||
- primary_category: Main arXiv category
|
||||
- categories: All arXiv categories
|
||||
- links: PDF and abstract URLs
|
||||
|
||||
## Common Use Cases
|
||||
|
||||
1. Literature Review:
|
||||
```python
|
||||
# Search multiple related topics
|
||||
topics = ["machine learning", "neural networks", "deep learning"]
|
||||
all_papers = []
|
||||
for topic in topics:
|
||||
papers = search_arxiv(
|
||||
topic,
|
||||
max_results=5,
|
||||
sort_by="relevance"
|
||||
)
|
||||
all_papers.extend(papers)
|
||||
```
|
||||
|
||||
2. Author Research:
|
||||
```python
|
||||
# Get recent papers by multiple authors
|
||||
authors = ["Yoshua Bengio", "Geoffrey Hinton", "Yann LeCun"]
|
||||
author_papers = {}
|
||||
for author in authors:
|
||||
papers = get_papers_by_author(
|
||||
author,
|
||||
max_results=3,
|
||||
sort_by="submittedDate"
|
||||
)
|
||||
author_papers[author] = papers
|
||||
```
|
||||
|
||||
3. Category Monitoring:
|
||||
```python
|
||||
# Monitor new papers in AI categories
|
||||
categories = ["cs.AI", "cs.LG", "cs.CL"]
|
||||
new_papers = {}
|
||||
for category in categories:
|
||||
papers = get_papers_by_category(
|
||||
category,
|
||||
max_results=5,
|
||||
sort_by="submittedDate"
|
||||
)
|
||||
new_papers[category] = papers
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
### Basic Research Agent
|
||||
|
||||
```python
|
||||
from praisonaiagents import Agent, Task, PraisonAIAgents
|
||||
from praisonaiagents.tools import search_arxiv, get_arxiv_paper, get_papers_by_author, get_papers_by_category
|
||||
|
||||
# Create research agent
|
||||
research_agent = Agent(
|
||||
name="PaperSearcher",
|
||||
role="Scientific Literature Specialist",
|
||||
goal="Find relevant scientific papers on specified topics.",
|
||||
backstory="Expert in academic research and literature analysis.",
|
||||
tools=[search_arxiv, get_arxiv_paper, get_papers_by_author, get_papers_by_category],
|
||||
self_reflect=False
|
||||
)
|
||||
|
||||
# Define research task
|
||||
research_task = Task(
|
||||
description="Search for papers on 'transformer models in NLP' from the last year.",
|
||||
expected_output="List of relevant papers with abstracts and key findings.",
|
||||
agent=research_agent,
|
||||
name="nlp_research"
|
||||
)
|
||||
|
||||
# Run agent
|
||||
agents = PraisonAIAgents(
|
||||
agents=[research_agent],
|
||||
tasks=[research_task],
|
||||
process="sequential"
|
||||
)
|
||||
agents.start()
|
||||
```
|
||||
|
||||
### Advanced Research with Multiple Agents
|
||||
|
||||
```python
|
||||
# Create research agent
|
||||
research_agent = Agent(
|
||||
name="Researcher",
|
||||
role="Literature Specialist",
|
||||
goal="Gather comprehensive scientific literature.",
|
||||
tools=[search_arxiv, get_arxiv_paper, get_papers_by_author, get_papers_by_category],
|
||||
self_reflect=False
|
||||
)
|
||||
|
||||
# Create analysis agent
|
||||
analysis_agent = Agent(
|
||||
name="Analyzer",
|
||||
role="Research Analyst",
|
||||
goal="Analyze and synthesize research findings.",
|
||||
backstory="Expert in scientific literature analysis.",
|
||||
self_reflect=False
|
||||
)
|
||||
|
||||
# Define tasks
|
||||
research_task = Task(
|
||||
description="Search for papers on quantum computing applications in cryptography.",
|
||||
agent=research_agent,
|
||||
name="quantum_research"
|
||||
)
|
||||
|
||||
analysis_task = Task(
|
||||
description="Analyze the papers and identify key trends and breakthroughs.",
|
||||
agent=analysis_agent,
|
||||
name="research_analysis"
|
||||
)
|
||||
|
||||
# Run agents
|
||||
agents = PraisonAIAgents(
|
||||
agents=[research_agent, analysis_agent],
|
||||
tasks=[research_task, analysis_task],
|
||||
process="sequential"
|
||||
)
|
||||
agents.start()
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="Agent Configuration">
|
||||
Configure agents with clear research focus:
|
||||
```python
|
||||
Agent(
|
||||
name="Researcher",
|
||||
role="Literature Specialist",
|
||||
goal="Find relevant scientific papers",
|
||||
tools=[search_arxiv, get_arxiv_paper, get_papers_by_author, get_papers_by_category]
|
||||
)
|
||||
```
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Task Definition">
|
||||
Define specific research objectives:
|
||||
```python
|
||||
Task(
|
||||
description="Find papers on 'deep learning in healthcare' from top authors",
|
||||
expected_output="Curated list of papers with impact analysis"
|
||||
)
|
||||
```
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
## Common Patterns
|
||||
|
||||
### Literature Review
|
||||
```python
|
||||
# Literature search agent
|
||||
searcher = Agent(
|
||||
name="Searcher",
|
||||
role="Literature Specialist",
|
||||
tools=[search_arxiv, get_arxiv_paper, get_papers_by_author, get_papers_by_category]
|
||||
)
|
||||
|
||||
# Review agent
|
||||
reviewer = Agent(
|
||||
name="Reviewer",
|
||||
role="Research Reviewer"
|
||||
)
|
||||
|
||||
# Define tasks
|
||||
search_task = Task(
|
||||
description="Find papers on AI ethics",
|
||||
agent=searcher
|
||||
)
|
||||
|
||||
review_task = Task(
|
||||
description="Review and summarize findings",
|
||||
agent=reviewer
|
||||
)
|
||||
|
||||
# Run workflow
|
||||
agents = PraisonAIAgents(
|
||||
agents=[searcher, reviewer],
|
||||
tasks=[search_task, review_task]
|
||||
)
|
||||
@@ -0,0 +1,216 @@
|
||||
---
|
||||
title: "Calculator Agent"
|
||||
description: "Mathematical calculation tools for AI agents."
|
||||
icon: "calculator"
|
||||
---
|
||||
|
||||
<Note>
|
||||
**Prerequisites**
|
||||
- Python 3.10 or higher
|
||||
- PraisonAI Agents package installed
|
||||
- `sympy` and `pint` packages installed
|
||||
</Note>
|
||||
|
||||
## Calculator Tools
|
||||
|
||||
Use Calculator Tools to perform mathematical calculations with AI agents.
|
||||
|
||||
<Steps>
|
||||
<Step title="Install Dependencies">
|
||||
First, install the required packages:
|
||||
```bash
|
||||
pip install praisonaiagents sympy pint
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Import 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 Agent">
|
||||
Create a calculator agent:
|
||||
```python
|
||||
calculator_agent = Agent(
|
||||
name="MathAssistant",
|
||||
role="Mathematical Computation Specialist",
|
||||
goal="Perform accurate mathematical calculations and solve equations.",
|
||||
backstory="Expert in mathematical computations and problem-solving.",
|
||||
tools=[
|
||||
evaluate, solve_equation, convert_units,
|
||||
calculate_statistics, calculate_financial
|
||||
],
|
||||
self_reflect=False
|
||||
)
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Define Task">
|
||||
Define the calculation task:
|
||||
```python
|
||||
calc_task = Task(
|
||||
description="Calculate the area of a circle with radius 5",
|
||||
expected_output="The area of the circle in square units",
|
||||
agent=calculator_agent,
|
||||
name="circle_area"
|
||||
)
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Run Agent">
|
||||
Initialize and run the agent:
|
||||
```python
|
||||
agents = PraisonAIAgents(
|
||||
agents=[calculator_agent],
|
||||
tasks=[calc_task],
|
||||
process="sequential"
|
||||
)
|
||||
agents.start()
|
||||
```
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
## Understanding Calculator Tools
|
||||
|
||||
<Card title="What are Calculator Tools?" icon="question">
|
||||
Calculator Tools provide mathematical computation capabilities for AI agents:
|
||||
- Expression evaluation
|
||||
- Equation solving
|
||||
- Unit conversions
|
||||
- Support for mathematical functions
|
||||
- Variable substitution
|
||||
</Card>
|
||||
|
||||
## Key Components
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Expression Evaluation" icon="function">
|
||||
Evaluate mathematical expressions:
|
||||
```python
|
||||
result = evaluate("2 + 2 * 3")
|
||||
```
|
||||
</Card>
|
||||
<Card title="Equation Solving" icon="equals">
|
||||
Solve mathematical equations:
|
||||
```python
|
||||
result = solve_equation("2*x + 3 = 7")
|
||||
```
|
||||
</Card>
|
||||
<Card title="Unit Conversions" icon="exchange">
|
||||
Convert between units:
|
||||
```python
|
||||
result = convert_units(100, "meters", "kilometers")
|
||||
```
|
||||
</Card>
|
||||
<Card title="Statistical Calculations" icon="chart-line">
|
||||
Calculate statistical metrics:
|
||||
```python
|
||||
result = calculate_statistics([1, 2, 3, 4, 5])
|
||||
```
|
||||
</Card>
|
||||
<Card title="Financial Calculations" icon="chart-pie">
|
||||
Calculate financial metrics:
|
||||
```python
|
||||
result = calculate_financial(1000, 5, 2)
|
||||
```
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
## Advanced Usage
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="Expression Evaluation">
|
||||
Evaluate complex mathematical expressions with variables:
|
||||
```python
|
||||
# Basic arithmetic
|
||||
result = evaluate("2 + 2 * 3")
|
||||
|
||||
# With mathematical functions
|
||||
result = evaluate("sin(pi/2) + sqrt(16)")
|
||||
|
||||
# With variables
|
||||
result = evaluate(
|
||||
"x^2 + y",
|
||||
variables={"x": 3, "y": 4}
|
||||
)
|
||||
```
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Equation Solving">
|
||||
Solve different types of equations:
|
||||
```python
|
||||
# Linear equation
|
||||
result = solve_equation("2*x + 3 = 7")
|
||||
|
||||
# With custom variable
|
||||
result = solve_equation("y^2 = 4", variable="y")
|
||||
```
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Unit Conversions">
|
||||
Convert between different units:
|
||||
```python
|
||||
# Length conversion
|
||||
result = convert_units(100, "meters", "kilometers")
|
||||
|
||||
# Temperature conversion
|
||||
result = convert_units(32, "fahrenheit", "celsius")
|
||||
|
||||
# Time conversion
|
||||
result = convert_units(2.5, "hours", "minutes")
|
||||
```
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Statistical Calculations">
|
||||
Calculate statistical metrics:
|
||||
```python
|
||||
result = calculate_statistics([1, 2, 3, 4, 5])
|
||||
```
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Financial Calculations">
|
||||
Calculate financial metrics:
|
||||
```python
|
||||
result = calculate_financial(1000, 5, 2)
|
||||
```
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
## Error Handling
|
||||
|
||||
<Card title="Error Management" icon="shield-check">
|
||||
The tools include comprehensive error handling:
|
||||
```python
|
||||
# Returns success result
|
||||
{"result": 8.0}
|
||||
|
||||
# Returns error message
|
||||
{"error": "Invalid expression"}
|
||||
```
|
||||
</Card>
|
||||
|
||||
## Best Practices
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Precision Control" icon="ruler">
|
||||
Control calculation precision:
|
||||
```python
|
||||
evaluate(
|
||||
"pi",
|
||||
precision=5
|
||||
)
|
||||
```
|
||||
</Card>
|
||||
<Card title="Safe Execution" icon="shield">
|
||||
Uses safe evaluation environment with:
|
||||
- Restricted builtins
|
||||
- Mathematical functions only
|
||||
- Variable validation
|
||||
</Card>
|
||||
</CardGroup>
|
||||
@@ -0,0 +1,384 @@
|
||||
---
|
||||
title: "CSV Agent"
|
||||
description: "CSV file processing tools for AI agents."
|
||||
icon: "file-csv"
|
||||
---
|
||||
|
||||
<Note>
|
||||
**Prerequisites**
|
||||
- Python 3.10 or higher
|
||||
- PraisonAI Agents package installed
|
||||
- `pandas` package installed
|
||||
</Note>
|
||||
|
||||
## CSV Tools
|
||||
|
||||
Use CSV Tools to read, write, and manipulate CSV files with AI agents.
|
||||
|
||||
<Steps>
|
||||
<Step title="Install Dependencies">
|
||||
First, install the required package:
|
||||
```bash
|
||||
pip install praisonaiagents
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Import Components">
|
||||
Import the necessary components:
|
||||
```python
|
||||
from praisonaiagents import Agent, Task, PraisonAIAgents
|
||||
from praisonaiagents.tools import read_csv, write_csv, merge_csv
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Create Agent">
|
||||
Create a CSV processing agent:
|
||||
```python
|
||||
csv_agent = Agent(
|
||||
name="CSVProcessor",
|
||||
role="CSV Processing Specialist",
|
||||
goal="Process CSV files efficiently and accurately.",
|
||||
backstory="Expert in CSV file manipulation and analysis.",
|
||||
tools=[read_csv, write_csv, merge_csv],
|
||||
self_reflect=False
|
||||
)
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Define Task">
|
||||
Define the CSV processing task:
|
||||
```python
|
||||
csv_task = Task(
|
||||
description="Process and analyze CSV data files.",
|
||||
expected_output="Processed CSV data with analysis.",
|
||||
agent=csv_agent,
|
||||
name="csv_processing"
|
||||
)
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Run Agent">
|
||||
Initialize and run the agent:
|
||||
```python
|
||||
agents = PraisonAIAgents(
|
||||
agents=[csv_agent],
|
||||
tasks=[csv_task],
|
||||
process="sequential"
|
||||
)
|
||||
agents.start()
|
||||
```
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
## Understanding CSV Tools
|
||||
|
||||
<Card title="What are CSV Tools?" icon="question">
|
||||
CSV Tools provide CSV processing capabilities for AI agents:
|
||||
- File reading and writing
|
||||
- Data parsing
|
||||
- Column manipulation
|
||||
- Data filtering
|
||||
- Format conversion
|
||||
</Card>
|
||||
|
||||
## Key Components
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="CSV Agent" icon="user-robot">
|
||||
Create specialized CSV agents:
|
||||
```python
|
||||
Agent(tools=[read_csv, write_csv, merge_csv])
|
||||
```
|
||||
</Card>
|
||||
<Card title="CSV Task" icon="list-check">
|
||||
Define CSV tasks:
|
||||
```python
|
||||
Task(description="csv_operation")
|
||||
```
|
||||
</Card>
|
||||
<Card title="Process Types" icon="arrows-split-up-and-left">
|
||||
Sequential or parallel processing:
|
||||
```python
|
||||
process="sequential"
|
||||
```
|
||||
</Card>
|
||||
<Card title="CSV Options" icon="sliders">
|
||||
Customize CSV parameters:
|
||||
```python
|
||||
delimiter=",", header=True
|
||||
```
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
## Available Functions
|
||||
|
||||
```python
|
||||
from praisonaiagents.tools import read_csv
|
||||
from praisonaiagents.tools import write_csv
|
||||
from praisonaiagents.tools import merge_csv
|
||||
```
|
||||
|
||||
## Function Details
|
||||
|
||||
### read_csv(filepath: str, encoding: str = 'utf-8', delimiter: str = ',', header: Union[int, List[int], None] = 0, usecols: Optional[List[str]] = None, dtype: Optional[Dict[str, str]] = None, parse_dates: Optional[List[str]] = None, na_values: Optional[List[str]] = None, nrows: Optional[int] = None)
|
||||
|
||||
Reads a CSV file with advanced options:
|
||||
- Supports multiple encodings (utf-8, ascii, etc.)
|
||||
- Configurable column delimiter
|
||||
- Flexible header row handling
|
||||
- Column selection and data type specification
|
||||
- Date parsing
|
||||
- Custom NA/NaN value handling
|
||||
- Row limit option
|
||||
|
||||
```python
|
||||
# Basic usage
|
||||
data = read_csv("data.csv")
|
||||
|
||||
# Advanced usage with options
|
||||
data = read_csv(
|
||||
"data.csv",
|
||||
encoding='utf-8',
|
||||
delimiter=',',
|
||||
header=0,
|
||||
usecols=['name', 'age', 'city'],
|
||||
dtype={'age': 'int32'},
|
||||
parse_dates=['birth_date'],
|
||||
na_values=['N/A', 'missing'],
|
||||
nrows=1000
|
||||
)
|
||||
# Returns: List[Dict[str, Any]]
|
||||
# Example: [{"name": "Alice", "age": 25, "city": "New York"}, ...]
|
||||
```
|
||||
|
||||
### write_csv(filepath: str, data: List[Dict[str, Any]], encoding: str = 'utf-8', delimiter: str = ',', index: bool = False, header: bool = True, float_format: Optional[str] = None, date_format: Optional[str] = None, mode: str = 'w')
|
||||
|
||||
Writes data to a CSV file with formatting options:
|
||||
- Supports different encodings
|
||||
- Configurable delimiter
|
||||
- Optional row indices
|
||||
- Optional headers
|
||||
- Custom float and date formatting
|
||||
- Append mode support
|
||||
|
||||
```python
|
||||
# Basic usage
|
||||
data = [
|
||||
{"name": "Alice", "age": 25, "city": "New York"},
|
||||
{"name": "Bob", "age": 30, "city": "San Francisco"}
|
||||
]
|
||||
success = write_csv("output.csv", data)
|
||||
|
||||
# Advanced usage with formatting
|
||||
success = write_csv(
|
||||
"output.csv",
|
||||
data,
|
||||
encoding='utf-8',
|
||||
delimiter=',',
|
||||
index=False,
|
||||
header=True,
|
||||
float_format='%.2f',
|
||||
date_format='%Y-%m-%d',
|
||||
mode='w'
|
||||
)
|
||||
# Returns: bool (True if successful)
|
||||
```
|
||||
|
||||
### merge_csv(files: List[str], output_file: str, how: str = 'inner', on: Optional[Union[str, List[str]]] = None, suffixes: Optional[tuple] = None)
|
||||
|
||||
Merges multiple CSV files with flexible join options:
|
||||
- Supports different join types (inner, outer, left, right)
|
||||
- Merge on single or multiple columns
|
||||
- Custom suffixes for overlapping columns
|
||||
- Automatic handling of column name conflicts
|
||||
|
||||
```python
|
||||
# Merge two files on a common column
|
||||
success = merge_csv(
|
||||
files=["employees.csv", "salaries.csv"],
|
||||
output_file="merged.csv",
|
||||
how='inner',
|
||||
on='employee_id'
|
||||
)
|
||||
|
||||
# Advanced merge with multiple columns and custom suffixes
|
||||
success = merge_csv(
|
||||
files=["data1.csv", "data2.csv", "data3.csv"],
|
||||
output_file="merged.csv",
|
||||
how='outer',
|
||||
on=['id', 'department'],
|
||||
suffixes=('_2022', '_2023')
|
||||
)
|
||||
# Returns: bool (True if successful)
|
||||
```
|
||||
|
||||
## Dependencies
|
||||
|
||||
The CSV tools require the following Python packages:
|
||||
- pandas: For advanced CSV operations and data manipulation
|
||||
|
||||
These will be automatically installed when needed.
|
||||
|
||||
## Example Agent Configuration
|
||||
|
||||
```python
|
||||
from praisonaiagents import Agent
|
||||
from praisonaiagents.tools import read_csv, write_csv, merge_csv
|
||||
|
||||
agent = Agent(
|
||||
name="CSVProcessor",
|
||||
description="An agent that processes CSV files",
|
||||
tools=[read_csv, write_csv, merge_csv]
|
||||
)
|
||||
```
|
||||
|
||||
## Error Handling
|
||||
|
||||
All functions include comprehensive error handling:
|
||||
- File not found errors
|
||||
- Permission errors
|
||||
- Encoding errors
|
||||
- Data format errors
|
||||
- Missing dependency errors
|
||||
|
||||
Errors are logged and returned in a consistent format:
|
||||
- Success cases return the expected data type
|
||||
- Error cases return a dict with an "error" key containing the error message
|
||||
|
||||
## Examples
|
||||
|
||||
### Basic CSV Processing Agent
|
||||
|
||||
```python
|
||||
from praisonaiagents import Agent, Task, PraisonAIAgents
|
||||
from praisonaiagents.tools import read_csv, write_csv, merge_csv
|
||||
|
||||
# Create CSV agent
|
||||
csv_agent = Agent(
|
||||
name="CSVExpert",
|
||||
role="CSV Processing Specialist",
|
||||
goal="Process CSV files efficiently and accurately.",
|
||||
backstory="Expert in data processing and analysis.",
|
||||
tools=[read_csv, write_csv, merge_csv],
|
||||
self_reflect=False
|
||||
)
|
||||
|
||||
# Define CSV task
|
||||
csv_task = Task(
|
||||
description="Process and analyze customer data.",
|
||||
expected_output="Customer analysis report.",
|
||||
agent=csv_agent,
|
||||
name="customer_analysis"
|
||||
)
|
||||
|
||||
# Run agent
|
||||
agents = PraisonAIAgents(
|
||||
agents=[csv_agent],
|
||||
tasks=[csv_task],
|
||||
process="sequential"
|
||||
)
|
||||
agents.start()
|
||||
```
|
||||
|
||||
### Advanced CSV Processing with Multiple Agents
|
||||
|
||||
```python
|
||||
# Create data processing agent
|
||||
processor_agent = Agent(
|
||||
name="Processor",
|
||||
role="Data Processor",
|
||||
goal="Process CSV data systematically.",
|
||||
tools=[read_csv, write_csv, merge_csv],
|
||||
self_reflect=False
|
||||
)
|
||||
|
||||
# Create analysis agent
|
||||
analysis_agent = Agent(
|
||||
name="Analyzer",
|
||||
role="Data Analyst",
|
||||
goal="Analyze processed CSV data.",
|
||||
backstory="Expert in data analysis and reporting.",
|
||||
self_reflect=False
|
||||
)
|
||||
|
||||
# Define tasks
|
||||
processing_task = Task(
|
||||
description="Process customer data files.",
|
||||
agent=processor_agent,
|
||||
name="data_processing"
|
||||
)
|
||||
|
||||
analysis_task = Task(
|
||||
description="Analyze customer trends and patterns.",
|
||||
agent=analysis_agent,
|
||||
name="data_analysis"
|
||||
)
|
||||
|
||||
# Run agents
|
||||
agents = PraisonAIAgents(
|
||||
agents=[processor_agent, analysis_agent],
|
||||
tasks=[processing_task, analysis_task],
|
||||
process="sequential"
|
||||
)
|
||||
agents.start()
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="Agent Configuration">
|
||||
Configure agents with clear CSV focus:
|
||||
```python
|
||||
Agent(
|
||||
name="CSVProcessor",
|
||||
role="CSV Processing Specialist",
|
||||
goal="Process CSV files accurately and efficiently",
|
||||
tools=[read_csv, write_csv, merge_csv]
|
||||
)
|
||||
```
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Task Definition">
|
||||
Define specific CSV operations:
|
||||
```python
|
||||
Task(
|
||||
description="Process customer data and generate reports",
|
||||
expected_output="Customer analysis report"
|
||||
)
|
||||
```
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
## Common Patterns
|
||||
|
||||
### CSV Processing Pipeline
|
||||
```python
|
||||
# Processing agent
|
||||
processor = Agent(
|
||||
name="Processor",
|
||||
role="CSV Processor",
|
||||
tools=[read_csv, write_csv, merge_csv]
|
||||
)
|
||||
|
||||
# Analysis agent
|
||||
analyzer = Agent(
|
||||
name="Analyzer",
|
||||
role="Data Analyst"
|
||||
)
|
||||
|
||||
# Define tasks
|
||||
process_task = Task(
|
||||
description="Process CSV files",
|
||||
agent=processor
|
||||
)
|
||||
|
||||
analyze_task = Task(
|
||||
description="Analyze processed data",
|
||||
agent=analyzer
|
||||
)
|
||||
|
||||
# Run workflow
|
||||
agents = PraisonAIAgents(
|
||||
agents=[processor, analyzer],
|
||||
tasks=[process_task, analyze_task]
|
||||
)
|
||||
@@ -0,0 +1,401 @@
|
||||
---
|
||||
title: "DuckDB Agent"
|
||||
description: "DuckDB database tools for AI agents."
|
||||
icon: "database"
|
||||
---
|
||||
|
||||
<Note>
|
||||
**Prerequisites**
|
||||
- Python 3.10 or higher
|
||||
- PraisonAI Agents package installed
|
||||
- `duckdb` package installed
|
||||
- Basic understanding of SQL and databases
|
||||
</Note>
|
||||
|
||||
## DuckDB Tools
|
||||
|
||||
Use DuckDB Tools to manage and query databases with AI agents.
|
||||
|
||||
<Steps>
|
||||
<Step title="Install Dependencies">
|
||||
First, install the required packages:
|
||||
```bash
|
||||
pip install praisonaiagents duckdb
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Import Components">
|
||||
Import the necessary components:
|
||||
```python
|
||||
from praisonaiagents import Agent, Task, PraisonAIAgents
|
||||
from praisonaiagents.tools import execute_query, load_csv, export_csv
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Create Agent">
|
||||
Create a DuckDB database agent:
|
||||
```python
|
||||
db_agent = Agent(
|
||||
name="DBProcessor",
|
||||
role="Database Management Specialist",
|
||||
goal="Manage and query databases efficiently.",
|
||||
backstory="Expert in database operations and SQL.",
|
||||
tools=[execute_query, load_csv, export_csv],
|
||||
self_reflect=False
|
||||
)
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Define Task">
|
||||
Define the database task:
|
||||
```python
|
||||
db_task = Task(
|
||||
description="Query and analyze database data.",
|
||||
expected_output="Query results and analysis.",
|
||||
agent=db_agent,
|
||||
name="db_analysis"
|
||||
)
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Run Agent">
|
||||
Initialize and run the agent:
|
||||
```python
|
||||
agents = PraisonAIAgents(
|
||||
agents=[db_agent],
|
||||
tasks=[db_task],
|
||||
process="sequential"
|
||||
)
|
||||
agents.start()
|
||||
```
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
## Available Functions
|
||||
|
||||
```python
|
||||
from praisonaiagents.tools import execute_query
|
||||
from praisonaiagents.tools import load_csv
|
||||
from praisonaiagents.tools import export_csv
|
||||
```
|
||||
|
||||
## Function Details
|
||||
|
||||
### execute_query(query: str, params: Optional[Union[tuple, dict]] = None, return_df: bool = True)
|
||||
|
||||
Executes SQL queries with advanced features:
|
||||
- Supports parameterized queries
|
||||
- Returns results as DataFrame records or raw tuples
|
||||
- Full SQL query support (SELECT, INSERT, UPDATE, DELETE, etc.)
|
||||
- Automatic connection management
|
||||
|
||||
```python
|
||||
# Basic SELECT query
|
||||
results = execute_query("SELECT * FROM employees")
|
||||
|
||||
# Parameterized query
|
||||
results = execute_query(
|
||||
"SELECT * FROM employees WHERE department = ? AND salary > ?",
|
||||
params=('Engineering', 75000)
|
||||
)
|
||||
|
||||
# Named parameters
|
||||
results = execute_query(
|
||||
"SELECT * FROM employees WHERE department = :dept",
|
||||
params={'dept': 'Engineering'}
|
||||
)
|
||||
# Returns: List[Dict[str, Any]]
|
||||
# Example: [{"id": 1, "name": "Alice", "department": "Engineering"}, ...]
|
||||
```
|
||||
|
||||
### load_csv(table_name: str, filepath: str, schema: Optional[Dict[str, str]] = None, if_exists: str = 'replace')
|
||||
|
||||
Loads CSV files into DuckDB tables:
|
||||
- Optional schema definition
|
||||
- Flexible table existence handling
|
||||
- Automatic type inference
|
||||
- Support for large files
|
||||
|
||||
```python
|
||||
# Basic usage - auto schema inference
|
||||
success = load_csv("employees", "employees.csv")
|
||||
|
||||
# With custom schema
|
||||
schema = {
|
||||
"id": "INTEGER PRIMARY KEY",
|
||||
"name": "VARCHAR",
|
||||
"salary": "DECIMAL(10,2)",
|
||||
"hire_date": "DATE"
|
||||
}
|
||||
success = load_csv(
|
||||
"employees",
|
||||
"employees.csv",
|
||||
schema=schema,
|
||||
if_exists='replace'
|
||||
)
|
||||
# Returns: bool (True if successful)
|
||||
```
|
||||
|
||||
### export_csv(query: str, filepath: str, params: Optional[Union[tuple, dict]] = None)
|
||||
|
||||
Exports query results to CSV files:
|
||||
- Supports parameterized queries
|
||||
- Automatic header generation
|
||||
- Configurable output formatting
|
||||
- Large result set handling
|
||||
|
||||
```python
|
||||
# Export simple query results
|
||||
success = export_csv(
|
||||
"SELECT * FROM employees",
|
||||
"exported_employees.csv"
|
||||
)
|
||||
|
||||
# Export filtered data with parameters
|
||||
success = export_csv(
|
||||
"SELECT * FROM employees WHERE department = ? AND year = ?",
|
||||
"eng_2023.csv",
|
||||
params=('Engineering', 2023)
|
||||
)
|
||||
# Returns: bool (True if successful)
|
||||
```
|
||||
|
||||
## Understanding DuckDB Tools
|
||||
|
||||
<Card title="What are DuckDB Tools?" icon="question">
|
||||
DuckDB Tools provide database capabilities for AI agents:
|
||||
- SQL query execution
|
||||
- Data import/export
|
||||
- Schema management
|
||||
- Data analysis
|
||||
- Performance optimization
|
||||
</Card>
|
||||
|
||||
## Key Components
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="DB Agent" icon="user-robot">
|
||||
Create specialized database agents:
|
||||
```python
|
||||
Agent(tools=[execute_query, load_csv, export_csv])
|
||||
```
|
||||
</Card>
|
||||
<Card title="DB Task" icon="list-check">
|
||||
Define database tasks:
|
||||
```python
|
||||
Task(description="db_operation")
|
||||
```
|
||||
</Card>
|
||||
<Card title="Process Types" icon="arrows-split-up-and-left">
|
||||
Sequential or parallel processing:
|
||||
```python
|
||||
process="sequential"
|
||||
```
|
||||
</Card>
|
||||
<Card title="DB Options" icon="sliders">
|
||||
Customize database parameters:
|
||||
```python
|
||||
read_only=True, memory=True
|
||||
```
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
## Examples
|
||||
|
||||
### Basic Database Agent
|
||||
|
||||
```python
|
||||
from praisonaiagents import Agent, Task, PraisonAIAgents
|
||||
from praisonaiagents.tools import execute_query, load_csv, export_csv
|
||||
|
||||
# Create database agent
|
||||
db_agent = Agent(
|
||||
name="DBExpert",
|
||||
role="Database Specialist",
|
||||
goal="Query and analyze data efficiently.",
|
||||
backstory="Expert in database management and SQL.",
|
||||
tools=[execute_query, load_csv, export_csv],
|
||||
self_reflect=False
|
||||
)
|
||||
|
||||
# Define database task
|
||||
db_task = Task(
|
||||
description="Analyze sales performance data.",
|
||||
expected_output="Sales analysis report.",
|
||||
agent=db_agent,
|
||||
name="sales_analysis"
|
||||
)
|
||||
|
||||
# Run agent
|
||||
agents = PraisonAIAgents(
|
||||
agents=[db_agent],
|
||||
tasks=[db_task],
|
||||
process="sequential"
|
||||
)
|
||||
agents.start()
|
||||
```
|
||||
|
||||
### Advanced Database Operations with Multiple Agents
|
||||
|
||||
```python
|
||||
# Create query agent
|
||||
query_agent = Agent(
|
||||
name="QueryProcessor",
|
||||
role="SQL Query Specialist",
|
||||
goal="Execute SQL queries efficiently.",
|
||||
tools=[execute_query],
|
||||
self_reflect=False
|
||||
)
|
||||
|
||||
# Create data import/export agent
|
||||
data_agent = Agent(
|
||||
name="DataProcessor",
|
||||
role="Data Import/Export Specialist",
|
||||
goal="Handle data import and export operations efficiently.",
|
||||
tools=[load_csv, export_csv],
|
||||
self_reflect=False
|
||||
)
|
||||
```
|
||||
|
||||
## Dependencies
|
||||
|
||||
The DuckDB tools require the following Python packages:
|
||||
- duckdb: For database operations
|
||||
- pandas: For data manipulation and CSV handling
|
||||
|
||||
These will be automatically installed when needed.
|
||||
|
||||
## Example Agent Configuration
|
||||
|
||||
```python
|
||||
from praisonaiagents import Agent
|
||||
from praisonaiagents.tools import execute_query, load_csv, export_csv
|
||||
|
||||
agent = Agent(
|
||||
name="DBProcessor",
|
||||
description="An agent that works with DuckDB databases",
|
||||
tools=[execute_query, load_csv, export_csv]
|
||||
)
|
||||
```
|
||||
|
||||
## Error Handling
|
||||
|
||||
All functions include comprehensive error handling:
|
||||
- Database connection errors
|
||||
- Query syntax errors
|
||||
- File I/O errors
|
||||
- Schema validation errors
|
||||
- Missing dependency errors
|
||||
|
||||
Errors are logged and returned in a consistent format:
|
||||
- Success cases return the expected data type
|
||||
- Error cases return a dict with an "error" key containing the error message
|
||||
|
||||
## Common Use Cases
|
||||
|
||||
1. Data Analysis:
|
||||
```python
|
||||
# Load data
|
||||
load_csv("sales", "sales_data.csv")
|
||||
|
||||
# Analyze with SQL
|
||||
results = execute_query("""
|
||||
SELECT
|
||||
department,
|
||||
COUNT(*) as count,
|
||||
AVG(salary) as avg_salary
|
||||
FROM employees
|
||||
GROUP BY department
|
||||
HAVING count > 5
|
||||
ORDER BY avg_salary DESC
|
||||
""")
|
||||
```
|
||||
|
||||
2. Data Export:
|
||||
```python
|
||||
# Export filtered and aggregated data
|
||||
export_csv("""
|
||||
SELECT
|
||||
date_trunc('month', date) as month,
|
||||
SUM(amount) as total_sales
|
||||
FROM sales
|
||||
GROUP BY 1
|
||||
ORDER BY 1
|
||||
""", "monthly_sales.csv")
|
||||
```
|
||||
|
||||
3. Data Transformation:
|
||||
```python
|
||||
# Load and transform data
|
||||
load_csv("raw_data", "input.csv")
|
||||
execute_query("""
|
||||
CREATE TABLE transformed AS
|
||||
SELECT
|
||||
id,
|
||||
UPPER(name) as name,
|
||||
ROUND(amount, 2) as amount,
|
||||
DATE_TRUNC('day', timestamp) as date
|
||||
FROM raw_data
|
||||
""")
|
||||
export_csv("SELECT * FROM transformed", "transformed.csv")
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="Agent Configuration">
|
||||
Configure agents with clear database focus:
|
||||
```python
|
||||
Agent(
|
||||
name="DBProcessor",
|
||||
role="Database Specialist",
|
||||
goal="Process queries accurately and efficiently",
|
||||
tools=[execute_query, load_csv, export_csv]
|
||||
)
|
||||
```
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Task Definition">
|
||||
Define specific database operations:
|
||||
```python
|
||||
Task(
|
||||
description="Query sales data and generate reports",
|
||||
expected_output="Sales performance report"
|
||||
)
|
||||
```
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
## Common Patterns
|
||||
|
||||
### Database Operation Pipeline
|
||||
```python
|
||||
# Query agent
|
||||
querier = Agent(
|
||||
name="Querier",
|
||||
role="SQL Specialist",
|
||||
tools=[execute_query]
|
||||
)
|
||||
|
||||
# Analysis agent
|
||||
analyzer = Agent(
|
||||
name="Analyzer",
|
||||
role="Data Analyst"
|
||||
)
|
||||
|
||||
# Define tasks
|
||||
query_task = Task(
|
||||
description="Execute SQL queries",
|
||||
agent=querier
|
||||
)
|
||||
|
||||
analyze_task = Task(
|
||||
description="Analyze query results",
|
||||
agent=analyzer
|
||||
)
|
||||
|
||||
# Run workflow
|
||||
agents = PraisonAIAgents(
|
||||
agents=[querier, analyzer],
|
||||
tasks=[query_task, analyze_task]
|
||||
)
|
||||
@@ -0,0 +1,248 @@
|
||||
---
|
||||
title: "DuckDuckGo Agent"
|
||||
description: "Internet search tools using DuckDuckGo for AI agents."
|
||||
icon: "magnifying-glass"
|
||||
---
|
||||
|
||||
<Note>
|
||||
**Prerequisites**
|
||||
- Python 3.10 or higher
|
||||
- PraisonAI Agents package installed
|
||||
- `duckduckgo-search` package installed
|
||||
</Note>
|
||||
|
||||
## DuckDuckGo Tools
|
||||
|
||||
Use DuckDuckGo Tools to perform internet searches with AI agents.
|
||||
|
||||
<Steps>
|
||||
<Step title="Install Dependencies">
|
||||
First, install the required packages:
|
||||
```bash
|
||||
pip install praisonaiagents duckduckgo-search
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Import Components">
|
||||
Import the necessary components:
|
||||
```python
|
||||
from praisonaiagents import Agent, Task, PraisonAIAgents
|
||||
from praisonaiagents.tools import duckduckgo
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Create Agent">
|
||||
Create a search agent:
|
||||
```python
|
||||
search_agent = Agent(
|
||||
name="SearchAgent",
|
||||
role="Internet Search Specialist",
|
||||
goal="Perform accurate internet searches and extract relevant information.",
|
||||
backstory="Expert in finding and organizing internet data.",
|
||||
tools=[duckduckgo],
|
||||
self_reflect=False
|
||||
)
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Define Task">
|
||||
Define the search task:
|
||||
```python
|
||||
search_task = Task(
|
||||
description="Search for 'AI trends 2024' and analyze the results.",
|
||||
expected_output="List of key AI trends with sources.",
|
||||
agent=search_agent,
|
||||
name="search_trends"
|
||||
)
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Run Agent">
|
||||
Initialize and run the agent:
|
||||
```python
|
||||
agents = PraisonAIAgents(
|
||||
agents=[search_agent],
|
||||
tasks=[search_task],
|
||||
process="sequential"
|
||||
)
|
||||
agents.start()
|
||||
```
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
## Understanding DuckDuckGo Tools
|
||||
|
||||
<Card title="What are DuckDuckGo Tools?" icon="question">
|
||||
DuckDuckGo Tools provide internet search capabilities for AI agents:
|
||||
- Web search functionality
|
||||
- News search
|
||||
- Privacy-focused results
|
||||
- Region-specific searches
|
||||
</Card>
|
||||
|
||||
## Key Components
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Search Agent" icon="user-robot">
|
||||
Create specialized search agents:
|
||||
```python
|
||||
Agent(tools=[duckduckgo])
|
||||
```
|
||||
</Card>
|
||||
<Card title="Search Task" icon="list-check">
|
||||
Define search tasks:
|
||||
```python
|
||||
Task(description="search_query")
|
||||
```
|
||||
</Card>
|
||||
<Card title="Process Types" icon="arrows-split-up-and-left">
|
||||
Sequential or parallel processing:
|
||||
```python
|
||||
process="sequential"
|
||||
```
|
||||
</Card>
|
||||
<Card title="Search Options" icon="sliders">
|
||||
Customize search parameters:
|
||||
```python
|
||||
region="wt-wt", time="w"
|
||||
```
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
## Examples
|
||||
|
||||
### Basic Search Agent
|
||||
|
||||
```python
|
||||
from praisonaiagents import Agent, Task, PraisonAIAgents
|
||||
from praisonaiagents.tools import duckduckgo
|
||||
|
||||
# Create search agent
|
||||
search_agent = Agent(
|
||||
name="WebSearcher",
|
||||
role="Search Specialist",
|
||||
goal="Find accurate information about specified topics.",
|
||||
backstory="Expert in internet research and data collection.",
|
||||
tools=[duckduckgo],
|
||||
self_reflect=False
|
||||
)
|
||||
|
||||
# Define search task
|
||||
search_task = Task(
|
||||
description="Search for 'Python programming best practices 2024' and summarize the key points.",
|
||||
expected_output="List of best practices with sources.",
|
||||
agent=search_agent,
|
||||
name="search_python"
|
||||
)
|
||||
|
||||
# Run agent
|
||||
agents = PraisonAIAgents(
|
||||
agents=[search_agent],
|
||||
tasks=[search_task],
|
||||
process="sequential"
|
||||
)
|
||||
agents.start()
|
||||
```
|
||||
|
||||
### Advanced Search with Multiple Agents
|
||||
|
||||
```python
|
||||
# Create search agent
|
||||
search_agent = Agent(
|
||||
name="Researcher",
|
||||
role="Search Specialist",
|
||||
goal="Gather comprehensive information about topics.",
|
||||
tools=[duckduckgo],
|
||||
self_reflect=False
|
||||
)
|
||||
|
||||
# Create analysis agent
|
||||
analysis_agent = Agent(
|
||||
name="Analyzer",
|
||||
role="Data Analyst",
|
||||
goal="Analyze and synthesize search results.",
|
||||
backstory="Expert in data analysis and trend identification.",
|
||||
self_reflect=False
|
||||
)
|
||||
|
||||
# Define tasks
|
||||
search_task = Task(
|
||||
description="Search for latest AI developments in healthcare.",
|
||||
agent=search_agent,
|
||||
name="healthcare_search"
|
||||
)
|
||||
|
||||
analysis_task = Task(
|
||||
description="Analyze the search results and identify key trends.",
|
||||
agent=analysis_agent,
|
||||
name="trend_analysis"
|
||||
)
|
||||
|
||||
# Run agents
|
||||
agents = PraisonAIAgents(
|
||||
agents=[search_agent, analysis_agent],
|
||||
tasks=[search_task, analysis_task],
|
||||
process="sequential"
|
||||
)
|
||||
agents.start()
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="Agent Configuration">
|
||||
Configure agents with clear roles and goals:
|
||||
```python
|
||||
Agent(
|
||||
name="Researcher",
|
||||
role="Search Specialist",
|
||||
goal="Find accurate and relevant information",
|
||||
tools=[duckduckgo]
|
||||
)
|
||||
```
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Task Definition">
|
||||
Define specific and clear tasks:
|
||||
```python
|
||||
Task(
|
||||
description="Search for 'AI ethics guidelines 2024' and summarize key points",
|
||||
expected_output="Structured list of guidelines with sources"
|
||||
)
|
||||
```
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
## Common Patterns
|
||||
|
||||
### Research and Analysis
|
||||
```python
|
||||
# Research agent
|
||||
researcher = Agent(
|
||||
name="Researcher",
|
||||
role="Search Specialist",
|
||||
tools=[duckduckgo]
|
||||
)
|
||||
|
||||
# Analysis agent
|
||||
analyst = Agent(
|
||||
name="Analyst",
|
||||
role="Information Analyst"
|
||||
)
|
||||
|
||||
# Define tasks
|
||||
research_task = Task(
|
||||
description="Research quantum computing advances",
|
||||
agent=researcher
|
||||
)
|
||||
|
||||
analysis_task = Task(
|
||||
description="Analyze research findings",
|
||||
agent=analyst
|
||||
)
|
||||
|
||||
# Run workflow
|
||||
agents = PraisonAIAgents(
|
||||
agents=[researcher, analyst],
|
||||
tasks=[research_task, analysis_task]
|
||||
)
|
||||
@@ -0,0 +1,442 @@
|
||||
---
|
||||
title: "Excel Agent"
|
||||
description: "Excel file processing tools for AI agents."
|
||||
icon: "file-excel"
|
||||
---
|
||||
|
||||
<Note>
|
||||
**Prerequisites**
|
||||
- Python 3.10 or higher
|
||||
- PraisonAI Agents package installed
|
||||
- `openpyxl` package installed
|
||||
- Basic understanding of Excel files
|
||||
</Note>
|
||||
|
||||
## Excel Tools
|
||||
|
||||
Use Excel Tools to process and manipulate Excel files with AI agents.
|
||||
|
||||
<Steps>
|
||||
<Step title="Install Dependencies">
|
||||
First, install the required packages:
|
||||
```bash
|
||||
pip install praisonaiagents openpyxl
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Import Components">
|
||||
Import the necessary components:
|
||||
```python
|
||||
from praisonaiagents import Agent, Task, PraisonAIAgents
|
||||
from praisonaiagents.tools import read_excel, write_excel, merge_excel
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Create Agent">
|
||||
Create an Excel processing agent:
|
||||
```python
|
||||
excel_agent = Agent(
|
||||
name="ExcelProcessor",
|
||||
role="Excel Processing Specialist",
|
||||
goal="Process Excel files efficiently and accurately.",
|
||||
backstory="Expert in Excel file manipulation and analysis.",
|
||||
tools=[read_excel, write_excel, merge_excel],
|
||||
self_reflect=False
|
||||
)
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Define Task">
|
||||
Define the Excel processing task:
|
||||
```python
|
||||
excel_task = Task(
|
||||
description="Process and analyze Excel spreadsheets.",
|
||||
expected_output="Processed Excel data with analysis.",
|
||||
agent=excel_agent,
|
||||
name="excel_processing"
|
||||
)
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Run Agent">
|
||||
Initialize and run the agent:
|
||||
```python
|
||||
agents = PraisonAIAgents(
|
||||
agents=[excel_agent],
|
||||
tasks=[excel_task],
|
||||
process="sequential"
|
||||
)
|
||||
agents.start()
|
||||
```
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
## Understanding Excel Tools
|
||||
|
||||
<Card title="What are Excel Tools?" icon="question">
|
||||
Excel Tools provide Excel processing capabilities for AI agents:
|
||||
- File reading and writing
|
||||
- Data extraction
|
||||
- Sheet manipulation
|
||||
- Formula handling
|
||||
- Data analysis
|
||||
</Card>
|
||||
|
||||
## Key Components
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Excel Agent" icon="user-robot">
|
||||
Create specialized Excel agents:
|
||||
```python
|
||||
Agent(tools=[read_excel, write_excel, merge_excel])
|
||||
```
|
||||
</Card>
|
||||
<Card title="Excel Task" icon="list-check">
|
||||
Define Excel tasks:
|
||||
```python
|
||||
Task(description="excel_operation")
|
||||
```
|
||||
</Card>
|
||||
<Card title="Process Types" icon="arrows-split-up-and-left">
|
||||
Sequential or parallel processing:
|
||||
```python
|
||||
process="sequential"
|
||||
```
|
||||
</Card>
|
||||
<Card title="Excel Options" icon="sliders">
|
||||
Customize Excel parameters:
|
||||
```python
|
||||
sheet_name="Sheet1", header=0
|
||||
```
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
## Available Functions
|
||||
|
||||
```python
|
||||
from praisonaiagents.tools import read_excel
|
||||
from praisonaiagents.tools import write_excel
|
||||
from praisonaiagents.tools import merge_excel
|
||||
```
|
||||
|
||||
## Function Details
|
||||
|
||||
### read_excel(filepath: str, sheet_name: Optional[Union[str, int, List[Union[str, int]]]] = 0, header: Optional[int] = 0, usecols: Optional[List[str]] = None, skiprows: Optional[Union[int, List[int]]] = None, na_values: Optional[List[str]] = None, dtype: Optional[Dict[str, str]] = None)
|
||||
|
||||
Reads Excel files with advanced options:
|
||||
- Support for multiple sheets
|
||||
- Flexible header handling
|
||||
- Column selection
|
||||
- Row skipping
|
||||
- Custom NA values
|
||||
- Data type specification
|
||||
|
||||
```python
|
||||
# Basic usage - read first sheet
|
||||
data = read_excel("data.xlsx")
|
||||
|
||||
# Read specific sheets
|
||||
data = read_excel(
|
||||
"data.xlsx",
|
||||
sheet_name=['Sheet1', 'Sheet2'],
|
||||
header=0,
|
||||
usecols=['A', 'B', 'C'],
|
||||
skiprows=[0, 1],
|
||||
na_values=['NA', 'missing'],
|
||||
dtype={'age': 'int32', 'salary': 'float64'}
|
||||
)
|
||||
# Returns: Dict[str, List[Dict[str, Any]]] for multiple sheets
|
||||
# Example: {
|
||||
# 'Sheet1': [{"name": "Alice", "age": 25}, ...],
|
||||
# 'Sheet2': [{"dept": "Engineering", "count": 10}, ...]
|
||||
# }
|
||||
```
|
||||
|
||||
### write_excel(filepath: str, data: Union[Dict[str, List[Dict[str, Any]]], List[Dict[str, Any]]], sheet_name: Optional[str] = None, index: bool = False, header: bool = True, mode: str = 'w')
|
||||
|
||||
Writes data to Excel files with formatting:
|
||||
- Multiple sheet support
|
||||
- Append mode for existing files
|
||||
- Optional row indices
|
||||
- Optional headers
|
||||
- Flexible data structure handling
|
||||
|
||||
```python
|
||||
# Write single sheet
|
||||
data = [
|
||||
{"name": "Alice", "age": 25, "city": "New York"},
|
||||
{"name": "Bob", "age": 30, "city": "San Francisco"}
|
||||
]
|
||||
success = write_excel("output.xlsx", data, sheet_name="Employees")
|
||||
|
||||
# Write multiple sheets
|
||||
data = {
|
||||
"Employees": [
|
||||
{"name": "Alice", "age": 25},
|
||||
{"name": "Bob", "age": 30}
|
||||
],
|
||||
"Departments": [
|
||||
{"name": "Engineering", "count": 50},
|
||||
{"name": "Sales", "count": 30}
|
||||
]
|
||||
}
|
||||
success = write_excel(
|
||||
"company.xlsx",
|
||||
data,
|
||||
index=False,
|
||||
header=True,
|
||||
mode='w'
|
||||
)
|
||||
# Returns: bool (True if successful)
|
||||
```
|
||||
|
||||
### merge_excel(files: List[str], output_file: str, how: str = 'inner', on: Optional[Union[str, List[str]]] = None, suffixes: Optional[Tuple[str, str]] = None)
|
||||
|
||||
Merges multiple Excel files:
|
||||
- Flexible join operations
|
||||
- Multiple key columns support
|
||||
- Custom column suffix handling
|
||||
- Preserves data types
|
||||
|
||||
```python
|
||||
# Merge two files on a common column
|
||||
success = merge_excel(
|
||||
files=["employees.xlsx", "salaries.xlsx"],
|
||||
output_file="merged.xlsx",
|
||||
how='inner',
|
||||
on='employee_id'
|
||||
)
|
||||
|
||||
# Advanced merge with multiple keys and custom suffixes
|
||||
success = merge_excel(
|
||||
files=["data2022.xlsx", "data2023.xlsx"],
|
||||
output_file="combined.xlsx",
|
||||
how='outer',
|
||||
on=['id', 'department'],
|
||||
suffixes=('_2022', '_2023')
|
||||
)
|
||||
# Returns: bool (True if successful)
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
### Basic Excel Processing Agent
|
||||
|
||||
```python
|
||||
from praisonaiagents import Agent, Task, PraisonAIAgents
|
||||
from praisonaiagents.tools import read_excel, write_excel, merge_excel
|
||||
|
||||
# Create Excel agent
|
||||
excel_agent = Agent(
|
||||
name="ExcelExpert",
|
||||
role="Excel Processing Specialist",
|
||||
goal="Process Excel files efficiently and accurately.",
|
||||
backstory="Expert in spreadsheet manipulation and analysis.",
|
||||
tools=[read_excel, write_excel, merge_excel],
|
||||
self_reflect=False
|
||||
)
|
||||
|
||||
# Define Excel task
|
||||
excel_task = Task(
|
||||
description="Process and analyze sales data.",
|
||||
expected_output="Sales analysis report.",
|
||||
agent=excel_agent,
|
||||
name="sales_analysis"
|
||||
)
|
||||
|
||||
# Run agent
|
||||
agents = PraisonAIAgents(
|
||||
agents=[excel_agent],
|
||||
tasks=[excel_task],
|
||||
process="sequential"
|
||||
)
|
||||
agents.start()
|
||||
```
|
||||
|
||||
### Advanced Excel Processing with Multiple Agents
|
||||
|
||||
```python
|
||||
# Create data processing agent
|
||||
processor_agent = Agent(
|
||||
name="Processor",
|
||||
role="Data Processor",
|
||||
goal="Process Excel data systematically.",
|
||||
tools=[read_excel, write_excel, merge_excel],
|
||||
self_reflect=False
|
||||
)
|
||||
|
||||
# Create analysis agent
|
||||
analysis_agent = Agent(
|
||||
name="Analyzer",
|
||||
role="Data Analyst",
|
||||
goal="Analyze processed Excel data.",
|
||||
backstory="Expert in data analysis and reporting.",
|
||||
self_reflect=False
|
||||
)
|
||||
|
||||
# Define tasks
|
||||
processing_task = Task(
|
||||
description="Process sales spreadsheets.",
|
||||
agent=processor_agent,
|
||||
name="data_processing"
|
||||
)
|
||||
|
||||
analysis_task = Task(
|
||||
description="Analyze sales trends and patterns.",
|
||||
agent=analysis_agent,
|
||||
name="data_analysis"
|
||||
)
|
||||
|
||||
# Run agents
|
||||
agents = PraisonAIAgents(
|
||||
agents=[processor_agent, analysis_agent],
|
||||
tasks=[processing_task, analysis_task],
|
||||
process="sequential"
|
||||
)
|
||||
agents.start()
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="Agent Configuration">
|
||||
Configure agents with clear Excel focus:
|
||||
```python
|
||||
Agent(
|
||||
name="ExcelProcessor",
|
||||
role="Excel Processing Specialist",
|
||||
goal="Process Excel files accurately and efficiently",
|
||||
tools=[read_excel, write_excel, merge_excel]
|
||||
)
|
||||
```
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Task Definition">
|
||||
Define specific Excel operations:
|
||||
```python
|
||||
Task(
|
||||
description="Process sales data and generate reports"
|
||||
)
|
||||
```
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
## Common Patterns
|
||||
|
||||
### Excel Processing Pipeline
|
||||
```python
|
||||
# Processing agent
|
||||
processor = Agent(
|
||||
name="Processor",
|
||||
role="Excel Processor",
|
||||
tools=[read_excel, write_excel, merge_excel]
|
||||
)
|
||||
|
||||
# Analysis agent
|
||||
analyzer = Agent(
|
||||
name="Analyzer",
|
||||
role="Data Analyst"
|
||||
)
|
||||
|
||||
# Define tasks
|
||||
process_task = Task(
|
||||
description="Process Excel files",
|
||||
agent=processor
|
||||
)
|
||||
|
||||
analyze_task = Task(
|
||||
description="Analyze processed data",
|
||||
agent=analyzer
|
||||
)
|
||||
|
||||
# Run workflow
|
||||
agents = PraisonAIAgents(
|
||||
agents=[processor, analyzer],
|
||||
tasks=[process_task, analyze_task]
|
||||
)
|
||||
|
||||
```
|
||||
|
||||
## Dependencies
|
||||
|
||||
The Excel tools require the following Python packages:
|
||||
- pandas: For data manipulation
|
||||
- openpyxl: For Excel file operations
|
||||
|
||||
These will be automatically installed when needed.
|
||||
|
||||
## Example Agent Configuration
|
||||
|
||||
```python
|
||||
from praisonaiagents import Agent
|
||||
from praisonaiagents.tools import read_excel, write_excel, merge_excel
|
||||
|
||||
agent = Agent(
|
||||
name="ExcelProcessor",
|
||||
description="An agent that processes Excel files",
|
||||
tools=[read_excel, write_excel, merge_excel]
|
||||
)
|
||||
```
|
||||
|
||||
## Error Handling
|
||||
|
||||
All functions include comprehensive error handling:
|
||||
- File not found errors
|
||||
- Permission errors
|
||||
- Invalid sheet names
|
||||
- Data format errors
|
||||
- Missing dependency errors
|
||||
|
||||
Errors are logged and returned in a consistent format:
|
||||
- Success cases return the expected data type
|
||||
- Error cases return a dict with an "error" key containing the error message
|
||||
|
||||
## Common Use Cases
|
||||
|
||||
1. Data Analysis:
|
||||
```python
|
||||
# Read and analyze employee data
|
||||
data = read_excel(
|
||||
"employees.xlsx",
|
||||
sheet_name="Salaries",
|
||||
usecols=["department", "salary"]
|
||||
)
|
||||
|
||||
# Write summary to new sheet
|
||||
summary = [
|
||||
{"department": dept, "avg_salary": sum(d["salary"] for d in dept_data) / len(dept_data)}
|
||||
for dept, dept_data in groupby(data, key=lambda x: x["department"])
|
||||
]
|
||||
write_excel("summary.xlsx", summary, sheet_name="Salary Summary")
|
||||
```
|
||||
|
||||
2. Data Consolidation:
|
||||
```python
|
||||
# Merge monthly reports
|
||||
monthly_files = ["jan.xlsx", "feb.xlsx", "mar.xlsx"]
|
||||
merge_excel(
|
||||
files=monthly_files,
|
||||
output_file="q1_report.xlsx",
|
||||
how='outer',
|
||||
on='transaction_id'
|
||||
)
|
||||
```
|
||||
|
||||
3. Multi-sheet Processing:
|
||||
```python
|
||||
# Read multiple sheets
|
||||
data = read_excel(
|
||||
"company_data.xlsx",
|
||||
sheet_name=None # Read all sheets
|
||||
)
|
||||
|
||||
# Process each sheet
|
||||
processed = {
|
||||
sheet: [process_record(record) for record in records]
|
||||
for sheet, records in data.items()
|
||||
}
|
||||
|
||||
# Write back to new file
|
||||
write_excel("processed_data.xlsx", processed)
|
||||
|
||||
```
|
||||
@@ -0,0 +1,472 @@
|
||||
---
|
||||
title: "File Agent"
|
||||
description: "File system operation tools for AI agents."
|
||||
icon: "folder"
|
||||
---
|
||||
|
||||
<Note>
|
||||
**Prerequisites**
|
||||
- Python 3.10 or higher
|
||||
- PraisonAI Agents package installed
|
||||
- Basic understanding of file operations
|
||||
</Note>
|
||||
|
||||
## File Tools
|
||||
|
||||
Use File Tools to perform file system operations with AI agents.
|
||||
|
||||
<Steps>
|
||||
<Step title="Install Dependencies">
|
||||
First, install the required package:
|
||||
```bash
|
||||
pip install praisonaiagents
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Import Components">
|
||||
Import the necessary components:
|
||||
```python
|
||||
from praisonaiagents import Agent, Task, PraisonAIAgents
|
||||
from praisonaiagents.tools import read_file, write_file, list_files, get_file_info, copy_file, move_file, delete_file
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Create Agent">
|
||||
Create a file management agent:
|
||||
```python
|
||||
file_agent = Agent(
|
||||
name="FileManager",
|
||||
role="File System Specialist",
|
||||
goal="Manage files and directories efficiently.",
|
||||
backstory="Expert in file system operations and organization.",
|
||||
tools=[read_file, write_file, list_files, get_file_info, copy_file, move_file, delete_file],
|
||||
self_reflect=False
|
||||
)
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Define Task">
|
||||
Define the file management task:
|
||||
```python
|
||||
file_task = Task(
|
||||
description="Organize files in the downloads directory by file type.",
|
||||
expected_output="Organized directory structure with categorized files.",
|
||||
agent=file_agent,
|
||||
name="organize_files"
|
||||
)
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Run Agent">
|
||||
Initialize and run the agent:
|
||||
```python
|
||||
agents = PraisonAIAgents(
|
||||
agents=[file_agent],
|
||||
tasks=[file_task],
|
||||
process="sequential"
|
||||
)
|
||||
agents.start()
|
||||
```
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
## Understanding File Tools
|
||||
|
||||
<Card title="What are File Tools?" icon="question">
|
||||
File Tools provide file system management capabilities for AI agents:
|
||||
- File operations (read, write, copy, move)
|
||||
- Directory management
|
||||
- File information retrieval
|
||||
- File organization
|
||||
- Path manipulation
|
||||
</Card>
|
||||
|
||||
## Key Components
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="File Agent" icon="user-robot">
|
||||
Create specialized file agents:
|
||||
```python
|
||||
Agent(tools=[read_file, write_file, list_files, get_file_info, copy_file, move_file, delete_file])
|
||||
```
|
||||
</Card>
|
||||
<Card title="File Task" icon="list-check">
|
||||
Define file tasks:
|
||||
```python
|
||||
Task(description="file_operation")
|
||||
```
|
||||
</Card>
|
||||
<Card title="Process Types" icon="arrows-split-up-and-left">
|
||||
Sequential or parallel processing:
|
||||
```python
|
||||
process="sequential"
|
||||
```
|
||||
</Card>
|
||||
<Card title="File Options" icon="sliders">
|
||||
Customize file operations:
|
||||
```python
|
||||
recursive=True, overwrite=False
|
||||
```
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
## Available Functions
|
||||
|
||||
```python
|
||||
from praisonaiagents.tools import read_file
|
||||
from praisonaiagents.tools import write_file
|
||||
from praisonaiagents.tools import list_files
|
||||
from praisonaiagents.tools import get_file_info
|
||||
from praisonaiagents.tools import copy_file
|
||||
from praisonaiagents.tools import move_file
|
||||
from praisonaiagents.tools import delete_file
|
||||
```
|
||||
|
||||
## Function Details
|
||||
|
||||
### read_file(filepath: str, encoding: str = 'utf-8')
|
||||
|
||||
Reads content from a file:
|
||||
- Supports different encodings
|
||||
- Error handling for missing files
|
||||
- Automatic encoding detection
|
||||
|
||||
```python
|
||||
# Basic usage
|
||||
content = read_file("example.txt")
|
||||
|
||||
# With specific encoding
|
||||
content = read_file("data.txt", encoding="latin-1")
|
||||
|
||||
# Returns: str (file content)
|
||||
# Error case: Returns error message as string
|
||||
```
|
||||
|
||||
### write_file(filepath: str, content: str, encoding: str = 'utf-8')
|
||||
|
||||
Writes content to a file:
|
||||
- Creates directories if they don't exist
|
||||
- Supports different encodings
|
||||
- Overwrites existing files
|
||||
|
||||
```python
|
||||
# Basic usage
|
||||
success = write_file("output.txt", "Hello World")
|
||||
|
||||
# With specific encoding and nested path
|
||||
success = write_file(
|
||||
"path/to/data/output.txt",
|
||||
"Content with special chars: áéíóú",
|
||||
encoding="utf-8"
|
||||
)
|
||||
# Returns: bool (True if successful)
|
||||
```
|
||||
|
||||
### list_files(directory: str, pattern: Optional[str] = None)
|
||||
|
||||
Lists files in a directory:
|
||||
- Optional pattern matching
|
||||
- Detailed file information
|
||||
- Recursive directory support
|
||||
|
||||
```python
|
||||
# List all files
|
||||
files = list_files("/path/to/directory")
|
||||
|
||||
# With pattern matching
|
||||
files = list_files("/path/to/directory", pattern="*.txt")
|
||||
|
||||
# Returns: List[Dict[str, Union[str, int]]]
|
||||
# Example: [
|
||||
# {
|
||||
# 'name': 'example.txt',
|
||||
# 'path': '/path/to/directory/example.txt',
|
||||
# 'size': 1024,
|
||||
# 'modified': 1609459200.0,
|
||||
# 'created': 1609459100.0
|
||||
# },
|
||||
# ...
|
||||
# ]
|
||||
```
|
||||
|
||||
### get_file_info(filepath: str)
|
||||
|
||||
Gets detailed information about a file:
|
||||
- File metadata
|
||||
- Size and timestamps
|
||||
- Type information
|
||||
- Path details
|
||||
|
||||
```python
|
||||
# Get file information
|
||||
info = get_file_info("example.txt")
|
||||
|
||||
# Returns: Dict[str, Union[str, int]]
|
||||
# Example: {
|
||||
# 'name': 'example.txt',
|
||||
# 'path': '/absolute/path/to/example.txt',
|
||||
# 'size': 1024,
|
||||
# 'modified': 1609459200.0,
|
||||
# 'created': 1609459100.0,
|
||||
# 'is_file': True,
|
||||
# 'is_dir': False,
|
||||
# 'extension': '.txt',
|
||||
# 'parent': '/absolute/path/to'
|
||||
# }
|
||||
```
|
||||
|
||||
### copy_file(src: str, dst: str)
|
||||
|
||||
Copies a file with metadata:
|
||||
- Preserves timestamps
|
||||
- Creates destination directories
|
||||
- Handles existing files
|
||||
|
||||
```python
|
||||
# Basic copy
|
||||
success = copy_file("source.txt", "destination.txt")
|
||||
|
||||
# Copy to new directory
|
||||
success = copy_file(
|
||||
"data.txt",
|
||||
"backup/2023/data_backup.txt"
|
||||
)
|
||||
# Returns: bool (True if successful)
|
||||
```
|
||||
|
||||
### move_file(src: str, dst: str)
|
||||
|
||||
Moves or renames a file:
|
||||
- Creates destination directories
|
||||
- Handles existing files
|
||||
- Cross-device moves
|
||||
|
||||
```python
|
||||
# Move file
|
||||
success = move_file("old/path/file.txt", "new/path/file.txt")
|
||||
|
||||
# Rename file
|
||||
success = move_file(
|
||||
"document.txt",
|
||||
"document_v2.txt"
|
||||
)
|
||||
# Returns: bool (True if successful)
|
||||
```
|
||||
|
||||
### delete_file(filepath: str)
|
||||
|
||||
Deletes a file:
|
||||
- Safe deletion
|
||||
- Error handling
|
||||
- Non-recursive (files only)
|
||||
|
||||
```python
|
||||
# Delete file
|
||||
success = delete_file("unwanted.txt")
|
||||
# Returns: bool (True if successful)
|
||||
```
|
||||
|
||||
## Example Agent Configuration
|
||||
|
||||
```python
|
||||
from praisonaiagents import Agent
|
||||
from praisonaiagents.tools import (
|
||||
read_file, write_file, list_files,
|
||||
get_file_info, copy_file, move_file, delete_file
|
||||
)
|
||||
|
||||
agent = Agent(
|
||||
name="FileManager",
|
||||
description="An agent that manages files",
|
||||
tools=[
|
||||
read_file, write_file, list_files,
|
||||
get_file_info, copy_file, move_file, delete_file
|
||||
]
|
||||
)
|
||||
```
|
||||
|
||||
## Error Handling
|
||||
|
||||
All functions include comprehensive error handling:
|
||||
- File not found errors
|
||||
- Permission errors
|
||||
- Path errors
|
||||
- I/O errors
|
||||
- Encoding errors
|
||||
|
||||
Errors are handled consistently:
|
||||
- File operations return bool for success/failure
|
||||
- Information functions return error details in result
|
||||
- All errors are logged for debugging
|
||||
|
||||
## Common Use Cases
|
||||
|
||||
1. File Organization:
|
||||
```python
|
||||
# List and organize files by extension
|
||||
files = list_files("downloads", pattern="*.*")
|
||||
for file in files:
|
||||
ext = file['extension']
|
||||
if ext:
|
||||
dst = f"organized/{ext[1:]}/{file['name']}"
|
||||
move_file(file['path'], dst)
|
||||
```
|
||||
|
||||
2. File Backup:
|
||||
```python
|
||||
# Create timestamped backups
|
||||
import time
|
||||
files = list_files("important_data")
|
||||
backup_time = time.strftime("%Y%m%d_%H%M%S")
|
||||
for file in files:
|
||||
dst = f"backup/{backup_time}/{file['name']}"
|
||||
copy_file(file['path'], dst)
|
||||
```
|
||||
|
||||
3. File Processing:
|
||||
```python
|
||||
# Read, process, and write files
|
||||
content = read_file("input.txt")
|
||||
processed = process_content(content) # Your processing function
|
||||
write_file("output.txt", processed)
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
### Basic File Management Agent
|
||||
|
||||
```python
|
||||
from praisonaiagents import Agent, Task, PraisonAIAgents
|
||||
from praisonaiagents.tools import read_file, write_file, list_files, get_file_info
|
||||
|
||||
# Create file management agent
|
||||
file_agent = Agent(
|
||||
name="FileExpert",
|
||||
role="File Manager",
|
||||
goal="Process and organize files efficiently.",
|
||||
backstory="Expert in file system operations and organization.",
|
||||
tools=[read_file, write_file, list_files, get_file_info],
|
||||
self_reflect=False
|
||||
)
|
||||
|
||||
# Define file task
|
||||
file_task = Task(
|
||||
description="Organize and process documents.",
|
||||
expected_output="Organized file structure.",
|
||||
agent=file_agent,
|
||||
name="file_organization"
|
||||
)
|
||||
|
||||
# Run agent
|
||||
agents = PraisonAIAgents(
|
||||
agents=[file_agent],
|
||||
tasks=[file_task],
|
||||
process="sequential"
|
||||
)
|
||||
agents.start()
|
||||
```
|
||||
|
||||
### Advanced File Operations with Multiple Agents
|
||||
|
||||
```python
|
||||
# Create file IO agent
|
||||
io_agent = Agent(
|
||||
name="FileIO",
|
||||
role="File IO Specialist",
|
||||
goal="Handle file read/write operations efficiently.",
|
||||
tools=[read_file, write_file],
|
||||
self_reflect=False
|
||||
)
|
||||
|
||||
# Create file management agent
|
||||
management_agent = Agent(
|
||||
name="FileManager",
|
||||
role="File Management Specialist",
|
||||
goal="Handle file organization and movement.",
|
||||
tools=[list_files, get_file_info, copy_file, move_file, delete_file],
|
||||
self_reflect=False
|
||||
)
|
||||
|
||||
# Define tasks
|
||||
io_task = Task(
|
||||
description="Read and write files.",
|
||||
expected_output="File operations completed successfully.",
|
||||
agent=io_agent,
|
||||
name="file_io"
|
||||
)
|
||||
|
||||
management_task = Task(
|
||||
description="Organize and move files.",
|
||||
expected_output="File management completed successfully.",
|
||||
agent=management_agent,
|
||||
name="file_management"
|
||||
)
|
||||
|
||||
# Run agents
|
||||
agents = PraisonAIAgents(
|
||||
agents=[io_agent, management_agent],
|
||||
tasks=[io_task, management_task],
|
||||
process="sequential"
|
||||
)
|
||||
agents.start()
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="Agent Configuration">
|
||||
Configure agents with clear file management focus:
|
||||
```python
|
||||
Agent(
|
||||
name="FileManager",
|
||||
role="File System Specialist",
|
||||
goal="Manage files efficiently and safely",
|
||||
tools=[read_file, write_file, list_files, get_file_info, copy_file, move_file, delete_file]
|
||||
)
|
||||
```
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Task Definition">
|
||||
Define specific file operations:
|
||||
```python
|
||||
Task(
|
||||
description="Clean up downloads folder and organize by file type",
|
||||
expected_output="Organized directory structure"
|
||||
)
|
||||
```
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
## Common Patterns
|
||||
|
||||
### File Organization Pipeline
|
||||
```python
|
||||
# Organization agent
|
||||
organizer = Agent(
|
||||
name="Organizer",
|
||||
role="File Organizer",
|
||||
tools=[read_file, write_file, list_files, get_file_info, copy_file, move_file, delete_file]
|
||||
)
|
||||
|
||||
# Cleanup agent
|
||||
cleaner = Agent(
|
||||
name="Cleaner",
|
||||
role="File Cleaner"
|
||||
)
|
||||
|
||||
# Define tasks
|
||||
organize_task = Task(
|
||||
description="Organize files by type",
|
||||
agent=organizer
|
||||
)
|
||||
|
||||
cleanup_task = Task(
|
||||
description="Remove temporary files",
|
||||
agent=cleaner
|
||||
)
|
||||
|
||||
# Run workflow
|
||||
agents = PraisonAIAgents(
|
||||
agents=[organizer, cleaner],
|
||||
tasks=[organize_task, cleanup_task]
|
||||
)
|
||||
@@ -0,0 +1,587 @@
|
||||
---
|
||||
title: "JSON Agent"
|
||||
description: "JSON data processing tools for AI agents."
|
||||
icon: "braces"
|
||||
---
|
||||
|
||||
<Note>
|
||||
**Prerequisites**
|
||||
- Python 3.10 or higher
|
||||
- PraisonAI Agents package installed
|
||||
- Basic understanding of JSON format
|
||||
</Note>
|
||||
|
||||
## JSON Tools
|
||||
|
||||
Use JSON Tools to process and manipulate JSON files with AI agents.
|
||||
|
||||
<Steps>
|
||||
<Step title="Install Dependencies">
|
||||
First, install the required package:
|
||||
```bash
|
||||
pip install praisonaiagents
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Import Components">
|
||||
Import the necessary components:
|
||||
```python
|
||||
from praisonaiagents import Agent, Task, PraisonAIAgents
|
||||
from praisonaiagents.tools import (
|
||||
read_json, write_json, merge_json,
|
||||
validate_json, analyze_json, transform_json
|
||||
)
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Create Agent">
|
||||
Create a JSON processing agent:
|
||||
```python
|
||||
json_agent = Agent(
|
||||
name="JSONProcessor",
|
||||
role="JSON Processing Specialist",
|
||||
goal="Process JSON files efficiently and accurately.",
|
||||
backstory="Expert in JSON file manipulation and validation.",
|
||||
tools=[
|
||||
read_json, write_json, merge_json,
|
||||
validate_json, analyze_json, transform_json
|
||||
],
|
||||
self_reflect=False
|
||||
)
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Define Task">
|
||||
Define the JSON processing task:
|
||||
```python
|
||||
json_task = Task(
|
||||
description="Parse and validate API response data.",
|
||||
expected_output="Validated and processed JSON data.",
|
||||
agent=json_agent,
|
||||
name="json_processing"
|
||||
)
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Run Agent">
|
||||
Initialize and run the agent:
|
||||
```python
|
||||
agents = PraisonAIAgents(
|
||||
agents=[json_agent],
|
||||
tasks=[json_task],
|
||||
process="sequential"
|
||||
)
|
||||
agents.start()
|
||||
```
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
## Understanding JSON Tools
|
||||
|
||||
<Card title="What are JSON Tools?" icon="question">
|
||||
JSON Tools provide JSON processing capabilities for AI agents:
|
||||
- File reading and writing
|
||||
- Data validation
|
||||
- Schema validation
|
||||
- Data transformation
|
||||
- Structure analysis
|
||||
</Card>
|
||||
|
||||
## Key Components
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="JSON Agent" icon="user-robot">
|
||||
Create specialized JSON agents:
|
||||
```python
|
||||
Agent(tools=[read_json, write_json, merge_json, validate_json, analyze_json, transform_json])
|
||||
```
|
||||
</Card>
|
||||
<Card title="JSON Task" icon="list-check">
|
||||
Define JSON tasks:
|
||||
```python
|
||||
Task(description="json_operation")
|
||||
```
|
||||
</Card>
|
||||
<Card title="Process Types" icon="arrows-split-up-and-left">
|
||||
Sequential or parallel processing:
|
||||
```python
|
||||
process="sequential"
|
||||
```
|
||||
</Card>
|
||||
<Card title="JSON Options" icon="sliders">
|
||||
Customize JSON operations:
|
||||
```python
|
||||
indent=2, sort_keys=True
|
||||
```
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
## Available Functions
|
||||
|
||||
```python
|
||||
from praisonaiagents.tools import read_json
|
||||
from praisonaiagents.tools import write_json
|
||||
from praisonaiagents.tools import merge_json
|
||||
from praisonaiagents.tools import validate_json
|
||||
from praisonaiagents.tools import analyze_json
|
||||
from praisonaiagents.tools import transform_json
|
||||
```
|
||||
|
||||
## Function Details
|
||||
|
||||
### read_json(filepath: str, encoding: str = 'utf-8', validate_schema: Optional[Dict[str, Any]] = None)
|
||||
|
||||
Reads JSON files with schema validation:
|
||||
- Optional schema validation
|
||||
- Custom encoding support
|
||||
- Error handling
|
||||
|
||||
```python
|
||||
# Basic usage
|
||||
data = read_json("config.json")
|
||||
|
||||
# With schema validation
|
||||
schema = {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {"type": "string"},
|
||||
"age": {"type": "integer"}
|
||||
}
|
||||
}
|
||||
data = read_json(
|
||||
"user.json",
|
||||
encoding="utf-8",
|
||||
validate_schema=schema
|
||||
)
|
||||
|
||||
# Returns: Dict[str, Any] (JSON data)
|
||||
# Error case: Returns dict with 'error' key
|
||||
```
|
||||
|
||||
### write_json(data: Union[Dict[str, Any], List[Any]], filepath: str, encoding: str = 'utf-8', indent: int = 2, sort_keys: bool = False, ensure_ascii: bool = False)
|
||||
|
||||
Writes data to JSON files:
|
||||
- Pretty printing with indentation
|
||||
- Optional key sorting
|
||||
- Unicode support
|
||||
- Directory creation
|
||||
|
||||
```python
|
||||
# Basic usage
|
||||
data = {"name": "Alice", "age": 30}
|
||||
success = write_json(data, "output.json")
|
||||
|
||||
# With formatting options
|
||||
data = {
|
||||
"users": [
|
||||
{"name": "Alice", "age": 30},
|
||||
{"name": "Bob", "age": 25}
|
||||
]
|
||||
}
|
||||
success = write_json(
|
||||
data,
|
||||
"users.json",
|
||||
indent=4,
|
||||
sort_keys=True,
|
||||
ensure_ascii=False
|
||||
)
|
||||
# Returns: bool (True if successful)
|
||||
```
|
||||
|
||||
### merge_json(files: List[str], output_file: str, merge_arrays: bool = True, overwrite_duplicates: bool = True)
|
||||
|
||||
Merges multiple JSON files:
|
||||
- Deep merging of objects
|
||||
- Array handling options
|
||||
- Duplicate key handling
|
||||
- Nested structure support
|
||||
|
||||
```python
|
||||
# Merge configuration files
|
||||
success = merge_json(
|
||||
files=["config1.json", "config2.json"],
|
||||
output_file="merged_config.json"
|
||||
)
|
||||
|
||||
# Advanced merge with options
|
||||
success = merge_json(
|
||||
files=["base.json", "override.json"],
|
||||
output_file="final.json",
|
||||
merge_arrays=True,
|
||||
overwrite_duplicates=False
|
||||
)
|
||||
# Returns: bool (True if successful)
|
||||
```
|
||||
|
||||
### validate_json(data: Union[Dict[str, Any], str], schema: Dict[str, Any])
|
||||
|
||||
Validates JSON against a schema:
|
||||
- JSON Schema support
|
||||
- Detailed error messages
|
||||
- File or data validation
|
||||
|
||||
```python
|
||||
# Validate data
|
||||
schema = {
|
||||
"type": "object",
|
||||
"required": ["name", "email"],
|
||||
"properties": {
|
||||
"name": {"type": "string"},
|
||||
"email": {"type": "string", "format": "email"},
|
||||
"age": {"type": "integer", "minimum": 0}
|
||||
}
|
||||
}
|
||||
|
||||
# Validate data directly
|
||||
data = {"name": "Alice", "email": "[email protected]", "age": 25}
|
||||
is_valid, error = validate_json(data, schema)
|
||||
|
||||
# Validate file
|
||||
is_valid, error = validate_json("user.json", schema)
|
||||
# Returns: Tuple[bool, Optional[str]]
|
||||
```
|
||||
|
||||
### analyze_json(data: Union[Dict[str, Any], str], max_depth: int = 10)
|
||||
|
||||
Analyzes JSON structure:
|
||||
- Type information
|
||||
- Size metrics
|
||||
- Nested structure analysis
|
||||
- Sample data
|
||||
|
||||
```python
|
||||
# Analyze file
|
||||
analysis = analyze_json("data.json", max_depth=5)
|
||||
|
||||
# Analyze data structure
|
||||
data = {
|
||||
"users": [
|
||||
{"name": "Alice", "scores": [95, 87, 92]},
|
||||
{"name": "Bob", "scores": [88, 85, 90]}
|
||||
]
|
||||
}
|
||||
analysis = analyze_json(data)
|
||||
|
||||
# Returns: Dict[str, Any]
|
||||
# Example output:
|
||||
# {
|
||||
# 'analysis_time': '2023-01-01T12:00:00',
|
||||
# 'structure': {
|
||||
# 'type': 'dict',
|
||||
# 'size': 1,
|
||||
# 'keys': ['users'],
|
||||
# 'children': {
|
||||
# 'users': {
|
||||
# 'type': 'list',
|
||||
# 'length': 2,
|
||||
# 'element_types': ['dict'],
|
||||
# 'sample_elements': [...]
|
||||
# }
|
||||
# }
|
||||
# }
|
||||
# }
|
||||
```
|
||||
|
||||
### transform_json(data: Union[Dict[str, Any], str], transformations: List[Dict[str, Any]])
|
||||
|
||||
Transforms JSON data:
|
||||
- Multiple operations
|
||||
- Path-based modifications
|
||||
- Nested transformations
|
||||
- Operation types: set, delete, rename, move
|
||||
|
||||
```python
|
||||
# Transform data
|
||||
transformations = [
|
||||
{
|
||||
"operation": "set",
|
||||
"path": "user.settings.theme",
|
||||
"value": "dark"
|
||||
},
|
||||
{
|
||||
"operation": "move",
|
||||
"path": "old.config",
|
||||
"value": "new.config"
|
||||
},
|
||||
{
|
||||
"operation": "delete",
|
||||
"path": "temporary.data"
|
||||
}
|
||||
]
|
||||
|
||||
# Transform file
|
||||
result = transform_json("config.json", transformations)
|
||||
|
||||
# Transform data directly
|
||||
data = {"user": {"name": "Alice"}}
|
||||
result = transform_json(data, transformations)
|
||||
# Returns: Dict[str, Any] (transformed data)
|
||||
```
|
||||
|
||||
## Example Agent Configuration
|
||||
|
||||
```python
|
||||
from praisonaiagents import Agent
|
||||
from praisonaiagents.tools import (
|
||||
read_json, write_json, merge_json,
|
||||
validate_json, analyze_json, transform_json
|
||||
)
|
||||
|
||||
agent = Agent(
|
||||
name="JSONProcessor",
|
||||
description="An agent that processes JSON data",
|
||||
tools=[
|
||||
read_json, write_json, merge_json,
|
||||
validate_json, analyze_json, transform_json
|
||||
]
|
||||
)
|
||||
```
|
||||
|
||||
## Dependencies
|
||||
|
||||
The JSON tools require the following Python packages:
|
||||
- jsonschema: For JSON schema validation
|
||||
|
||||
These will be automatically installed when needed.
|
||||
|
||||
## Error Handling
|
||||
|
||||
All functions include comprehensive error handling:
|
||||
- File I/O errors
|
||||
- JSON parsing errors
|
||||
- Schema validation errors
|
||||
- Transformation errors
|
||||
|
||||
Errors are handled consistently:
|
||||
- File operations return bool for success/failure
|
||||
- Data operations return error details in result
|
||||
- All errors are logged for debugging
|
||||
|
||||
## Common Use Cases
|
||||
|
||||
1. Configuration Management:
|
||||
```python
|
||||
# Merge multiple config files
|
||||
success = merge_json(
|
||||
["base_config.json", "env_config.json", "user_config.json"],
|
||||
"final_config.json",
|
||||
merge_arrays=True,
|
||||
overwrite_duplicates=True
|
||||
)
|
||||
|
||||
# Validate configuration
|
||||
schema = {
|
||||
"type": "object",
|
||||
"required": ["database", "api"],
|
||||
"properties": {
|
||||
"database": {
|
||||
"type": "object",
|
||||
"required": ["host", "port"]
|
||||
},
|
||||
"api": {
|
||||
"type": "object",
|
||||
"required": ["key"]
|
||||
}
|
||||
}
|
||||
}
|
||||
is_valid, error = validate_json("final_config.json", schema)
|
||||
```
|
||||
|
||||
2. Data Analysis:
|
||||
```python
|
||||
# Analyze data structure
|
||||
analysis = analyze_json("large_dataset.json", max_depth=3)
|
||||
print(f"Dataset size: {analysis['structure']['size']} entries")
|
||||
print(f"Available fields: {analysis['structure']['keys']}")
|
||||
```
|
||||
|
||||
3. Data Transformation:
|
||||
```python
|
||||
# Transform data format
|
||||
transformations = [
|
||||
{"operation": "rename", "path": "firstName", "value": "first_name"},
|
||||
{"operation": "rename", "path": "lastName", "value": "last_name"},
|
||||
{"operation": "move", "path": "address.zip", "value": "address.postal_code"},
|
||||
{"operation": "delete", "path": "temporary_data"}
|
||||
]
|
||||
result = transform_json("user_data.json", transformations)
|
||||
write_json(result, "transformed_data.json")
|
||||
```
|
||||
|
||||
## Understanding JSON Tools
|
||||
|
||||
<Card title="What are JSON Tools?" icon="question">
|
||||
JSON Tools provide JSON processing capabilities for AI agents:
|
||||
- File reading and writing
|
||||
- Data validation
|
||||
- Schema validation
|
||||
- Data transformation
|
||||
- Structure analysis
|
||||
</Card>
|
||||
|
||||
## Key Components
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="JSON Agent" icon="user-robot">
|
||||
Create specialized JSON agents:
|
||||
```python
|
||||
Agent(tools=[read_json, write_json, merge_json, validate_json, analyze_json, transform_json])
|
||||
```
|
||||
</Card>
|
||||
<Card title="JSON Task" icon="list-check">
|
||||
Define JSON tasks:
|
||||
```python
|
||||
Task(description="json_operation")
|
||||
```
|
||||
</Card>
|
||||
<Card title="Process Types" icon="arrows-split-up-and-left">
|
||||
Sequential or parallel processing:
|
||||
```python
|
||||
process="sequential"
|
||||
```
|
||||
</Card>
|
||||
<Card title="JSON Options" icon="sliders">
|
||||
Customize JSON operations:
|
||||
```python
|
||||
indent=2, sort_keys=True
|
||||
```
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
## Examples
|
||||
|
||||
### Basic JSON Processing Agent
|
||||
|
||||
```python
|
||||
from praisonaiagents import Agent, Task, PraisonAIAgents
|
||||
from praisonaiagents.tools import read_json, write_json, validate_json
|
||||
|
||||
# Create JSON processing agent
|
||||
json_agent = Agent(
|
||||
name="JSONExpert",
|
||||
role="JSON Processor",
|
||||
goal="Process and validate JSON data efficiently.",
|
||||
backstory="Expert in JSON processing and validation.",
|
||||
tools=[read_json, write_json, validate_json],
|
||||
self_reflect=False
|
||||
)
|
||||
|
||||
# Define JSON task
|
||||
json_task = Task(
|
||||
description="Process and validate configuration files.",
|
||||
expected_output="Validated JSON configuration.",
|
||||
agent=json_agent,
|
||||
name="config_validation"
|
||||
)
|
||||
|
||||
# Run agent
|
||||
agents = PraisonAIAgents(
|
||||
agents=[json_agent],
|
||||
tasks=[json_task],
|
||||
process="sequential"
|
||||
)
|
||||
agents.start()
|
||||
```
|
||||
|
||||
### Advanced JSON Operations with Multiple Agents
|
||||
|
||||
```python
|
||||
# Create JSON validation agent
|
||||
validation_agent = Agent(
|
||||
name="Validator",
|
||||
role="JSON Validation Specialist",
|
||||
goal="Ensure JSON data integrity and schema compliance.",
|
||||
tools=[validate_json, analyze_json],
|
||||
self_reflect=False
|
||||
)
|
||||
|
||||
# Create JSON transformation agent
|
||||
transform_agent = Agent(
|
||||
name="Transformer",
|
||||
role="JSON Transformation Specialist",
|
||||
goal="Transform and merge JSON data structures.",
|
||||
tools=[transform_json, merge_json],
|
||||
self_reflect=False
|
||||
)
|
||||
|
||||
# Define tasks
|
||||
validation_task = Task(
|
||||
description="Validate JSON data",
|
||||
agent=validation_agent,
|
||||
name="json_validation"
|
||||
)
|
||||
|
||||
transform_task = Task(
|
||||
description="Transform JSON data",
|
||||
agent=transform_agent,
|
||||
name="json_transformation"
|
||||
)
|
||||
|
||||
# Run agents
|
||||
agents = PraisonAIAgents(
|
||||
agents=[validation_agent, transform_agent],
|
||||
tasks=[validation_task, transform_task],
|
||||
process="sequential"
|
||||
)
|
||||
agents.start()
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="Agent Configuration">
|
||||
Configure agents with clear JSON focus:
|
||||
```python
|
||||
Agent(
|
||||
name="JSONProcessor",
|
||||
role="JSON Processing Specialist",
|
||||
goal="Process JSON files accurately and safely",
|
||||
tools=[read_json, write_json, merge_json, validate_json, analyze_json, transform_json]
|
||||
)
|
||||
```
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Task Definition">
|
||||
Define specific JSON operations:
|
||||
```python
|
||||
Task(
|
||||
description="Parse and validate API response data",
|
||||
expected_output="Validated data structure"
|
||||
)
|
||||
```
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
## Common Patterns
|
||||
|
||||
### JSON Processing Pipeline
|
||||
```python
|
||||
# Processing agent
|
||||
processor = Agent(
|
||||
name="Processor",
|
||||
role="JSON Processor",
|
||||
tools=[read_json, write_json, merge_json, validate_json, analyze_json, transform_json]
|
||||
)
|
||||
|
||||
# Validation agent
|
||||
validator = Agent(
|
||||
name="Validator",
|
||||
role="Data Validator"
|
||||
)
|
||||
|
||||
# Define tasks
|
||||
process_task = Task(
|
||||
description="Process JSON files",
|
||||
agent=processor
|
||||
)
|
||||
|
||||
validate_task = Task(
|
||||
description="Validate processed data",
|
||||
agent=validator
|
||||
)
|
||||
|
||||
# Run workflow
|
||||
agents = PraisonAIAgents(
|
||||
agents=[processor, validator],
|
||||
tasks=[process_task, validate_task]
|
||||
)
|
||||
@@ -0,0 +1,464 @@
|
||||
---
|
||||
title: "Newspaper Agent"
|
||||
description: "News article extraction tools for AI agents."
|
||||
icon: "newspaper"
|
||||
---
|
||||
|
||||
<Note>
|
||||
**Prerequisites**
|
||||
- Python 3.10 or higher
|
||||
- PraisonAI Agents package installed
|
||||
- `newspaper3k` package installed
|
||||
</Note>
|
||||
|
||||
## Newspaper Tools
|
||||
|
||||
Use Newspaper Tools to extract and analyze news articles with AI agents.
|
||||
|
||||
<Steps>
|
||||
<Step title="Install Dependencies">
|
||||
First, install the required packages:
|
||||
```bash
|
||||
pip install praisonaiagents newspaper3k
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Import Components">
|
||||
Import the necessary components:
|
||||
```python
|
||||
from praisonaiagents import Agent, Task, PraisonAIAgents
|
||||
from praisonaiagents.tools import get_article, get_news_sources, get_articles_from_source, get_trending_topics
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Create Agent">
|
||||
Create a news agent:
|
||||
```python
|
||||
news_agent = Agent(
|
||||
name="NewsAgent",
|
||||
role="News Analyst",
|
||||
goal="Collect and analyze news articles from various sources.",
|
||||
backstory="Expert in news gathering and content analysis.",
|
||||
tools=[get_article, get_news_sources, get_articles_from_source, get_trending_topics],
|
||||
self_reflect=False
|
||||
)
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Define Task">
|
||||
Define the news task:
|
||||
```python
|
||||
news_task = Task(
|
||||
description="Analyze news articles about 'AI developments' from major tech news sources.",
|
||||
expected_output="Summary of key AI developments with source articles.",
|
||||
agent=news_agent,
|
||||
name="ai_news"
|
||||
)
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Run Agent">
|
||||
Initialize and run the agent:
|
||||
```python
|
||||
agents = PraisonAIAgents(
|
||||
agents=[news_agent],
|
||||
tasks=[news_task],
|
||||
process="sequential"
|
||||
)
|
||||
agents.start()
|
||||
```
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
## Understanding Newspaper Tools
|
||||
|
||||
<Card title="What are Newspaper Tools?" icon="question">
|
||||
Newspaper Tools provide news article processing capabilities for AI agents:
|
||||
- Article extraction
|
||||
- Source management
|
||||
- Content analysis
|
||||
- Trend detection
|
||||
- Multi-language support
|
||||
</Card>
|
||||
|
||||
## Key Components
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="News Agent" icon="user-robot">
|
||||
Create specialized news agents:
|
||||
```python
|
||||
Agent(tools=[get_article, get_news_sources, get_articles_from_source, get_trending_topics])
|
||||
```
|
||||
</Card>
|
||||
<Card title="News Task" icon="list-check">
|
||||
Define news tasks:
|
||||
```python
|
||||
Task(description="news_query")
|
||||
```
|
||||
</Card>
|
||||
<Card title="Process Types" icon="arrows-split-up-and-left">
|
||||
Sequential or parallel processing:
|
||||
```python
|
||||
process="sequential"
|
||||
```
|
||||
</Card>
|
||||
<Card title="Article Options" icon="sliders">
|
||||
Customize article retrieval:
|
||||
```python
|
||||
language="en", limit=10
|
||||
```
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
## Available Functions
|
||||
|
||||
```python
|
||||
from praisonaiagents.tools import get_article
|
||||
from praisonaiagents.tools import get_news_sources
|
||||
from praisonaiagents.tools import get_articles_from_source
|
||||
from praisonaiagents.tools import get_trending_topics
|
||||
```
|
||||
|
||||
## Function Details
|
||||
|
||||
### get_article(url: str, language: str = 'en')
|
||||
|
||||
Extracts and parses news articles:
|
||||
- Full text extraction
|
||||
- Author detection
|
||||
- Date parsing
|
||||
- Image extraction
|
||||
- NLP processing
|
||||
|
||||
```python
|
||||
# Basic usage
|
||||
article = get_article("https://example.com/article")
|
||||
|
||||
# With language specification
|
||||
article = get_article(
|
||||
"https://lemonde.fr/article",
|
||||
language="fr"
|
||||
)
|
||||
|
||||
# Returns: Dict[str, Any]
|
||||
# Example output:
|
||||
# {
|
||||
# "url": "https://example.com/article",
|
||||
# "title": "Breaking News Story",
|
||||
# "text": "Full article text...",
|
||||
# "authors": ["John Doe", "Jane Smith"],
|
||||
# "publish_date": "2025-01-07T05:31:38",
|
||||
# "top_image": "https://example.com/image.jpg",
|
||||
# "images": ["https://example.com/image1.jpg", ...],
|
||||
# "movies": ["https://example.com/video1.mp4", ...],
|
||||
# "source_domain": "example.com",
|
||||
# "keywords": ["technology", "ai", ...],
|
||||
# "summary": "Article summary..."
|
||||
# }
|
||||
```
|
||||
|
||||
### get_news_sources(category: Optional[str] = None, language: str = 'en', country: Optional[str] = None)
|
||||
|
||||
Gets news sources by category:
|
||||
- Category filtering
|
||||
- Language support
|
||||
- Country filtering
|
||||
- Domain information
|
||||
|
||||
```python
|
||||
# Get all sources
|
||||
sources = get_news_sources()
|
||||
|
||||
# Get technology news sources
|
||||
tech_sources = get_news_sources(
|
||||
category="technology",
|
||||
language="en",
|
||||
country="us"
|
||||
)
|
||||
|
||||
# Returns: List[Dict[str, str]]
|
||||
# Example output:
|
||||
# [
|
||||
# {
|
||||
# "url": "https://techcrunch.com",
|
||||
# "domain": "techcrunch.com",
|
||||
# "name": "TechCrunch",
|
||||
# "category": "technology"
|
||||
# },
|
||||
# ...
|
||||
# ]
|
||||
```
|
||||
|
||||
### get_articles_from_source(source_url: str, limit: int = 10, language: str = 'en')
|
||||
|
||||
Gets recent articles from a source:
|
||||
- Configurable limit
|
||||
- Language support
|
||||
- Full article parsing
|
||||
- Error handling
|
||||
|
||||
```python
|
||||
# Get latest articles
|
||||
articles = get_articles_from_source(
|
||||
"https://techcrunch.com",
|
||||
limit=5
|
||||
)
|
||||
|
||||
# Get articles in specific language
|
||||
articles = get_articles_from_source(
|
||||
"https://lemonde.fr",
|
||||
limit=10,
|
||||
language="fr"
|
||||
)
|
||||
|
||||
# Returns: List[Dict[str, Any]]
|
||||
# Each article has the same structure as get_article()
|
||||
```
|
||||
|
||||
### get_trending_topics(sources: Optional[List[str]] = None, limit: int = 10, language: str = 'en')
|
||||
|
||||
Analyzes trending topics:
|
||||
- Cross-source analysis
|
||||
- Keyword extraction
|
||||
- Customizable sources
|
||||
- Topic ranking
|
||||
|
||||
```python
|
||||
# Get trending topics from default sources
|
||||
topics = get_trending_topics(limit=5)
|
||||
|
||||
# Get topics from specific sources
|
||||
topics = get_trending_topics(
|
||||
sources=[
|
||||
"https://techcrunch.com",
|
||||
"https://wired.com"
|
||||
],
|
||||
limit=10,
|
||||
language="en"
|
||||
)
|
||||
|
||||
# Returns: List[str]
|
||||
# Example: ["artificial intelligence", "climate change", ...]
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
### Basic News Agent
|
||||
|
||||
```python
|
||||
from praisonaiagents import Agent, Task, PraisonAIAgents
|
||||
from praisonaiagents.tools import get_article, get_news_sources, get_articles_from_source, get_trending_topics
|
||||
|
||||
# Create news agent
|
||||
news_agent = Agent(
|
||||
name="NewsExpert",
|
||||
role="News Analyst",
|
||||
goal="Gather and analyze news content efficiently.",
|
||||
backstory="Expert in news analysis and content curation.",
|
||||
tools=[get_article, get_news_sources, get_articles_from_source, get_trending_topics],
|
||||
self_reflect=False
|
||||
)
|
||||
|
||||
# Define news task
|
||||
news_task = Task(
|
||||
description="Analyze tech news trends.",
|
||||
expected_output="Tech news analysis report.",
|
||||
agent=news_agent,
|
||||
name="tech_news_analysis"
|
||||
)
|
||||
|
||||
# Run agent
|
||||
agents = PraisonAIAgents(
|
||||
agents=[news_agent],
|
||||
tasks=[news_task],
|
||||
process="sequential"
|
||||
)
|
||||
agents.start()
|
||||
```
|
||||
|
||||
### Advanced News Analysis with Multiple Agents
|
||||
|
||||
```python
|
||||
# Create news collection agent
|
||||
collector_agent = Agent(
|
||||
name="Collector",
|
||||
role="News Collector",
|
||||
goal="Gather comprehensive news coverage.",
|
||||
tools=[get_article, get_news_sources, get_articles_from_source, get_trending_topics],
|
||||
self_reflect=False
|
||||
)
|
||||
|
||||
# Create analysis agent
|
||||
analysis_agent = Agent(
|
||||
name="Analyzer",
|
||||
role="Content Analyst",
|
||||
goal="Analyze news content and identify trends.",
|
||||
backstory="Expert in news analysis and trend identification.",
|
||||
self_reflect=False
|
||||
)
|
||||
|
||||
# Define tasks
|
||||
collection_task = Task(
|
||||
description="Collect news articles about renewable energy developments.",
|
||||
agent=collector_agent,
|
||||
name="energy_news"
|
||||
)
|
||||
|
||||
analysis_task = Task(
|
||||
description="Analyze the articles and identify key trends and breakthroughs.",
|
||||
agent=analysis_agent,
|
||||
name="news_analysis"
|
||||
)
|
||||
|
||||
# Run agents
|
||||
agents = PraisonAIAgents(
|
||||
agents=[collector_agent, analysis_agent],
|
||||
tasks=[collection_task, analysis_task],
|
||||
process="sequential"
|
||||
)
|
||||
agents.start()
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="Agent Configuration">
|
||||
Configure agents with clear news focus:
|
||||
```python
|
||||
Agent(
|
||||
name="NewsAnalyst",
|
||||
role="News Specialist",
|
||||
goal="Analyze news content effectively",
|
||||
tools=[get_article, get_news_sources, get_articles_from_source, get_trending_topics]
|
||||
)
|
||||
```
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Task Definition">
|
||||
Define specific news objectives:
|
||||
```python
|
||||
Task(
|
||||
description="Analyze tech news from major sources for AI developments",
|
||||
expected_output="Trend analysis with key findings"
|
||||
)
|
||||
```
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
## Common Patterns
|
||||
|
||||
### News Monitoring
|
||||
```python
|
||||
# News monitor agent
|
||||
monitor = Agent(
|
||||
name="Monitor",
|
||||
role="News Monitor",
|
||||
tools=[get_article, get_news_sources, get_articles_from_source, get_trending_topics]
|
||||
)
|
||||
|
||||
# Analysis agent
|
||||
analyst = Agent(
|
||||
name="Analyst",
|
||||
role="News Analyst"
|
||||
)
|
||||
|
||||
# Define tasks
|
||||
monitor_task = Task(
|
||||
description="Monitor tech news sources",
|
||||
agent=monitor
|
||||
)
|
||||
|
||||
analysis_task = Task(
|
||||
description="Analyze news trends",
|
||||
agent=analyst
|
||||
)
|
||||
|
||||
# Run workflow
|
||||
agents = PraisonAIAgents(
|
||||
agents=[monitor, analyst],
|
||||
tasks=[monitor_task, analysis_task]
|
||||
)
|
||||
|
||||
```
|
||||
|
||||
## Example Agent Configuration
|
||||
|
||||
```python
|
||||
from praisonaiagents import Agent
|
||||
from praisonaiagents.tools import (
|
||||
get_article, get_news_sources,
|
||||
get_articles_from_source, get_trending_topics
|
||||
)
|
||||
|
||||
agent = Agent(
|
||||
name="NewsAnalyzer",
|
||||
description="An agent that analyzes news articles",
|
||||
tools=[
|
||||
get_article, get_news_sources,
|
||||
get_articles_from_source, get_trending_topics
|
||||
]
|
||||
)
|
||||
```
|
||||
|
||||
## Dependencies
|
||||
|
||||
The newspaper tools require the following Python packages:
|
||||
- newspaper3k: For article extraction and parsing
|
||||
- nltk: For NLP processing (automatically installed with newspaper3k)
|
||||
|
||||
These will be automatically installed when needed.
|
||||
|
||||
## Error Handling
|
||||
|
||||
All functions include comprehensive error handling:
|
||||
- Network errors
|
||||
- Parsing errors
|
||||
- Language errors
|
||||
- Source availability errors
|
||||
|
||||
Errors are handled consistently:
|
||||
- Success cases return the expected data type
|
||||
- Error cases return a dict with an "error" key
|
||||
- All errors are logged for debugging
|
||||
|
||||
## Common Use Cases
|
||||
|
||||
1. News Monitoring:
|
||||
```python
|
||||
# Monitor tech news
|
||||
sources = get_news_sources(category="technology")
|
||||
for source in sources:
|
||||
articles = get_articles_from_source(
|
||||
source["url"],
|
||||
limit=5
|
||||
)
|
||||
for article in articles:
|
||||
if "ai" in article.get("keywords", []):
|
||||
print(f"AI article found: {article['title']}")
|
||||
```
|
||||
|
||||
2. Trend Analysis:
|
||||
```python
|
||||
# Analyze trending topics
|
||||
topics = get_trending_topics(limit=10)
|
||||
print("Current hot topics:")
|
||||
for i, topic in enumerate(topics, 1):
|
||||
print(f"{i}. {topic}")
|
||||
```
|
||||
|
||||
3. Content Aggregation:
|
||||
```python
|
||||
# Aggregate news from multiple sources
|
||||
def aggregate_news(categories):
|
||||
all_articles = []
|
||||
for category in categories:
|
||||
sources = get_news_sources(category=category)
|
||||
for source in sources[:3]: # Top 3 sources per category
|
||||
articles = get_articles_from_source(
|
||||
source["url"],
|
||||
limit=3
|
||||
)
|
||||
all_articles.extend(articles)
|
||||
return all_articles
|
||||
|
||||
news = aggregate_news(["technology", "business", "science"])
|
||||
@@ -0,0 +1,584 @@
|
||||
---
|
||||
title: "Pandas Agent"
|
||||
description: "Pandas data manipulation tools for AI agents."
|
||||
icon: "table"
|
||||
---
|
||||
|
||||
<Note>
|
||||
**Prerequisites**
|
||||
- Python 3.10 or higher
|
||||
- PraisonAI Agents package installed
|
||||
- `pandas` package installed
|
||||
</Note>
|
||||
|
||||
## Pandas Tools
|
||||
|
||||
Use Pandas Tools to manipulate and analyze data with AI agents.
|
||||
|
||||
<Steps>
|
||||
<Step title="Install Dependencies">
|
||||
First, install the required packages:
|
||||
```bash
|
||||
pip install praisonaiagents pandas
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Import Components">
|
||||
Import the necessary components:
|
||||
```python
|
||||
from praisonaiagents import Agent, Task, PraisonAIAgents
|
||||
from praisonaiagents.tools import read_csv, read_excel, write_csv, write_excel, filter_data, get_summary, group_by, pivot_table
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Create Agent">
|
||||
Create a data analysis agent:
|
||||
```python
|
||||
data_agent = Agent(
|
||||
name="DataAnalyst",
|
||||
role="Data Analysis Specialist",
|
||||
goal="Analyze and transform data efficiently.",
|
||||
backstory="Expert in data manipulation and statistical analysis.",
|
||||
tools=[read_csv, read_excel, write_csv, write_excel, filter_data, get_summary, group_by, pivot_table],
|
||||
self_reflect=False
|
||||
)
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Define Task">
|
||||
Define the analysis task:
|
||||
```python
|
||||
analysis_task = Task(
|
||||
description="Analyze sales data to identify trends and patterns.",
|
||||
expected_output="Statistical summary and key insights.",
|
||||
agent=data_agent,
|
||||
name="sales_analysis"
|
||||
)
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Run Agent">
|
||||
Initialize and run the agent:
|
||||
```python
|
||||
agents = PraisonAIAgents(
|
||||
agents=[data_agent],
|
||||
tasks=[analysis_task],
|
||||
process="sequential"
|
||||
)
|
||||
agents.start()
|
||||
```
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
## Understanding Pandas Tools
|
||||
|
||||
<Card title="What are Pandas Tools?" icon="question">
|
||||
Pandas Tools provide data analysis capabilities for AI agents:
|
||||
- Data filtering and selection
|
||||
- Statistical analysis
|
||||
- Data transformation
|
||||
- Group operations
|
||||
- Pivot table creation
|
||||
</Card>
|
||||
|
||||
## Key Components
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Data Agent" icon="user-robot">
|
||||
Create specialized data agents:
|
||||
```python
|
||||
Agent(tools=[read_csv, read_excel, write_csv, write_excel, filter_data, get_summary, group_by, pivot_table])
|
||||
```
|
||||
</Card>
|
||||
<Card title="Analysis Task" icon="list-check">
|
||||
Define analysis tasks:
|
||||
```python
|
||||
Task(description="analysis_query")
|
||||
```
|
||||
</Card>
|
||||
<Card title="Process Types" icon="arrows-split-up-and-left">
|
||||
Sequential or parallel processing:
|
||||
```python
|
||||
process="sequential"
|
||||
```
|
||||
</Card>
|
||||
<Card title="Analysis Options" icon="sliders">
|
||||
Customize analysis parameters:
|
||||
```python
|
||||
group_by="category", agg_func="mean"
|
||||
```
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
## Available Functions
|
||||
|
||||
```python
|
||||
from praisonaiagents.tools import read_csv
|
||||
from praisonaiagents.tools import read_excel
|
||||
from praisonaiagents.tools import write_csv
|
||||
from praisonaiagents.tools import write_excel
|
||||
from praisonaiagents.tools import filter_data
|
||||
from praisonaiagents.tools import get_summary
|
||||
from praisonaiagents.tools import group_by
|
||||
from praisonaiagents.tools import pivot_table
|
||||
```
|
||||
|
||||
## Function Details
|
||||
|
||||
### read_csv(filepath: str, **kwargs)
|
||||
|
||||
Reads CSV files into pandas DataFrames:
|
||||
- Flexible data import
|
||||
- Error handling
|
||||
- Additional pandas options
|
||||
|
||||
```python
|
||||
# Basic usage
|
||||
df = read_csv("data.csv")
|
||||
|
||||
# With additional options
|
||||
df = read_csv(
|
||||
"data.csv",
|
||||
encoding="utf-8",
|
||||
sep=",",
|
||||
header=0,
|
||||
usecols=["name", "age", "salary"]
|
||||
)
|
||||
|
||||
# Returns: pd.DataFrame
|
||||
# Error case: Returns dict with 'error' key
|
||||
```
|
||||
|
||||
### read_excel(filepath: str, **kwargs)
|
||||
|
||||
Reads Excel files into pandas DataFrames:
|
||||
- Multiple sheet support
|
||||
- Error handling
|
||||
- Additional pandas options
|
||||
|
||||
```python
|
||||
# Basic usage
|
||||
df = read_excel("data.xlsx")
|
||||
|
||||
# With sheet specification
|
||||
df = read_excel(
|
||||
"data.xlsx",
|
||||
sheet_name="Sheet1",
|
||||
header=0,
|
||||
usecols="A:D"
|
||||
)
|
||||
|
||||
# Returns: pd.DataFrame
|
||||
# Error case: Returns dict with 'error' key
|
||||
```
|
||||
|
||||
### write_csv(df: pd.DataFrame, filepath: str, **kwargs)
|
||||
|
||||
Writes DataFrames to CSV files:
|
||||
- Directory creation
|
||||
- Error handling
|
||||
- Formatting options
|
||||
|
||||
```python
|
||||
# Basic usage
|
||||
success = write_csv(df, "output.csv")
|
||||
|
||||
# With formatting options
|
||||
success = write_csv(
|
||||
df,
|
||||
"output.csv",
|
||||
index=False,
|
||||
encoding="utf-8",
|
||||
sep=",",
|
||||
date_format="%Y-%m-%d"
|
||||
)
|
||||
# Returns: bool (True if successful)
|
||||
```
|
||||
|
||||
### write_excel(df: pd.DataFrame, filepath: str, **kwargs)
|
||||
|
||||
Writes DataFrames to Excel files:
|
||||
- Directory creation
|
||||
- Error handling
|
||||
- Excel-specific options
|
||||
|
||||
```python
|
||||
# Basic usage
|
||||
success = write_excel(df, "output.xlsx")
|
||||
|
||||
# With formatting options
|
||||
success = write_excel(
|
||||
df,
|
||||
"output.xlsx",
|
||||
sheet_name="Data",
|
||||
index=False,
|
||||
freeze_panes=(1,0)
|
||||
)
|
||||
# Returns: bool (True if successful)
|
||||
```
|
||||
|
||||
### filter_data(df: pd.DataFrame, query: str)
|
||||
|
||||
Filters DataFrames using query strings:
|
||||
- SQL-like syntax
|
||||
- Complex conditions
|
||||
- Efficient filtering
|
||||
|
||||
```python
|
||||
# Basic filtering
|
||||
filtered_df = filter_data(df, "age > 25")
|
||||
|
||||
# Complex conditions
|
||||
filtered_df = filter_data(
|
||||
df,
|
||||
"age > 25 and salary >= 50000 and city == 'New York'"
|
||||
)
|
||||
|
||||
# Returns: pd.DataFrame
|
||||
# Error case: Returns dict with 'error' key
|
||||
```
|
||||
|
||||
### get_summary(df: pd.DataFrame)
|
||||
|
||||
Generates comprehensive data summaries:
|
||||
- Basic statistics
|
||||
- Data types
|
||||
- Memory usage
|
||||
- Null counts
|
||||
|
||||
```python
|
||||
# Get data summary
|
||||
summary = get_summary(df)
|
||||
|
||||
# Returns: Dict[str, Any]
|
||||
# Example output:
|
||||
# {
|
||||
# "shape": [1000, 5],
|
||||
# "columns": ["name", "age", "salary", "city"],
|
||||
# "dtypes": {
|
||||
# "name": "object",
|
||||
# "age": "int64",
|
||||
# "salary": "float64",
|
||||
# "city": "object"
|
||||
# },
|
||||
# "null_counts": {
|
||||
# "name": 0,
|
||||
# "age": 2,
|
||||
# "salary": 1,
|
||||
# "city": 0
|
||||
# },
|
||||
# "numeric_summary": {
|
||||
# "age": {
|
||||
# "count": 998,
|
||||
# "mean": 35.5,
|
||||
# "std": 12.3,
|
||||
# "min": 18,
|
||||
# "25%": 28,
|
||||
# "50%": 35,
|
||||
# "75%": 45,
|
||||
# "max": 65
|
||||
# },
|
||||
# ...
|
||||
# },
|
||||
# "memory_usage": 40960
|
||||
# }
|
||||
```
|
||||
|
||||
### group_by(df: pd.DataFrame, columns: Union[str, List[str]], agg_dict: Dict[str, Union[str, List[str]]])
|
||||
|
||||
Groups and aggregates data:
|
||||
- Multiple grouping columns
|
||||
- Multiple aggregations
|
||||
- Custom functions
|
||||
|
||||
```python
|
||||
# Basic grouping
|
||||
grouped_df = group_by(
|
||||
df,
|
||||
columns="city",
|
||||
agg_dict={"salary": "mean"}
|
||||
)
|
||||
|
||||
# Complex grouping
|
||||
grouped_df = group_by(
|
||||
df,
|
||||
columns=["city", "department"],
|
||||
agg_dict={
|
||||
"salary": ["mean", "sum", "count"],
|
||||
"age": ["min", "max", "mean"]
|
||||
}
|
||||
)
|
||||
|
||||
# Returns: pd.DataFrame
|
||||
# Error case: Returns dict with 'error' key
|
||||
```
|
||||
|
||||
### pivot_table(df: pd.DataFrame, index: Union[str, List[str]], columns: Optional[Union[str, List[str]]] = None, values: Optional[Union[str, List[str]]] = None, aggfunc: str = "mean")
|
||||
|
||||
Creates pivot tables:
|
||||
- Multiple index levels
|
||||
- Column pivoting
|
||||
- Custom aggregations
|
||||
- Flexible reshaping
|
||||
|
||||
```python
|
||||
# Basic pivot
|
||||
pivot_df = pivot_table(
|
||||
df,
|
||||
index="city",
|
||||
columns="department",
|
||||
values="salary"
|
||||
)
|
||||
|
||||
# Complex pivot
|
||||
pivot_df = pivot_table(
|
||||
df,
|
||||
index=["city", "department"],
|
||||
columns="year",
|
||||
values=["salary", "headcount"],
|
||||
aggfunc={
|
||||
"salary": "mean",
|
||||
"headcount": "sum"
|
||||
}
|
||||
)
|
||||
|
||||
# Returns: pd.DataFrame
|
||||
# Error case: Returns dict with 'error' key
|
||||
```
|
||||
|
||||
## Example Agent Configuration
|
||||
|
||||
```python
|
||||
from praisonaiagents import Agent
|
||||
from praisonaiagents.tools import (
|
||||
read_csv, read_excel, write_csv, write_excel,
|
||||
filter_data, get_summary, group_by, pivot_table
|
||||
)
|
||||
|
||||
agent = Agent(
|
||||
name="DataAnalyzer",
|
||||
description="An agent that analyzes data using pandas",
|
||||
tools=[
|
||||
read_csv, read_excel, write_csv, write_excel,
|
||||
filter_data, get_summary, group_by, pivot_table
|
||||
]
|
||||
)
|
||||
```
|
||||
|
||||
## Dependencies
|
||||
|
||||
The pandas tools require the following Python packages:
|
||||
- pandas: For data manipulation and analysis
|
||||
- numpy: For numerical operations (automatically installed with pandas)
|
||||
- openpyxl: For Excel file support (optional)
|
||||
|
||||
These will be automatically installed when needed.
|
||||
|
||||
## Error Handling
|
||||
|
||||
All functions include comprehensive error handling:
|
||||
- File I/O errors
|
||||
- Data format errors
|
||||
- Query syntax errors
|
||||
- Memory errors
|
||||
|
||||
Errors are handled consistently:
|
||||
- File operations return bool for success/failure
|
||||
- Data operations return error details in result
|
||||
- All errors are logged for debugging
|
||||
|
||||
## Common Use Cases
|
||||
|
||||
1. Data Analysis:
|
||||
```python
|
||||
# Load and analyze sales data
|
||||
df = read_csv("sales_data.csv")
|
||||
summary = get_summary(df)
|
||||
print(f"Total records: {summary['shape'][0]}")
|
||||
print(f"Missing values: {summary['null_counts']}")
|
||||
|
||||
# Filter high-value transactions
|
||||
high_value = filter_data(df, "amount > 10000")
|
||||
write_excel(high_value, "high_value_sales.xlsx")
|
||||
```
|
||||
|
||||
2. Sales Reporting:
|
||||
```python
|
||||
# Create sales summary by region and product
|
||||
sales_summary = group_by(
|
||||
df,
|
||||
columns=["region", "product"],
|
||||
agg_dict={
|
||||
"amount": ["sum", "mean", "count"],
|
||||
"profit": ["sum", "mean"]
|
||||
}
|
||||
)
|
||||
|
||||
# Create pivot table for quarterly analysis
|
||||
quarterly_sales = pivot_table(
|
||||
df,
|
||||
index="product",
|
||||
columns="quarter",
|
||||
values="amount",
|
||||
aggfunc="sum"
|
||||
)
|
||||
```
|
||||
|
||||
3. Data Transformation:
|
||||
```python
|
||||
# Load and clean customer data
|
||||
customers = read_excel("customers.xlsx")
|
||||
filtered = filter_data(
|
||||
customers,
|
||||
"age >= 18 and status == 'active'"
|
||||
)
|
||||
|
||||
# Group by demographics
|
||||
demographics = group_by(
|
||||
filtered,
|
||||
columns=["age_group", "region"],
|
||||
agg_dict={
|
||||
"spending": ["mean", "sum"],
|
||||
"visits": "count"
|
||||
}
|
||||
)
|
||||
write_csv(demographics, "demographic_analysis.csv")
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
### Basic Data Analysis Agent
|
||||
|
||||
```python
|
||||
from praisonaiagents import Agent, Task, PraisonAIAgents
|
||||
from praisonaiagents.tools import read_csv, filter_data, get_summary, group_by
|
||||
|
||||
# Create data analysis agent
|
||||
data_agent = Agent(
|
||||
name="DataExpert",
|
||||
role="Data Analyst",
|
||||
goal="Process and analyze data efficiently.",
|
||||
backstory="Expert in data analysis and statistical methods.",
|
||||
tools=[read_csv, filter_data, get_summary, group_by],
|
||||
self_reflect=False
|
||||
)
|
||||
|
||||
# Define analysis task
|
||||
analysis_task = Task(
|
||||
description="Analyze sales performance data.",
|
||||
expected_output="Sales analysis report.",
|
||||
agent=data_agent,
|
||||
name="sales_analysis"
|
||||
)
|
||||
|
||||
# Run agent
|
||||
agents = PraisonAIAgents(
|
||||
agents=[data_agent],
|
||||
tasks=[analysis_task],
|
||||
process="sequential"
|
||||
)
|
||||
agents.start()
|
||||
```
|
||||
|
||||
### Advanced Data Operations with Multiple Agents
|
||||
|
||||
```python
|
||||
# Create data import/export agent
|
||||
io_agent = Agent(
|
||||
name="DataIO",
|
||||
role="Data IO Specialist",
|
||||
goal="Handle data import and export operations.",
|
||||
tools=[read_csv, read_excel, write_csv, write_excel],
|
||||
self_reflect=False
|
||||
)
|
||||
|
||||
# Create analysis agent
|
||||
analysis_agent = Agent(
|
||||
name="Analyzer",
|
||||
role="Data Analysis Specialist",
|
||||
goal="Perform complex data analysis.",
|
||||
tools=[filter_data, get_summary, group_by, pivot_table],
|
||||
self_reflect=False
|
||||
)
|
||||
|
||||
# Define tasks
|
||||
io_task = Task(
|
||||
description="Import and export data",
|
||||
agent=io_agent,
|
||||
name="data_io"
|
||||
)
|
||||
|
||||
analysis_task = Task(
|
||||
description="Analyze data",
|
||||
agent=analysis_agent,
|
||||
name="data_analysis"
|
||||
)
|
||||
|
||||
# Run agents
|
||||
agents = PraisonAIAgents(
|
||||
agents=[io_agent, analysis_agent],
|
||||
tasks=[io_task, analysis_task],
|
||||
process="sequential"
|
||||
)
|
||||
agents.start()
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="Agent Configuration">
|
||||
Configure agents with clear analysis focus:
|
||||
```python
|
||||
Agent(
|
||||
name="DataScientist",
|
||||
role="Data Analysis Specialist",
|
||||
goal="Extract meaningful insights from data",
|
||||
tools=[read_csv, read_excel, write_csv, write_excel, filter_data, get_summary, group_by, pivot_table]
|
||||
)
|
||||
```
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Task Definition">
|
||||
Define specific analysis objectives:
|
||||
```python
|
||||
Task(
|
||||
description="Analyze sales trends and forecast future growth",
|
||||
expected_output="Growth analysis with forecasts"
|
||||
)
|
||||
```
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
## Common Patterns
|
||||
|
||||
### Data Analysis Pipeline
|
||||
```python
|
||||
# Data preparation agent
|
||||
prep_agent = Agent(
|
||||
name="Preparer",
|
||||
role="Data Preparation",
|
||||
tools=[read_csv, read_excel, write_csv, write_excel, filter_data, get_summary, group_by, pivot_table]
|
||||
)
|
||||
|
||||
# Analysis agent
|
||||
analyst = Agent(
|
||||
name="Analyst",
|
||||
role="Data Analyst"
|
||||
)
|
||||
|
||||
# Define tasks
|
||||
prep_task = Task(
|
||||
description="Clean and prepare data",
|
||||
agent=prep_agent
|
||||
)
|
||||
|
||||
analysis_task = Task(
|
||||
description="Analyze prepared data",
|
||||
agent=analyst
|
||||
)
|
||||
|
||||
# Run workflow
|
||||
agents = PraisonAIAgents(
|
||||
agents=[prep_agent, analyst],
|
||||
tasks=[prep_task, analysis_task]
|
||||
)
|
||||
@@ -0,0 +1,528 @@
|
||||
---
|
||||
title: "Python Agent"
|
||||
description: "Python code execution tools for AI agents."
|
||||
icon: "code"
|
||||
---
|
||||
|
||||
<Note>
|
||||
**Prerequisites**
|
||||
- Python 3.10 or higher
|
||||
- PraisonAI Agents package installed
|
||||
- Basic understanding of Python programming
|
||||
</Note>
|
||||
|
||||
## Python Tools
|
||||
|
||||
Use Python Tools to execute and manage Python code with AI agents.
|
||||
|
||||
<Steps>
|
||||
<Step title="Install Dependencies">
|
||||
First, install the required package:
|
||||
```bash
|
||||
pip install praisonaiagents
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Import Components">
|
||||
Import the necessary components:
|
||||
```python
|
||||
from praisonaiagents import Agent, Task, PraisonAIAgents
|
||||
from praisonaiagents.tools import (
|
||||
execute_code, analyze_code, format_code,
|
||||
lint_code, disassemble_code
|
||||
)
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Create Agent">
|
||||
Create a Python execution agent:
|
||||
```python
|
||||
python_agent = Agent(
|
||||
name="PythonExecutor",
|
||||
role="Python Code Specialist",
|
||||
goal="Execute Python code efficiently and safely.",
|
||||
backstory="Expert in Python programming and code execution.",
|
||||
tools=[
|
||||
execute_code, analyze_code, format_code,
|
||||
lint_code, disassemble_code
|
||||
],
|
||||
self_reflect=False
|
||||
)
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Define Task">
|
||||
Define the Python execution task:
|
||||
```python
|
||||
python_task = Task(
|
||||
description="Execute and manage Python code.",
|
||||
expected_output="Code execution results.",
|
||||
agent=python_agent,
|
||||
name="code_execution"
|
||||
)
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Run Agent">
|
||||
Initialize and run the agent:
|
||||
```python
|
||||
agents = PraisonAIAgents(
|
||||
agents=[python_agent],
|
||||
tasks=[python_task],
|
||||
process="sequential"
|
||||
)
|
||||
agents.start()
|
||||
```
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
## Available Functions
|
||||
|
||||
```python
|
||||
from praisonaiagents.tools import execute_code
|
||||
from praisonaiagents.tools import analyze_code
|
||||
from praisonaiagents.tools import format_code
|
||||
from praisonaiagents.tools import lint_code
|
||||
from praisonaiagents.tools import disassemble_code
|
||||
```
|
||||
|
||||
## Function Details
|
||||
|
||||
### execute_code(code: str, globals_dict: Optional[Dict[str, Any]] = None, locals_dict: Optional[Dict[str, Any]] = None, timeout: int = 30, max_output_size: int = 10000)
|
||||
|
||||
Safely executes Python code:
|
||||
- Isolated execution environment
|
||||
- Output capture
|
||||
- Error handling
|
||||
- Timeout protection
|
||||
- Output size limits
|
||||
|
||||
```python
|
||||
# Basic execution
|
||||
result = execute_code("print('Hello, World!')")
|
||||
|
||||
# With custom environment
|
||||
result = execute_code(
|
||||
"""
|
||||
x = 10
|
||||
y = 20
|
||||
print(f'Sum: {x + y}')
|
||||
""",
|
||||
globals_dict={'__builtins__': __builtins__},
|
||||
timeout=5
|
||||
)
|
||||
|
||||
# Returns: Dict[str, Any]
|
||||
# Example output:
|
||||
# {
|
||||
# 'result': None,
|
||||
# 'stdout': 'Hello, World!\n',
|
||||
# 'stderr': '',
|
||||
# 'success': True
|
||||
# }
|
||||
```
|
||||
|
||||
### analyze_code(code: str)
|
||||
|
||||
Analyzes Python code structure:
|
||||
- Import statements
|
||||
- Function definitions
|
||||
- Class definitions
|
||||
- Variable usage
|
||||
- Code complexity
|
||||
|
||||
```python
|
||||
# Analyze code structure
|
||||
analysis = analyze_code("""
|
||||
def greet(name):
|
||||
return f"Hello, {name}!"
|
||||
|
||||
class Person:
|
||||
def __init__(self, name):
|
||||
self.name = name
|
||||
""")
|
||||
|
||||
# Returns: Dict[str, Any]
|
||||
# Example output:
|
||||
# {
|
||||
# 'imports': [],
|
||||
# 'functions': [
|
||||
# {
|
||||
# 'name': 'greet',
|
||||
# 'args': ['name'],
|
||||
# 'decorators': []
|
||||
# }
|
||||
# ],
|
||||
# 'classes': [
|
||||
# {
|
||||
# 'name': 'Person',
|
||||
# 'bases': [],
|
||||
# 'decorators': []
|
||||
# }
|
||||
# ],
|
||||
# 'variables': ['name'],
|
||||
# 'complexity': {
|
||||
# 'lines': 6,
|
||||
# 'functions': 2,
|
||||
# 'classes': 1,
|
||||
# 'branches': 0
|
||||
# }
|
||||
# }
|
||||
```
|
||||
|
||||
### format_code(code: str, style: str = 'black', line_length: int = 88)
|
||||
|
||||
Formats Python code:
|
||||
- Multiple style options
|
||||
- Line length control
|
||||
- PEP 8 compliance
|
||||
- Consistent formatting
|
||||
|
||||
```python
|
||||
# Format with black
|
||||
formatted = format_code("""
|
||||
def messy_function(x,y, z):
|
||||
if x>0:
|
||||
return y+z
|
||||
else:
|
||||
return y-z
|
||||
""")
|
||||
|
||||
# Format with PEP 8
|
||||
formatted = format_code(
|
||||
"""
|
||||
def messy_function(x,y, z):
|
||||
if x>0:
|
||||
return y+z
|
||||
else:
|
||||
return y-z
|
||||
""",
|
||||
style='pep8',
|
||||
line_length=79
|
||||
)
|
||||
|
||||
# Returns: str
|
||||
# Example output:
|
||||
# def messy_function(x, y, z):
|
||||
# if x > 0:
|
||||
# return y + z
|
||||
# else:
|
||||
# return y - z
|
||||
```
|
||||
|
||||
### lint_code(code: str)
|
||||
|
||||
Lints Python code for issues:
|
||||
- Code quality checks
|
||||
- Style violations
|
||||
- Potential bugs
|
||||
- Best practices
|
||||
|
||||
```python
|
||||
# Lint code for issues
|
||||
results = lint_code("""
|
||||
def bad_function():
|
||||
unused_var = 42
|
||||
return 'result'
|
||||
""")
|
||||
|
||||
# Returns: Dict[str, List[Dict[str, Any]]]
|
||||
# Example output:
|
||||
# {
|
||||
# 'errors': [],
|
||||
# 'warnings': [
|
||||
# {
|
||||
# 'type': 'warning',
|
||||
# 'module': 'bad_function',
|
||||
# 'obj': 'unused_var',
|
||||
# 'line': 2,
|
||||
# 'column': 4,
|
||||
# 'path': '<string>',
|
||||
# 'symbol': 'unused-variable',
|
||||
# 'message': 'Unused variable "unused_var"',
|
||||
# 'message-id': 'W0612'
|
||||
# }
|
||||
# ],
|
||||
# 'conventions': []
|
||||
# }
|
||||
```
|
||||
|
||||
### disassemble_code(code: str)
|
||||
|
||||
Disassembles Python code to bytecode:
|
||||
- Bytecode inspection
|
||||
- Performance analysis
|
||||
- Code optimization
|
||||
- Debugging support
|
||||
|
||||
```python
|
||||
# Disassemble code to bytecode
|
||||
bytecode = disassemble_code("""
|
||||
def add(a, b):
|
||||
return a + b
|
||||
""")
|
||||
|
||||
# Returns: str
|
||||
# Example output:
|
||||
# 1 0 LOAD_CONST 0 (<code object add at ...>)
|
||||
# 2 LOAD_CONST 1 ('add')
|
||||
# 4 MAKE_FUNCTION 0
|
||||
# 6 STORE_NAME 0 (add)
|
||||
# 8 LOAD_CONST 2 (None)
|
||||
# 10 RETURN_VALUE
|
||||
```
|
||||
|
||||
## Example Agent Configuration
|
||||
|
||||
```python
|
||||
from praisonaiagents import Agent
|
||||
from praisonaiagents.tools import (
|
||||
execute_code, analyze_code, format_code,
|
||||
lint_code, disassemble_code
|
||||
)
|
||||
|
||||
agent = Agent(
|
||||
name="PythonDeveloper",
|
||||
description="An agent that helps with Python development",
|
||||
tools=[
|
||||
execute_code, analyze_code, format_code,
|
||||
lint_code, disassemble_code
|
||||
]
|
||||
)
|
||||
```
|
||||
|
||||
## Dependencies
|
||||
|
||||
The Python tools require the following packages:
|
||||
- black: For code formatting (black style)
|
||||
- autopep8: For code formatting (PEP 8 style)
|
||||
- pylint: For code linting
|
||||
|
||||
These will be automatically installed when needed.
|
||||
|
||||
## Error Handling
|
||||
|
||||
All functions include comprehensive error handling:
|
||||
- Code execution errors
|
||||
- Syntax errors
|
||||
- Import errors
|
||||
- Timeout errors
|
||||
- Memory errors
|
||||
|
||||
Errors are handled consistently:
|
||||
- Success cases return expected data type
|
||||
- Error cases return None or error details
|
||||
- All errors are logged for debugging
|
||||
|
||||
## Common Use Cases
|
||||
|
||||
1. Code Testing:
|
||||
```python
|
||||
# Test code execution
|
||||
test_code = """
|
||||
def factorial(n):
|
||||
return 1 if n <= 1 else n * factorial(n - 1)
|
||||
|
||||
result = factorial(5)
|
||||
print(f"Factorial: {result}")
|
||||
"""
|
||||
result = execute_code(test_code)
|
||||
print(f"Output: {result['stdout']}")
|
||||
```
|
||||
|
||||
2. Code Quality:
|
||||
```python
|
||||
# Check code quality
|
||||
code = """
|
||||
def process_data(data):
|
||||
processed = []
|
||||
for item in data:
|
||||
if item > 0:
|
||||
processed.append(item * 2)
|
||||
return processed
|
||||
"""
|
||||
analysis = analyze_code(code)
|
||||
lint_results = lint_code(code)
|
||||
formatted = format_code(code)
|
||||
```
|
||||
|
||||
3. Code Analysis:
|
||||
```python
|
||||
# Analyze code structure
|
||||
code = """
|
||||
class DataProcessor:
|
||||
def __init__(self, data):
|
||||
self.data = data
|
||||
|
||||
def process(self):
|
||||
return [x * 2 for x in self.data]
|
||||
"""
|
||||
structure = analyze_code(code)
|
||||
bytecode = disassemble_code(code)
|
||||
print(f"Classes: {structure['classes']}")
|
||||
print(f"Functions: {structure['functions']}")
|
||||
```
|
||||
|
||||
## Understanding Python Tools
|
||||
|
||||
<Card title="What are Python Tools?" icon="question">
|
||||
Python Tools provide code execution capabilities for AI agents:
|
||||
- Code execution
|
||||
- Module management
|
||||
- Error handling
|
||||
- Output capture
|
||||
- Environment control
|
||||
</Card>
|
||||
|
||||
## Examples
|
||||
|
||||
### Basic Python Execution Agent
|
||||
|
||||
```python
|
||||
from praisonaiagents import Agent, Task, PraisonAIAgents
|
||||
from praisonaiagents.tools import (
|
||||
execute_code, analyze_code, format_code,
|
||||
lint_code, disassemble_code
|
||||
)
|
||||
|
||||
# Create Python agent
|
||||
python_agent = Agent(
|
||||
name="PythonExpert",
|
||||
role="Code Execution Specialist",
|
||||
goal="Execute Python code efficiently and safely.",
|
||||
backstory="Expert in Python programming and execution.",
|
||||
tools=[
|
||||
execute_code, analyze_code, format_code,
|
||||
lint_code, disassemble_code
|
||||
],
|
||||
self_reflect=False
|
||||
)
|
||||
|
||||
# Define Python task
|
||||
python_task = Task(
|
||||
description="Execute data processing scripts.",
|
||||
expected_output="Processing results.",
|
||||
agent=python_agent,
|
||||
name="data_processing"
|
||||
)
|
||||
|
||||
# Run agent
|
||||
agents = PraisonAIAgents(
|
||||
agents=[python_agent],
|
||||
tasks=[python_task],
|
||||
process="sequential"
|
||||
)
|
||||
agents.start()
|
||||
```
|
||||
|
||||
### Advanced Python Operations with Multiple Agents
|
||||
|
||||
```python
|
||||
# Create execution agent
|
||||
executor_agent = Agent(
|
||||
name="CodeExecutor",
|
||||
role="Code Execution Specialist",
|
||||
goal="Execute Python code efficiently.",
|
||||
tools=[
|
||||
execute_code, analyze_code, format_code,
|
||||
lint_code, disassemble_code
|
||||
],
|
||||
self_reflect=False
|
||||
)
|
||||
|
||||
# Create monitoring agent
|
||||
monitor_agent = Agent(
|
||||
name="CodeMonitor",
|
||||
role="Execution Monitor",
|
||||
goal="Monitor code execution and handle errors.",
|
||||
backstory="Expert in code monitoring and error handling.",
|
||||
self_reflect=False
|
||||
)
|
||||
|
||||
# Define tasks
|
||||
execution_task = Task(
|
||||
description="Execute Python scripts.",
|
||||
agent=executor_agent,
|
||||
name="code_execution"
|
||||
)
|
||||
|
||||
monitoring_task = Task(
|
||||
description="Monitor execution and handle errors.",
|
||||
agent=monitor_agent,
|
||||
name="execution_monitoring"
|
||||
)
|
||||
|
||||
# Run agents
|
||||
agents = PraisonAIAgents(
|
||||
agents=[executor_agent, monitor_agent],
|
||||
tasks=[execution_task, monitoring_task],
|
||||
process="sequential"
|
||||
)
|
||||
agents.start()
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="Agent Configuration">
|
||||
Configure agents with clear Python focus:
|
||||
```python
|
||||
Agent(
|
||||
name="PythonExecutor",
|
||||
role="Code Execution Specialist",
|
||||
goal="Execute code safely and efficiently",
|
||||
tools=[
|
||||
execute_code, analyze_code, format_code,
|
||||
lint_code, disassemble_code
|
||||
]
|
||||
)
|
||||
```
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Task Definition">
|
||||
Define specific Python operations:
|
||||
```python
|
||||
Task(
|
||||
description="Execute data processing scripts",
|
||||
expected_output="Processing results"
|
||||
)
|
||||
```
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
## Common Patterns
|
||||
|
||||
### Python Execution Pipeline
|
||||
```python
|
||||
# Execution agent
|
||||
executor = Agent(
|
||||
name="Executor",
|
||||
role="Code Executor",
|
||||
tools=[
|
||||
execute_code, analyze_code, format_code,
|
||||
lint_code, disassemble_code
|
||||
]
|
||||
)
|
||||
|
||||
# Monitor agent
|
||||
monitor = Agent(
|
||||
name="Monitor",
|
||||
role="Execution Monitor"
|
||||
)
|
||||
|
||||
# Define tasks
|
||||
execute_task = Task(
|
||||
description="Execute Python code",
|
||||
agent=executor
|
||||
)
|
||||
|
||||
monitor_task = Task(
|
||||
description="Monitor execution",
|
||||
agent=monitor
|
||||
)
|
||||
|
||||
# Run workflow
|
||||
agents = PraisonAIAgents(
|
||||
agents=[executor, monitor],
|
||||
tasks=[execute_task, monitor_task]
|
||||
)
|
||||
@@ -0,0 +1,488 @@
|
||||
---
|
||||
title: "Shell Agent"
|
||||
description: "Shell command execution tools for AI agents."
|
||||
icon: "terminal"
|
||||
---
|
||||
|
||||
<Note>
|
||||
**Prerequisites**
|
||||
- Python 3.10 or higher
|
||||
- PraisonAI Agents package installed
|
||||
- Basic understanding of shell commands
|
||||
</Note>
|
||||
|
||||
## Shell Tools
|
||||
|
||||
Use Shell Tools to execute shell commands with AI agents.
|
||||
|
||||
<Steps>
|
||||
<Step title="Install Dependencies">
|
||||
First, install the required package:
|
||||
```bash
|
||||
pip install praisonaiagents
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Import Components">
|
||||
Import the necessary components:
|
||||
```python
|
||||
from praisonaiagents import Agent, Task, PraisonAIAgents
|
||||
from praisonaiagents.tools import execute_command, list_processes, kill_process, get_system_info
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Create Agent">
|
||||
Create a shell command agent:
|
||||
```python
|
||||
shell_agent = Agent(
|
||||
name="ShellCommander",
|
||||
role="Shell Command Specialist",
|
||||
goal="Execute shell commands efficiently and safely.",
|
||||
backstory="Expert in command-line operations and automation.",
|
||||
tools=[execute_command, list_processes, kill_process, get_system_info],
|
||||
self_reflect=False
|
||||
)
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Define Task">
|
||||
Define the shell task:
|
||||
```python
|
||||
shell_task = Task(
|
||||
description="List and organize files in the current directory.",
|
||||
expected_output="Organized file structure with detailed listing.",
|
||||
agent=shell_agent,
|
||||
name="file_organization"
|
||||
)
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Run Agent">
|
||||
Initialize and run the agent:
|
||||
```python
|
||||
agents = PraisonAIAgents(
|
||||
agents=[shell_agent],
|
||||
tasks=[shell_task],
|
||||
process="sequential"
|
||||
)
|
||||
agents.start()
|
||||
```
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
## Understanding Shell Tools
|
||||
|
||||
<Card title="What are Shell Tools?" icon="question">
|
||||
Shell Tools provide command-line capabilities for AI agents:
|
||||
- Command execution
|
||||
- Process management
|
||||
- Output handling
|
||||
- Error handling
|
||||
- Environment management
|
||||
</Card>
|
||||
|
||||
## Key Components
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Shell Agent" icon="user-robot">
|
||||
Create specialized shell agents:
|
||||
```python
|
||||
Agent(tools=[execute_command, list_processes, kill_process, get_system_info])
|
||||
```
|
||||
</Card>
|
||||
<Card title="Shell Task" icon="list-check">
|
||||
Define shell tasks:
|
||||
```python
|
||||
Task(description="shell_operation")
|
||||
```
|
||||
</Card>
|
||||
<Card title="Process Types" icon="arrows-split-up-and-left">
|
||||
Sequential or parallel processing:
|
||||
```python
|
||||
process="sequential"
|
||||
```
|
||||
</Card>
|
||||
<Card title="Shell Options" icon="sliders">
|
||||
Customize shell operations:
|
||||
```python
|
||||
timeout=30, shell=True
|
||||
```
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
```python
|
||||
from praisonaiagents import Agent, Task, PraisonAIAgents
|
||||
from praisonaiagents.tools import execute_command, list_processes, kill_process, get_system_info
|
||||
|
||||
# Create shell agent
|
||||
shell_agent = Agent(
|
||||
name="CommandExecutor",
|
||||
role="Shell Command Specialist",
|
||||
goal="Execute shell commands efficiently and safely.",
|
||||
backstory="Expert in command-line operations and scripting.",
|
||||
tools=[execute_command, list_processes, kill_process, get_system_info],
|
||||
self_reflect=False
|
||||
)
|
||||
|
||||
# Define shell task
|
||||
shell_task = Task(
|
||||
description="Clean up temporary files and organize downloads.",
|
||||
expected_output="Cleaned and organized file system.",
|
||||
agent=shell_agent,
|
||||
name="system_cleanup"
|
||||
)
|
||||
|
||||
# Run agent
|
||||
agents = PraisonAIAgents(
|
||||
agents=[shell_agent],
|
||||
tasks=[shell_task],
|
||||
process="sequential"
|
||||
)
|
||||
agents.start()
|
||||
```
|
||||
|
||||
### Advanced Shell Management with Multiple Agents
|
||||
|
||||
```python
|
||||
# Create command agent
|
||||
command_agent = Agent(
|
||||
name="Commander",
|
||||
role="Command Executor",
|
||||
goal="Execute shell commands systematically.",
|
||||
tools=[execute_command, list_processes, kill_process, get_system_info],
|
||||
self_reflect=False
|
||||
)
|
||||
|
||||
# Create monitoring agent
|
||||
monitor_agent = Agent(
|
||||
name="Monitor",
|
||||
role="Process Monitor",
|
||||
goal="Monitor and manage running processes.",
|
||||
backstory="Expert in system monitoring and process control.",
|
||||
self_reflect=False
|
||||
)
|
||||
|
||||
# Define tasks
|
||||
command_task = Task(
|
||||
description="Execute system maintenance commands.",
|
||||
agent=command_agent,
|
||||
name="system_maintenance"
|
||||
)
|
||||
|
||||
monitor_task = Task(
|
||||
description="Monitor system resources and processes.",
|
||||
agent=monitor_agent,
|
||||
name="process_monitoring"
|
||||
)
|
||||
|
||||
# Run agents
|
||||
agents = PraisonAIAgents(
|
||||
agents=[command_agent, monitor_agent],
|
||||
tasks=[command_task, monitor_task],
|
||||
process="sequential"
|
||||
)
|
||||
agents.start()
|
||||
```
|
||||
|
||||
## Available Functions
|
||||
|
||||
```python
|
||||
from praisonaiagents.tools import execute_command
|
||||
from praisonaiagents.tools import list_processes
|
||||
from praisonaiagents.tools import kill_process
|
||||
from praisonaiagents.tools import get_system_info
|
||||
```
|
||||
|
||||
## Function Details
|
||||
|
||||
### execute_command(command: str, cwd: Optional[str] = None, timeout: int = 30, shell: bool = False, env: Optional[Dict[str, str]] = None, max_output_size: int = 10000)
|
||||
|
||||
Safely executes shell commands:
|
||||
- Timeout protection
|
||||
- Output capture
|
||||
- Error handling
|
||||
- Environment control
|
||||
- Working directory control
|
||||
|
||||
```python
|
||||
# Basic command execution
|
||||
result = execute_command("ls -la")
|
||||
|
||||
# Advanced execution
|
||||
result = execute_command(
|
||||
"python script.py",
|
||||
cwd="/path/to/scripts",
|
||||
timeout=60,
|
||||
env={"PYTHONPATH": "/custom/path"},
|
||||
shell=True
|
||||
)
|
||||
|
||||
# Returns: Dict[str, Union[str, int, bool]]
|
||||
# Example output:
|
||||
# {
|
||||
# 'stdout': 'command output...',
|
||||
# 'stderr': 'error output if any',
|
||||
# 'exit_code': 0,
|
||||
# 'success': True,
|
||||
# 'execution_time': 0.123
|
||||
# }
|
||||
```
|
||||
|
||||
### list_processes()
|
||||
|
||||
Lists running system processes:
|
||||
- Process details
|
||||
- Resource usage
|
||||
- User information
|
||||
- Performance metrics
|
||||
|
||||
```python
|
||||
# Get list of running processes
|
||||
processes = list_processes()
|
||||
|
||||
# Sort by CPU usage
|
||||
cpu_intensive = sorted(
|
||||
processes,
|
||||
key=lambda x: x['cpu_percent'],
|
||||
reverse=True
|
||||
)[:5]
|
||||
|
||||
# Returns: List[Dict[str, Union[int, str, float]]]
|
||||
# Example output:
|
||||
# [
|
||||
# {
|
||||
# 'pid': 1234,
|
||||
# 'name': 'python',
|
||||
# 'username': 'user',
|
||||
# 'memory_percent': 2.5,
|
||||
# 'cpu_percent': 15.3
|
||||
# },
|
||||
# ...
|
||||
# ]
|
||||
```
|
||||
|
||||
### kill_process(pid: int, force: bool = False)
|
||||
|
||||
Terminates system processes:
|
||||
- Graceful termination
|
||||
- Force kill option
|
||||
- Error handling
|
||||
- Access control
|
||||
|
||||
```python
|
||||
# Graceful termination
|
||||
result = kill_process(1234)
|
||||
|
||||
# Force kill
|
||||
result = kill_process(
|
||||
pid=1234,
|
||||
force=True # Use SIGKILL
|
||||
)
|
||||
|
||||
# Returns: Dict[str, Union[bool, str]]
|
||||
# Example output:
|
||||
# {
|
||||
# 'success': True,
|
||||
# 'message': 'Process 1234 killed successfully'
|
||||
# }
|
||||
# or
|
||||
# {
|
||||
# 'success': False,
|
||||
# 'message': 'Access denied to kill process 1234'
|
||||
# }
|
||||
```
|
||||
|
||||
### get_system_info()
|
||||
|
||||
Retrieves system information:
|
||||
- CPU statistics
|
||||
- Memory usage
|
||||
- Disk space
|
||||
- Platform details
|
||||
- Boot time
|
||||
|
||||
```python
|
||||
# Get system information
|
||||
info = get_system_info()
|
||||
|
||||
# Access specific metrics
|
||||
print(f"CPU Usage: {info['cpu']['percent']}%")
|
||||
print(f"Memory Free: {info['memory']['free']} bytes")
|
||||
|
||||
# Returns: Dict[str, Union[float, int, str, Dict]]
|
||||
# Example output:
|
||||
# {
|
||||
# 'cpu': {
|
||||
# 'percent': 45.2,
|
||||
# 'cores': 8,
|
||||
# 'physical_cores': 4
|
||||
# },
|
||||
# 'memory': {
|
||||
# 'total': 16000000000,
|
||||
# 'available': 8000000000,
|
||||
# 'percent': 50.0,
|
||||
# 'used': 8000000000,
|
||||
# 'free': 4000000000
|
||||
# },
|
||||
# 'disk': {
|
||||
# 'total': 500000000000,
|
||||
# 'used': 250000000000,
|
||||
# 'free': 250000000000,
|
||||
# 'percent': 50.0
|
||||
# },
|
||||
# 'boot_time': 1641544800,
|
||||
# 'platform': 'Darwin'
|
||||
# }
|
||||
```
|
||||
|
||||
## Example Agent Configuration
|
||||
|
||||
```python
|
||||
from praisonaiagents import Agent
|
||||
from praisonaiagents.tools import (
|
||||
execute_command, list_processes,
|
||||
kill_process, get_system_info
|
||||
)
|
||||
|
||||
agent = Agent(
|
||||
name="SystemManager",
|
||||
description="An agent that manages system processes and executes commands",
|
||||
tools=[
|
||||
execute_command, list_processes,
|
||||
kill_process, get_system_info
|
||||
]
|
||||
)
|
||||
```
|
||||
|
||||
## Dependencies
|
||||
|
||||
The shell tools require the following package:
|
||||
- psutil: For system and process information
|
||||
|
||||
This will be automatically installed when needed.
|
||||
|
||||
## Error Handling
|
||||
|
||||
All functions include comprehensive error handling:
|
||||
- Command execution errors
|
||||
- Process access errors
|
||||
- Permission errors
|
||||
- Timeout errors
|
||||
- Resource errors
|
||||
|
||||
Errors are handled consistently:
|
||||
- Success cases return expected data type
|
||||
- Error cases return error details in result
|
||||
- All errors are logged for debugging
|
||||
|
||||
## Common Use Cases
|
||||
|
||||
1. System Monitoring:
|
||||
```python
|
||||
# Monitor system resources
|
||||
info = get_system_info()
|
||||
if info['cpu']['percent'] > 90:
|
||||
print("High CPU usage detected!")
|
||||
if info['memory']['percent'] > 80:
|
||||
print("Low memory warning!")
|
||||
|
||||
# List resource-intensive processes
|
||||
processes = sorted(
|
||||
list_processes(),
|
||||
key=lambda x: x['memory_percent'],
|
||||
reverse=True
|
||||
)[:5]
|
||||
print("Top memory users:", processes)
|
||||
```
|
||||
|
||||
2. Process Management:
|
||||
```python
|
||||
# Find and kill zombie processes
|
||||
for process in list_processes():
|
||||
if process['name'] == 'zombie_process':
|
||||
result = kill_process(
|
||||
process['pid'],
|
||||
force=True
|
||||
)
|
||||
print(f"Kill result: {result['message']}")
|
||||
```
|
||||
|
||||
3. Command Execution:
|
||||
```python
|
||||
# Run a series of maintenance commands
|
||||
commands = [
|
||||
"apt-get update",
|
||||
"apt-get upgrade -y",
|
||||
"apt-get autoremove -y"
|
||||
]
|
||||
for cmd in commands:
|
||||
result = execute_command(
|
||||
cmd,
|
||||
timeout=300,
|
||||
shell=True
|
||||
)
|
||||
if result['success']:
|
||||
print(f"Command succeeded: {cmd}")
|
||||
else:
|
||||
print(f"Command failed: {result['stderr']}")
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="Agent Configuration">
|
||||
Configure agents with clear shell focus:
|
||||
```python
|
||||
Agent(
|
||||
name="ShellManager",
|
||||
role="Command Line Specialist",
|
||||
goal="Execute shell commands safely and efficiently",
|
||||
tools=[execute_command, list_processes, kill_process, get_system_info]
|
||||
)
|
||||
```
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Task Definition">
|
||||
Define specific shell operations:
|
||||
```python
|
||||
Task(
|
||||
description="Clean up system temp files and optimize storage",
|
||||
expected_output="Optimized system storage"
|
||||
)
|
||||
```
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
## Common Patterns
|
||||
|
||||
### Shell Command Pipeline
|
||||
```python
|
||||
# Command agent
|
||||
commander = Agent(
|
||||
name="Commander",
|
||||
role="Shell Commander",
|
||||
tools=[execute_command]
|
||||
)
|
||||
|
||||
# Monitor agent
|
||||
monitor = Agent(
|
||||
name="Monitor",
|
||||
role="Process Monitor"
|
||||
)
|
||||
|
||||
# Define tasks
|
||||
command_task = Task(
|
||||
description="Execute maintenance commands",
|
||||
agent=commander
|
||||
)
|
||||
|
||||
monitor_task = Task(
|
||||
description="Monitor command execution",
|
||||
agent=monitor
|
||||
)
|
||||
|
||||
# Run workflow
|
||||
agents = PraisonAIAgents(
|
||||
agents=[commander, monitor],
|
||||
tasks=[command_task, monitor_task]
|
||||
)
|
||||
@@ -0,0 +1,251 @@
|
||||
---
|
||||
title: "Spider Agent"
|
||||
description: "Web scraping tools for AI agents."
|
||||
icon: "spider"
|
||||
---
|
||||
|
||||
<Note>
|
||||
**Prerequisites**
|
||||
- Python 3.10 or higher
|
||||
- PraisonAI Agents package installed
|
||||
- `scrapy` package installed
|
||||
</Note>
|
||||
|
||||
## Spider Tools
|
||||
|
||||
Use Spider Tools to crawl and scrape web content with AI agents.
|
||||
|
||||
<Steps>
|
||||
<Step title="Install Dependencies">
|
||||
First, install the required packages:
|
||||
```bash
|
||||
pip install praisonaiagents scrapy
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Import Components">
|
||||
Import the necessary components:
|
||||
```python
|
||||
from praisonaiagents import Agent, Task, PraisonAIAgents
|
||||
from praisonaiagents.tools import scrape_page, extract_links, crawl, extract_text
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Create Agent">
|
||||
Create a web scraping agent:
|
||||
```python
|
||||
spider_agent = Agent(
|
||||
name="WebSpider",
|
||||
role="Web Scraping Specialist",
|
||||
goal="Extract and analyze web content efficiently.",
|
||||
backstory="Expert in web scraping and content extraction.",
|
||||
tools=[scrape_page, extract_links, crawl, extract_text],
|
||||
self_reflect=False
|
||||
)
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Define Task">
|
||||
Define the scraping task:
|
||||
```python
|
||||
scraping_task = Task(
|
||||
description="Scrape product information from an e-commerce website.",
|
||||
expected_output="Structured product data with prices and descriptions.",
|
||||
agent=spider_agent,
|
||||
name="product_scraping"
|
||||
)
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Run Agent">
|
||||
Initialize and run the agent:
|
||||
```python
|
||||
agents = PraisonAIAgents(
|
||||
agents=[spider_agent],
|
||||
tasks=[scraping_task],
|
||||
process="sequential"
|
||||
)
|
||||
agents.start()
|
||||
```
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
## Understanding Spider Tools
|
||||
|
||||
<Card title="What are Spider Tools?" icon="question">
|
||||
Spider Tools provide web scraping capabilities for AI agents:
|
||||
- Page scraping and downloading
|
||||
- Content extraction and filtering
|
||||
- Link discovery and crawling
|
||||
- HTML parsing and cleaning
|
||||
- Data structuring and formatting
|
||||
</Card>
|
||||
|
||||
## Key Components
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Spider Agent" icon="user-robot">
|
||||
Create specialized scraping agents:
|
||||
```python
|
||||
Agent(tools=[scrape_page, extract_content, crawl_links, parse_html, structure_data])
|
||||
```
|
||||
</Card>
|
||||
<Card title="Spider Task" icon="list-check">
|
||||
Define scraping tasks:
|
||||
```python
|
||||
Task(description="scraping_query")
|
||||
```
|
||||
</Card>
|
||||
<Card title="Process Types" icon="arrows-split-up-and-left">
|
||||
Sequential or parallel processing:
|
||||
```python
|
||||
process="sequential"
|
||||
```
|
||||
</Card>
|
||||
<Card title="Scraping Options" icon="sliders">
|
||||
Customize scraping parameters:
|
||||
```python
|
||||
max_depth=2, delay=1
|
||||
```
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
## Examples
|
||||
|
||||
### Basic Web Scraping Agent
|
||||
|
||||
```python
|
||||
from praisonaiagents import Agent, Task, PraisonAIAgents
|
||||
from praisonaiagents.tools import scrape_page, extract_links, crawl, extract_text
|
||||
|
||||
# Create search agent
|
||||
agent = Agent(
|
||||
name="WebCrawler",
|
||||
role="Web Scraping Specialist",
|
||||
goal="Extract and analyze web content efficiently.",
|
||||
backstory="Expert in web scraping and content extraction.",
|
||||
tools=[scrape_page, extract_links, crawl, extract_text],
|
||||
self_reflect=False
|
||||
)
|
||||
|
||||
# Define task
|
||||
task = Task(
|
||||
description="Scrape and analyze the content from 'https://example.com'",
|
||||
expected_output="Extracted content with links and text analysis",
|
||||
agent=agent,
|
||||
name="web_scraping"
|
||||
)
|
||||
|
||||
# Run agent
|
||||
agents = PraisonAIAgents(
|
||||
agents=[agent],
|
||||
tasks=[task],
|
||||
process="sequential"
|
||||
)
|
||||
agents.start()
|
||||
```
|
||||
|
||||
### Advanced Scraping with Multiple Agents
|
||||
|
||||
```python
|
||||
# Create scraping agent
|
||||
scraper_agent = Agent(
|
||||
name="Scraper",
|
||||
role="Content Scraper",
|
||||
goal="Extract web content systematically.",
|
||||
tools=[scrape_page, crawl_links, parse_html],
|
||||
self_reflect=False
|
||||
)
|
||||
|
||||
# Create analysis agent
|
||||
analysis_agent = Agent(
|
||||
name="Analyzer",
|
||||
role="Content Analyst",
|
||||
goal="Analyze and structure scraped content.",
|
||||
backstory="Expert in data analysis and organization.",
|
||||
tools=[extract_content, structure_data],
|
||||
self_reflect=False
|
||||
)
|
||||
|
||||
# Define tasks
|
||||
scraping_task = Task(
|
||||
description="Scrape product data from multiple pages.",
|
||||
agent=scraper_agent,
|
||||
name="product_scraping"
|
||||
)
|
||||
|
||||
analysis_task = Task(
|
||||
description="Analyze and structure the scraped product data.",
|
||||
agent=analysis_agent,
|
||||
name="data_analysis"
|
||||
)
|
||||
|
||||
# Run agents
|
||||
agents = PraisonAIAgents(
|
||||
agents=[scraper_agent, analysis_agent],
|
||||
tasks=[scraping_task, analysis_task],
|
||||
process="sequential"
|
||||
)
|
||||
agents.start()
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="Agent Configuration">
|
||||
Configure agents with clear scraping focus:
|
||||
```python
|
||||
Agent(
|
||||
name="WebScraper",
|
||||
role="Content Extraction Specialist",
|
||||
goal="Extract web content ethically and efficiently",
|
||||
tools=[scrape_page, extract_content, crawl_links, parse_html, structure_data]
|
||||
)
|
||||
```
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Task Definition">
|
||||
Define specific scraping objectives:
|
||||
```python
|
||||
Task(
|
||||
description="Extract product prices and descriptions from e-commerce site",
|
||||
expected_output="Structured product database"
|
||||
)
|
||||
```
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
## Common Patterns
|
||||
|
||||
### Web Scraping Pipeline
|
||||
```python
|
||||
# Scraping agent
|
||||
scraper = Agent(
|
||||
name="Scraper",
|
||||
role="Web Scraper",
|
||||
tools=[scrape_page, crawl_links, parse_html]
|
||||
)
|
||||
|
||||
# Processing agent
|
||||
processor = Agent(
|
||||
name="Processor",
|
||||
role="Data Processor",
|
||||
tools=[extract_content, structure_data]
|
||||
)
|
||||
|
||||
# Define tasks
|
||||
scrape_task = Task(
|
||||
description="Scrape website content",
|
||||
agent=scraper
|
||||
)
|
||||
|
||||
process_task = Task(
|
||||
description="Process scraped content",
|
||||
agent=processor
|
||||
)
|
||||
|
||||
# Run workflow
|
||||
agents = PraisonAIAgents(
|
||||
agents=[scraper, processor],
|
||||
tasks=[scrape_task, process_task]
|
||||
)
|
||||
@@ -0,0 +1,253 @@
|
||||
---
|
||||
title: "Wikipedia Agent"
|
||||
description: "Wikipedia data retrieval tools for AI agents."
|
||||
icon: "book"
|
||||
---
|
||||
|
||||
<Note>
|
||||
**Prerequisites**
|
||||
- Python 3.10 or higher
|
||||
- PraisonAI Agents package installed
|
||||
- `wikipedia` package installed
|
||||
- Basic understanding of Wikipedia APIs
|
||||
</Note>
|
||||
|
||||
## Wikipedia Tools
|
||||
|
||||
Use Wikipedia Tools to retrieve and analyze Wikipedia content with AI agents.
|
||||
|
||||
<Steps>
|
||||
<Step title="Install Dependencies">
|
||||
First, install the required packages:
|
||||
```bash
|
||||
pip install praisonaiagents wikipedia
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Import Components">
|
||||
Import the necessary components:
|
||||
```python
|
||||
from praisonaiagents import Agent, Task, PraisonAIAgents
|
||||
from praisonaiagents.tools import wiki_search, wiki_summary, wiki_page, wiki_random, wiki_language
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Create Agent">
|
||||
Create a Wikipedia research agent:
|
||||
```python
|
||||
wiki_agent = Agent(
|
||||
name="WikiResearcher",
|
||||
role="Wikipedia Research Specialist",
|
||||
goal="Research and analyze Wikipedia content efficiently.",
|
||||
backstory="Expert in information retrieval and content analysis.",
|
||||
tools=[wiki_search, wiki_summary, wiki_page, wiki_random, wiki_language],
|
||||
self_reflect=False
|
||||
)
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Define Task">
|
||||
Define the research task:
|
||||
```python
|
||||
research_task = Task(
|
||||
description="Research historical events and gather information.",
|
||||
expected_output="Comprehensive research summary with citations.",
|
||||
agent=wiki_agent,
|
||||
name="historical_research"
|
||||
)
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Run Agent">
|
||||
Initialize and run the agent:
|
||||
```python
|
||||
agents = PraisonAIAgents(
|
||||
agents=[wiki_agent],
|
||||
tasks=[research_task],
|
||||
process="sequential"
|
||||
)
|
||||
agents.start()
|
||||
```
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
## Understanding Wikipedia Tools
|
||||
|
||||
<Card title="What are Wikipedia Tools?" icon="question">
|
||||
Wikipedia Tools provide research capabilities for AI agents:
|
||||
- Article search and retrieval
|
||||
- Content summary generation
|
||||
- Full page information access
|
||||
- Random article discovery
|
||||
- Multi-language support
|
||||
</Card>
|
||||
|
||||
## Key Components
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Wiki Agent" icon="user-robot">
|
||||
Create specialized research agents:
|
||||
```python
|
||||
Agent(tools=[wiki_search, wiki_summary, wiki_page, wiki_random, wiki_language])
|
||||
```
|
||||
</Card>
|
||||
<Card title="Wiki Task" icon="list-check">
|
||||
Define research tasks:
|
||||
```python
|
||||
Task(description="wiki_query")
|
||||
```
|
||||
</Card>
|
||||
<Card title="Process Types" icon="arrows-split-up-and-left">
|
||||
Sequential or parallel processing:
|
||||
```python
|
||||
process="sequential"
|
||||
```
|
||||
</Card>
|
||||
<Card title="Wiki Options" icon="sliders">
|
||||
Customize search parameters:
|
||||
```python
|
||||
language="en", sentences=3
|
||||
```
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
## Examples
|
||||
|
||||
### Basic Wikipedia Research Agent
|
||||
|
||||
```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="WikiExpert",
|
||||
role="Research Specialist",
|
||||
goal="Research topics efficiently and accurately.",
|
||||
backstory="Expert in information gathering and analysis.",
|
||||
tools=[wiki_search, wiki_summary, wiki_page, wiki_random, wiki_language],
|
||||
self_reflect=False
|
||||
)
|
||||
|
||||
# Define research task
|
||||
research_task = Task(
|
||||
description="Research scientific discoveries and breakthroughs.",
|
||||
expected_output="Detailed research report with references.",
|
||||
agent=wiki_agent,
|
||||
name="science_research"
|
||||
)
|
||||
|
||||
# Run agent
|
||||
agents = PraisonAIAgents(
|
||||
agents=[wiki_agent],
|
||||
tasks=[research_task],
|
||||
process="sequential"
|
||||
)
|
||||
agents.start()
|
||||
|
||||
```
|
||||
|
||||
### Advanced Research with Multiple Agents
|
||||
|
||||
```python
|
||||
# Create research agent
|
||||
researcher_agent = Agent(
|
||||
name="Researcher",
|
||||
role="Content Researcher",
|
||||
goal="Research topics systematically.",
|
||||
tools=[wiki_search, wiki_summary, wiki_page],
|
||||
self_reflect=False
|
||||
)
|
||||
|
||||
# Create analysis agent
|
||||
analysis_agent = Agent(
|
||||
name="Analyzer",
|
||||
role="Content Analyst",
|
||||
goal="Analyze and summarize research findings.",
|
||||
backstory="Expert in content analysis and synthesis.",
|
||||
tools=[wiki_summary, wiki_page],
|
||||
self_reflect=False
|
||||
)
|
||||
|
||||
# Define tasks
|
||||
research_task = Task(
|
||||
description="Research technological advancements.",
|
||||
agent=researcher_agent,
|
||||
name="tech_research"
|
||||
)
|
||||
|
||||
analysis_task = Task(
|
||||
description="Analyze and synthesize research findings.",
|
||||
agent=analysis_agent,
|
||||
name="content_analysis"
|
||||
)
|
||||
|
||||
# Run agents
|
||||
agents = PraisonAIAgents(
|
||||
agents=[researcher_agent, analysis_agent],
|
||||
tasks=[research_task, analysis_task],
|
||||
process="sequential"
|
||||
)
|
||||
agents.start()
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="Agent Configuration">
|
||||
Configure agents with clear research focus:
|
||||
```python
|
||||
Agent(
|
||||
name="WikiResearcher",
|
||||
role="Research Specialist",
|
||||
goal="Research topics accurately and efficiently",
|
||||
tools=[wiki_search, wiki_summary, wiki_page, wiki_random, wiki_language]
|
||||
)
|
||||
```
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Task Definition">
|
||||
Define specific research objectives:
|
||||
```python
|
||||
Task(
|
||||
description="Research historical events and gather sources",
|
||||
expected_output="Detailed research summary"
|
||||
)
|
||||
```
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
## Common Patterns
|
||||
|
||||
### Research Pipeline
|
||||
```python
|
||||
# Research agent
|
||||
researcher = Agent(
|
||||
name="Researcher",
|
||||
role="Wiki Researcher",
|
||||
tools=[wiki_search, wiki_summary, wiki_page]
|
||||
)
|
||||
|
||||
# Analysis agent
|
||||
analyzer = Agent(
|
||||
name="Analyzer",
|
||||
role="Content Analyzer",
|
||||
tools=[wiki_summary, wiki_page]
|
||||
)
|
||||
|
||||
# Define tasks
|
||||
research_task = Task(
|
||||
description="Research topic",
|
||||
agent=researcher
|
||||
)
|
||||
|
||||
analyze_task = Task(
|
||||
description="Analyze findings",
|
||||
agent=analyzer
|
||||
)
|
||||
|
||||
# Run workflow
|
||||
agents = PraisonAIAgents(
|
||||
agents=[researcher, analyzer],
|
||||
tasks=[research_task, analyze_task]
|
||||
)
|
||||
@@ -0,0 +1,251 @@
|
||||
---
|
||||
title: "XML Agent"
|
||||
description: "XML data processing tools for AI agents."
|
||||
icon: "code"
|
||||
---
|
||||
|
||||
<Note>
|
||||
**Prerequisites**
|
||||
- Python 3.10 or higher
|
||||
- PraisonAI Agents package installed
|
||||
- `lxml` package installed
|
||||
</Note>
|
||||
|
||||
## XML Tools
|
||||
|
||||
Use XML Tools to read, write, and manipulate XML data with AI agents.
|
||||
|
||||
<Steps>
|
||||
<Step title="Install Dependencies">
|
||||
First, install the required package:
|
||||
```bash
|
||||
pip install praisonaiagents
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Import Components">
|
||||
Import the necessary components:
|
||||
```python
|
||||
from praisonaiagents import Agent, Task, PraisonAIAgents
|
||||
from praisonaiagents.tools import read_xml, write_xml, transform_xml, validate_xml, xml_to_dict, dict_to_xml
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Create Agent">
|
||||
Create an XML processing agent:
|
||||
```python
|
||||
xml_agent = Agent(
|
||||
name="XMLProcessor",
|
||||
role="XML Processing Specialist",
|
||||
goal="Process XML files efficiently and accurately.",
|
||||
backstory="Expert in XML file manipulation and validation.",
|
||||
tools=[read_xml, write_xml, transform_xml, validate_xml, xml_to_dict, dict_to_xml],
|
||||
self_reflect=False
|
||||
)
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Define Task">
|
||||
Define the XML processing task:
|
||||
```python
|
||||
xml_task = Task(
|
||||
description="Parse and validate XML configuration files.",
|
||||
expected_output="Validated and processed XML data.",
|
||||
agent=xml_agent,
|
||||
name="xml_processing"
|
||||
)
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Run Agent">
|
||||
Initialize and run the agent:
|
||||
```python
|
||||
agents = PraisonAIAgents(
|
||||
agents=[xml_agent],
|
||||
tasks=[xml_task],
|
||||
process="sequential"
|
||||
)
|
||||
agents.start()
|
||||
```
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
## Understanding XML Tools
|
||||
|
||||
<Card title="What are XML Tools?" icon="question">
|
||||
XML Tools provide XML processing capabilities for AI agents:
|
||||
- XML parsing and reading
|
||||
- File writing and validation
|
||||
- Data transformation
|
||||
- Dictionary conversion
|
||||
- Structure manipulation
|
||||
</Card>
|
||||
|
||||
## Key Components
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="XML Agent" icon="user-robot">
|
||||
Create specialized XML agents:
|
||||
```python
|
||||
Agent(tools=[read_xml, write_xml, transform_xml, validate_xml, xml_to_dict, dict_to_xml])
|
||||
```
|
||||
</Card>
|
||||
<Card title="XML Task" icon="list-check">
|
||||
Define XML tasks:
|
||||
```python
|
||||
Task(description="xml_operation")
|
||||
```
|
||||
</Card>
|
||||
<Card title="Process Types" icon="arrows-split-up-and-left">
|
||||
Sequential or parallel processing:
|
||||
```python
|
||||
process="sequential"
|
||||
```
|
||||
</Card>
|
||||
<Card title="XML Options" icon="sliders">
|
||||
Customize XML parameters:
|
||||
```python
|
||||
encoding="utf-8", pretty_print=True
|
||||
```
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
## Examples
|
||||
|
||||
### Basic XML Processing Agent
|
||||
|
||||
```python
|
||||
from praisonaiagents import Agent, Task, PraisonAIAgents
|
||||
from praisonaiagents.tools import read_xml, write_xml, transform_xml, validate_xml, xml_to_dict, dict_to_xml
|
||||
|
||||
# Create XML agent
|
||||
xml_agent = Agent(
|
||||
name="XMLExpert",
|
||||
role="XML Processing Specialist",
|
||||
goal="Process XML files efficiently and accurately.",
|
||||
backstory="Expert in XML file handling and validation.",
|
||||
tools=[read_xml, write_xml, transform_xml, validate_xml, xml_to_dict, dict_to_xml],
|
||||
self_reflect=False
|
||||
)
|
||||
|
||||
# Define XML task
|
||||
xml_task = Task(
|
||||
description="Parse and validate XML configurations.",
|
||||
expected_output="Processed and validated XML data.",
|
||||
agent=xml_agent,
|
||||
name="config_processing"
|
||||
)
|
||||
|
||||
# Run agent
|
||||
agents = PraisonAIAgents(
|
||||
agents=[xml_agent],
|
||||
tasks=[xml_task],
|
||||
process="sequential"
|
||||
)
|
||||
agents.start()
|
||||
```
|
||||
|
||||
### Advanced XML Processing with Multiple Agents
|
||||
|
||||
```python
|
||||
# Create XML processing agent
|
||||
processor_agent = Agent(
|
||||
name="Processor",
|
||||
role="XML Processor",
|
||||
goal="Process XML files systematically.",
|
||||
tools=[read_xml, write_xml, transform_xml],
|
||||
self_reflect=False
|
||||
)
|
||||
|
||||
# Create validation agent
|
||||
validator_agent = Agent(
|
||||
name="Validator",
|
||||
role="Data Validator",
|
||||
goal="Validate XML structure and content.",
|
||||
backstory="Expert in data validation and verification.",
|
||||
tools=[validate_xml, xml_to_dict, dict_to_xml],
|
||||
self_reflect=False
|
||||
)
|
||||
|
||||
# Define tasks
|
||||
processing_task = Task(
|
||||
description="Process and transform XML configurations.",
|
||||
agent=processor_agent,
|
||||
name="xml_processing"
|
||||
)
|
||||
|
||||
validation_task = Task(
|
||||
description="Validate processed XML data.",
|
||||
agent=validator_agent,
|
||||
name="data_validation"
|
||||
)
|
||||
|
||||
# Run agents
|
||||
agents = PraisonAIAgents(
|
||||
agents=[processor_agent, validator_agent],
|
||||
tasks=[processing_task, validation_task],
|
||||
process="sequential"
|
||||
)
|
||||
agents.start()
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="Agent Configuration">
|
||||
Configure agents with clear XML focus:
|
||||
```python
|
||||
Agent(
|
||||
name="XMLProcessor",
|
||||
role="XML Processing Specialist",
|
||||
goal="Process XML files accurately and safely",
|
||||
tools=[read_xml, write_xml, transform_xml, validate_xml, xml_to_dict, dict_to_xml]
|
||||
)
|
||||
```
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Task Definition">
|
||||
Define specific XML operations:
|
||||
```python
|
||||
Task(
|
||||
description="Parse and validate XML configurations",
|
||||
expected_output="Validated data structure"
|
||||
)
|
||||
```
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
## Common Patterns
|
||||
|
||||
### XML Processing Pipeline
|
||||
```python
|
||||
# Processing agent
|
||||
processor = Agent(
|
||||
name="Processor",
|
||||
role="XML Processor",
|
||||
tools=[read_xml, write_xml, transform_xml]
|
||||
)
|
||||
|
||||
# Validation agent
|
||||
validator = Agent(
|
||||
name="Validator",
|
||||
role="Data Validator",
|
||||
tools=[validate_xml, xml_to_dict, dict_to_xml]
|
||||
)
|
||||
|
||||
# Define tasks
|
||||
process_task = Task(
|
||||
description="Process XML files",
|
||||
agent=processor
|
||||
)
|
||||
|
||||
validate_task = Task(
|
||||
description="Validate processed data",
|
||||
agent=validator
|
||||
)
|
||||
|
||||
# Run workflow
|
||||
agents = PraisonAIAgents(
|
||||
agents=[processor, validator],
|
||||
tasks=[process_task, validate_task]
|
||||
)
|
||||
@@ -0,0 +1,252 @@
|
||||
---
|
||||
title: "YAML Agent"
|
||||
description: "YAML data processing tools for AI agents."
|
||||
icon: "code"
|
||||
---
|
||||
|
||||
<Note>
|
||||
**Prerequisites**
|
||||
- Python 3.10 or higher
|
||||
- PraisonAI Agents package installed
|
||||
- `pyyaml` package installed
|
||||
- Basic understanding of YAML format
|
||||
</Note>
|
||||
|
||||
## YAML Tools
|
||||
|
||||
Use YAML Tools to process and manipulate YAML files with AI agents.
|
||||
|
||||
<Steps>
|
||||
<Step title="Install Dependencies">
|
||||
First, install the required packages:
|
||||
```bash
|
||||
pip install praisonaiagents pyyaml
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Import Components">
|
||||
Import the necessary components:
|
||||
```python
|
||||
from praisonaiagents import Agent, Task, PraisonAIAgents
|
||||
from praisonaiagents.tools import read_yaml, write_yaml, validate_yaml, merge_yaml, convert_yaml
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Create Agent">
|
||||
Create a YAML processing agent:
|
||||
```python
|
||||
yaml_agent = Agent(
|
||||
name="YAMLProcessor",
|
||||
role="YAML Processing Specialist",
|
||||
goal="Process YAML files efficiently and accurately.",
|
||||
backstory="Expert in YAML file manipulation and validation.",
|
||||
tools=[read_yaml, write_yaml, validate_yaml, merge_yaml, convert_yaml],
|
||||
self_reflect=False
|
||||
)
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Define Task">
|
||||
Define the YAML processing task:
|
||||
```python
|
||||
yaml_task = Task(
|
||||
description="Parse and validate configuration files.",
|
||||
expected_output="Validated and processed YAML configurations.",
|
||||
agent=yaml_agent,
|
||||
name="yaml_processing"
|
||||
)
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Run Agent">
|
||||
Initialize and run the agent:
|
||||
```python
|
||||
agents = PraisonAIAgents(
|
||||
agents=[yaml_agent],
|
||||
tasks=[yaml_task],
|
||||
process="sequential"
|
||||
)
|
||||
agents.start()
|
||||
```
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
## Understanding YAML Tools
|
||||
|
||||
<Card title="What are YAML Tools?" icon="question">
|
||||
YAML Tools provide YAML processing capabilities for AI agents:
|
||||
- Reading YAML files
|
||||
- Writing YAML data
|
||||
- Validating YAML structure
|
||||
- Merging YAML files
|
||||
- Converting between formats
|
||||
</Card>
|
||||
|
||||
## Key Components
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="YAML Agent" icon="user-robot">
|
||||
Create specialized YAML agents:
|
||||
```python
|
||||
Agent(tools=[read_yaml, write_yaml, validate_yaml, merge_yaml, convert_yaml])
|
||||
```
|
||||
</Card>
|
||||
<Card title="YAML Task" icon="list-check">
|
||||
Define YAML tasks:
|
||||
```python
|
||||
Task(description="yaml_operation")
|
||||
```
|
||||
</Card>
|
||||
<Card title="Process Types" icon="arrows-split-up-and-left">
|
||||
Sequential or parallel processing:
|
||||
```python
|
||||
process="sequential"
|
||||
```
|
||||
</Card>
|
||||
<Card title="YAML Options" icon="sliders">
|
||||
Customize YAML parameters:
|
||||
```python
|
||||
safe_load=True, encoding="utf-8"
|
||||
```
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
## Examples
|
||||
|
||||
### Basic YAML Processing Agent
|
||||
|
||||
```python
|
||||
from praisonaiagents import Agent, Task, PraisonAIAgents
|
||||
from praisonaiagents.tools import read_yaml, write_yaml, validate_yaml, merge_yaml, convert_yaml
|
||||
|
||||
# Create YAML agent
|
||||
yaml_agent = Agent(
|
||||
name="YAMLExpert",
|
||||
role="YAML Processing Specialist",
|
||||
goal="Process YAML files efficiently and accurately.",
|
||||
backstory="Expert in YAML file handling and validation.",
|
||||
tools=[read_yaml, write_yaml, validate_yaml, merge_yaml, convert_yaml],
|
||||
self_reflect=False
|
||||
)
|
||||
|
||||
# Define YAML task
|
||||
yaml_task = Task(
|
||||
description="Parse and validate configuration files.",
|
||||
expected_output="Processed and validated YAML data.",
|
||||
agent=yaml_agent,
|
||||
name="config_processing"
|
||||
)
|
||||
|
||||
# Run agent
|
||||
agents = PraisonAIAgents(
|
||||
agents=[yaml_agent],
|
||||
tasks=[yaml_task],
|
||||
process="sequential"
|
||||
)
|
||||
agents.start()
|
||||
```
|
||||
|
||||
### Advanced YAML Processing with Multiple Agents
|
||||
|
||||
```python
|
||||
# Create YAML processing agent
|
||||
processor_agent = Agent(
|
||||
name="Processor",
|
||||
role="YAML Processor",
|
||||
goal="Process YAML files systematically.",
|
||||
tools=[read_yaml, write_yaml, convert_yaml],
|
||||
self_reflect=False
|
||||
)
|
||||
|
||||
# Create validation agent
|
||||
validator_agent = Agent(
|
||||
name="Validator",
|
||||
role="Data Validator",
|
||||
goal="Validate YAML structure and content.",
|
||||
backstory="Expert in data validation and verification.",
|
||||
tools=[validate_yaml, merge_yaml],
|
||||
self_reflect=False
|
||||
)
|
||||
|
||||
# Define tasks
|
||||
processing_task = Task(
|
||||
description="Process and transform YAML configurations.",
|
||||
agent=processor_agent,
|
||||
name="yaml_processing"
|
||||
)
|
||||
|
||||
validation_task = Task(
|
||||
description="Validate processed YAML data.",
|
||||
agent=validator_agent,
|
||||
name="data_validation"
|
||||
)
|
||||
|
||||
# Run agents
|
||||
agents = PraisonAIAgents(
|
||||
agents=[processor_agent, validator_agent],
|
||||
tasks=[processing_task, validation_task],
|
||||
process="sequential"
|
||||
)
|
||||
agents.start()
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="Agent Configuration">
|
||||
Configure agents with clear YAML focus:
|
||||
```python
|
||||
Agent(
|
||||
name="YAMLProcessor",
|
||||
role="YAML Processing Specialist",
|
||||
goal="Process YAML files accurately and safely",
|
||||
tools=[read_yaml, write_yaml, validate_yaml, merge_yaml, convert_yaml]
|
||||
)
|
||||
```
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Task Definition">
|
||||
Define specific YAML operations:
|
||||
```python
|
||||
Task(
|
||||
description="Parse and validate deployment configurations",
|
||||
expected_output="Validated configuration set"
|
||||
)
|
||||
```
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
## Common Patterns
|
||||
|
||||
### YAML Processing Pipeline
|
||||
```python
|
||||
# Processing agent
|
||||
processor = Agent(
|
||||
name="Processor",
|
||||
role="YAML Processor",
|
||||
tools=[read_yaml, write_yaml, convert_yaml]
|
||||
)
|
||||
|
||||
# Validation agent
|
||||
validator = Agent(
|
||||
name="Validator",
|
||||
role="Data Validator",
|
||||
tools=[validate_yaml, merge_yaml]
|
||||
)
|
||||
|
||||
# Define tasks
|
||||
process_task = Task(
|
||||
description="Process YAML files",
|
||||
agent=processor
|
||||
)
|
||||
|
||||
validate_task = Task(
|
||||
description="Validate processed data",
|
||||
agent=validator
|
||||
)
|
||||
|
||||
# Run workflow
|
||||
agents = PraisonAIAgents(
|
||||
agents=[processor, validator],
|
||||
tasks=[process_task, validate_task]
|
||||
)
|
||||
@@ -0,0 +1,252 @@
|
||||
---
|
||||
title: "YFinance Agent"
|
||||
description: "Yahoo Finance data retrieval tools for AI agents."
|
||||
icon: "chart-line"
|
||||
---
|
||||
|
||||
<Note>
|
||||
**Prerequisites**
|
||||
- Python 3.10 or higher
|
||||
- PraisonAI Agents package installed
|
||||
- `yfinance` package installed
|
||||
- Basic understanding of financial data
|
||||
</Note>
|
||||
|
||||
## YFinance Tools
|
||||
|
||||
Use YFinance Tools to retrieve and analyze financial data with AI agents.
|
||||
|
||||
<Steps>
|
||||
<Step title="Install Dependencies">
|
||||
First, install the required packages:
|
||||
```bash
|
||||
pip install praisonaiagents yfinance
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Import Components">
|
||||
Import the necessary components:
|
||||
```python
|
||||
from praisonaiagents import Agent, Task, PraisonAIAgents
|
||||
from praisonaiagents.tools import get_stock_price, get_stock_info, get_historical_data
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Create Agent">
|
||||
Create a financial data agent:
|
||||
```python
|
||||
finance_agent = Agent(
|
||||
name="FinanceAnalyst",
|
||||
role="Financial Data Specialist",
|
||||
goal="Retrieve and analyze financial data efficiently.",
|
||||
backstory="Expert in financial data analysis and market research.",
|
||||
tools=[get_stock_price, get_stock_info, get_historical_data],
|
||||
self_reflect=False
|
||||
)
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Define Task">
|
||||
Define the financial analysis task:
|
||||
```python
|
||||
finance_task = Task(
|
||||
description="Analyze stock performance and market trends.",
|
||||
expected_output="Detailed financial analysis with market insights.",
|
||||
agent=finance_agent,
|
||||
name="market_analysis"
|
||||
)
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Run Agent">
|
||||
Initialize and run the agent:
|
||||
```python
|
||||
agents = PraisonAIAgents(
|
||||
agents=[finance_agent],
|
||||
tasks=[finance_task],
|
||||
process="sequential"
|
||||
)
|
||||
agents.start()
|
||||
```
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
## Understanding YFinance Tools
|
||||
|
||||
<Card title="What are YFinance Tools?" icon="question">
|
||||
YFinance Tools provide financial data capabilities for AI agents:
|
||||
- Real-time stock prices
|
||||
- Detailed company information
|
||||
- Historical market data
|
||||
- Financial metrics and ratios
|
||||
- Market performance analysis
|
||||
</Card>
|
||||
|
||||
## Key Components
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Finance Agent" icon="user-robot">
|
||||
Create specialized finance agents:
|
||||
```python
|
||||
Agent(tools=[get_stock_price, get_stock_info, get_historical_data])
|
||||
```
|
||||
</Card>
|
||||
<Card title="Finance Task" icon="list-check">
|
||||
Define finance tasks:
|
||||
```python
|
||||
Task(description="finance_query")
|
||||
```
|
||||
</Card>
|
||||
<Card title="Process Types" icon="arrows-split-up-and-left">
|
||||
Sequential or parallel processing:
|
||||
```python
|
||||
process="sequential"
|
||||
```
|
||||
</Card>
|
||||
<Card title="Finance Options" icon="sliders">
|
||||
Customize data parameters:
|
||||
```python
|
||||
period="1y", interval="1d"
|
||||
```
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
## Examples
|
||||
|
||||
### Basic Financial Data Agent
|
||||
|
||||
```python
|
||||
from praisonaiagents import Agent, Task, PraisonAIAgents
|
||||
from praisonaiagents.tools import get_stock_price, get_stock_info, get_historical_data
|
||||
|
||||
# Create finance agent
|
||||
finance_agent = Agent(
|
||||
name="MarketAnalyst",
|
||||
role="Financial Data Specialist",
|
||||
goal="Analyze market data efficiently and accurately.",
|
||||
backstory="Expert in financial analysis and market research.",
|
||||
tools=[get_stock_price, get_stock_info, get_historical_data],
|
||||
self_reflect=False
|
||||
)
|
||||
|
||||
# Define finance task
|
||||
finance_task = Task(
|
||||
description="Analyze tech sector performance and trends.",
|
||||
expected_output="Comprehensive market analysis report.",
|
||||
agent=finance_agent,
|
||||
name="sector_analysis"
|
||||
)
|
||||
|
||||
# Run agent
|
||||
agents = PraisonAIAgents(
|
||||
agents=[finance_agent],
|
||||
tasks=[finance_task],
|
||||
process="sequential"
|
||||
)
|
||||
agents.start()
|
||||
```
|
||||
|
||||
### Advanced Market Analysis with Multiple Agents
|
||||
|
||||
```python
|
||||
# Create data retrieval agent
|
||||
data_agent = Agent(
|
||||
name="DataCollector",
|
||||
role="Market Data Collector",
|
||||
goal="Retrieve financial data systematically.",
|
||||
tools=[get_stock_price, get_historical_data],
|
||||
self_reflect=False
|
||||
)
|
||||
|
||||
# Create analysis agent
|
||||
analysis_agent = Agent(
|
||||
name="Analyst",
|
||||
role="Market Analyst",
|
||||
goal="Analyze market trends and patterns.",
|
||||
backstory="Expert in financial market analysis.",
|
||||
tools=[get_stock_info],
|
||||
self_reflect=False
|
||||
)
|
||||
|
||||
# Define tasks
|
||||
data_task = Task(
|
||||
description="Collect historical market data for analysis.",
|
||||
agent=data_agent,
|
||||
name="data_collection"
|
||||
)
|
||||
|
||||
analysis_task = Task(
|
||||
description="Analyze collected market data for insights.",
|
||||
agent=analysis_agent,
|
||||
name="trend_analysis"
|
||||
)
|
||||
|
||||
# Run agents
|
||||
agents = PraisonAIAgents(
|
||||
agents=[data_agent, analysis_agent],
|
||||
tasks=[data_task, analysis_task],
|
||||
process="sequential"
|
||||
)
|
||||
agents.start()
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="Agent Configuration">
|
||||
Configure agents with clear finance focus:
|
||||
```python
|
||||
Agent(
|
||||
name="FinanceAnalyst",
|
||||
role="Market Analysis Specialist",
|
||||
goal="Analyze financial data accurately and efficiently",
|
||||
tools=[get_stock_price, get_stock_info, get_historical_data]
|
||||
)
|
||||
```
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Task Definition">
|
||||
Define specific analysis objectives:
|
||||
```python
|
||||
Task(
|
||||
description="Analyze market trends and generate insights",
|
||||
expected_output="Detailed market analysis"
|
||||
)
|
||||
```
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
## Common Patterns
|
||||
|
||||
### Market Analysis Pipeline
|
||||
```python
|
||||
# Data agent
|
||||
collector = Agent(
|
||||
name="Collector",
|
||||
role="Data Collector",
|
||||
tools=[get_stock_price, get_historical_data]
|
||||
)
|
||||
|
||||
# Analysis agent
|
||||
analyst = Agent(
|
||||
name="Analyst",
|
||||
role="Market Analyst",
|
||||
tools=[get_stock_info]
|
||||
)
|
||||
|
||||
# Define tasks
|
||||
collect_task = Task(
|
||||
description="Collect market data",
|
||||
agent=collector
|
||||
)
|
||||
|
||||
analyze_task = Task(
|
||||
description="Analyze market trends",
|
||||
agent=analyst
|
||||
)
|
||||
|
||||
# Run workflow
|
||||
agents = PraisonAIAgents(
|
||||
agents=[collector, analyst],
|
||||
tasks=[collect_task, analyze_task]
|
||||
)
|
||||
Generated
-8830
File diff suppressed because it is too large.
Load diff
+1
-1
@@ -3,7 +3,7 @@ class Praisonai < Formula
|
||||
|
||||
desc "AI tools for various AI applications"
|
||||
homepage "https://github.com/MervinPraison/PraisonAI"
|
||||
url "https://github.com/MervinPraison/PraisonAI/archive/refs/tags/2.0.28.tar.gz"
|
||||
url "https://github.com/MervinPraison/PraisonAI/archive/refs/tags/2.0.36.tar.gz"
|
||||
sha256 "1828fb9227d10f991522c3f24f061943a254b667196b40b1a3e4a54a8d30ce32" # Replace with actual SHA256 checksum
|
||||
license "MIT"
|
||||
|
||||
|
||||
+1
-1
@@ -56,7 +56,7 @@ class CloudDeployer:
|
||||
file.write("FROM python:3.11-slim\n")
|
||||
file.write("WORKDIR /app\n")
|
||||
file.write("COPY . .\n")
|
||||
file.write("RUN pip install flask praisonai==2.0.28 gunicorn markdown\n")
|
||||
file.write("RUN pip install flask praisonai==2.0.36 gunicorn markdown\n")
|
||||
file.write("EXPOSE 8080\n")
|
||||
file.write('CMD ["gunicorn", "-b", "0.0.0.0:8080", "api:app"]\n')
|
||||
|
||||
|
||||
+4
-4
@@ -1,6 +1,6 @@
|
||||
[project]
|
||||
name = "PraisonAI"
|
||||
version = "2.0.28"
|
||||
version = "2.0.36"
|
||||
description = "PraisonAI is an AI Agents Framework with Self Reflection. PraisonAI application combines PraisonAI Agents, AutoGen, and CrewAI into a low-code solution for building and managing multi-agent LLM systems, focusing on simplicity, customisation, and efficient human–agent collaboration."
|
||||
readme = "README.md"
|
||||
license = ""
|
||||
@@ -12,7 +12,7 @@ dependencies = [
|
||||
"rich>=13.7",
|
||||
"markdown>=3.5",
|
||||
"pyparsing>=3.0.0",
|
||||
"praisonaiagents>=0.0.20",
|
||||
"praisonaiagents>=0.0.27",
|
||||
"python-dotenv>=0.19.0",
|
||||
"instructor>=1.3.3",
|
||||
"PyYAML>=6.0",
|
||||
@@ -84,7 +84,7 @@ autogen = ["pyautogen>=0.2.19", "praisonai-tools>=0.0.7", "crewai"]
|
||||
|
||||
[tool.poetry]
|
||||
name = "PraisonAI"
|
||||
version = "2.0.28"
|
||||
version = "2.0.36"
|
||||
description = "PraisonAI is an AI Agents Framework with Self Reflection. PraisonAI application combines PraisonAI Agents, AutoGen, and CrewAI into a low-code solution for building and managing multi-agent LLM systems, focusing on simplicity, customisation, and efficient human–agent collaboration."
|
||||
authors = ["Mervin Praison"]
|
||||
license = ""
|
||||
@@ -102,7 +102,7 @@ python = ">=3.10,<3.13"
|
||||
rich = ">=13.7"
|
||||
markdown = ">=3.5"
|
||||
pyparsing = ">=3.0.0"
|
||||
praisonaiagents = ">=0.0.20"
|
||||
praisonaiagents = ">=0.0.27"
|
||||
python-dotenv = ">=0.19.0"
|
||||
instructor = ">=1.3.3"
|
||||
PyYAML = ">=6.0"
|
||||
|
||||
@@ -672,7 +672,7 @@ name = "click"
|
||||
version = "8.1.8"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "colorama", marker = "platform_system == 'Windows'" },
|
||||
{ name = "colorama", marker = "sys_platform == 'win32'" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/b9/2e/0090cbf739cee7d23781ad4b89a9894a41538e4fcf4c31dcdd705b78eb8b/click-8.1.8.tar.gz", hash = "sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a", size = 226593 }
|
||||
wheels = [
|
||||
@@ -3061,7 +3061,7 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "praisonai"
|
||||
version = "2.0.28"
|
||||
version = "2.0.36"
|
||||
source = { editable = "." }
|
||||
dependencies = [
|
||||
{ name = "instructor" },
|
||||
@@ -3198,7 +3198,7 @@ requires-dist = [
|
||||
{ name = "plotly", marker = "extra == 'realtime'", specifier = ">=5.24.0" },
|
||||
{ name = "praisonai-tools", marker = "extra == 'autogen'", specifier = ">=0.0.7" },
|
||||
{ name = "praisonai-tools", marker = "extra == 'crewai'", specifier = ">=0.0.7" },
|
||||
{ name = "praisonaiagents", specifier = ">=0.0.20" },
|
||||
{ name = "praisonaiagents", specifier = ">=0.0.27" },
|
||||
{ name = "pyautogen", marker = "extra == 'autogen'", specifier = ">=0.2.19" },
|
||||
{ name = "pydantic", marker = "extra == 'chat'", specifier = "<=2.10.1" },
|
||||
{ name = "pydantic", marker = "extra == 'code'", specifier = "<=2.10.1" },
|
||||
@@ -3251,16 +3251,16 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "praisonaiagents"
|
||||
version = "0.0.20"
|
||||
version = "0.0.27"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "openai" },
|
||||
{ name = "pydantic" },
|
||||
{ name = "rich" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/8e/89/0e9d17b7113772ab469f3d113af51fb3ff5c2f16eb0a1b70667a12478358/praisonaiagents-0.0.20.tar.gz", hash = "sha256:15e08f2c8c06643e091870ba0f15c1614f6052dea45986c877dad52e8fe7f06e", size = 23885 }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/05/c9/b368dc9c23e9d0df0b2d427055b71e842beebc15e3d005520b52baf05481/praisonaiagents-0.0.27.tar.gz", hash = "sha256:a195a8ea902ef437cc2ba8a6cac4ff76d7c4a208ef387ff69e752343e53ce104", size = 61683 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/f8/94/5f62ded3aad4ee5d879e8b9712be4a3268abc2d89f71b10999109cef147c/praisonaiagents-0.0.20-py3-none-any.whl", hash = "sha256:3e9c62f3c4d8978bea8e0c95359a49e20db833511e17e122ccc06eb77996a618", size = 29883 },
|
||||
{ url = "https://files.pythonhosted.org/packages/0d/63/b4b45c943c78b1818cec8b2dd92b3fdea36075eb5e323c8ca22e917ca75e/praisonaiagents-0.0.27-py3-none-any.whl", hash = "sha256:3404a186f2be2dfed0b56efec613896f4306f5589dc65d4b3f7034b0401d7593", size = 80590 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -4641,7 +4641,7 @@ name = "tqdm"
|
||||
version = "4.67.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "colorama", marker = "platform_system == 'Windows'" },
|
||||
{ name = "colorama", marker = "sys_platform == 'win32'" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/a8/4b/29b4ef32e036bb34e4ab51796dd745cdba7ed47ad142a9f4a1eb8e0c744d/tqdm-4.67.1.tar.gz", hash = "sha256:f8aef9c52c08c13a65f30ea34f4e5aac3fd1a34959879d7e59e63027286627f2", size = 169737 }
|
||||
wheels = [
|
||||
@@ -5021,7 +5021,7 @@ version = "2.1.3"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "numpy" },
|
||||
{ name = "nvidia-nccl-cu12", marker = "platform_machine != 'aarch64' and platform_system == 'Linux'" },
|
||||
{ name = "nvidia-nccl-cu12", marker = "platform_machine != 'aarch64' and sys_platform == 'linux'" },
|
||||
{ name = "scipy" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/48/b0/131ffc4a15fd3acee9be3a7baa6b2fa6faa479799c51b880de9fc3ddf550/xgboost-2.1.3.tar.gz", hash = "sha256:7699ec4226156887d3afc665c63ab87469db9d46e361c702ba9fccd22535730c", size = 1090326 }
|
||||
|
||||
Reference in new issue
Block a user