mirror of
https://github.com/MervinPraison/PraisonAI.git
synced 2026-11-13 05:01:35 -10:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d278f2d2b2 | ||
|
|
df4596a699 | ||
|
|
dd0f47ec81 | ||
|
|
e53017a2fe | ||
|
|
fe034ba8f4 | ||
|
|
063e5780d6 |
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.77 gunicorn markdown
|
||||
RUN pip install flask praisonai==2.0.80 gunicorn markdown
|
||||
EXPOSE 8080
|
||||
CMD ["gunicorn", "-b", "0.0.0.0:8080", "api:app"]
|
||||
@@ -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.77 gunicorn markdown\n")
|
||||
file.write("RUN pip install flask praisonai==2.0.80 gunicorn markdown\n")
|
||||
file.write("EXPOSE 8080\n")
|
||||
file.write('CMD ["gunicorn", "-b", "0.0.0.0:8080", "api:app"]\n')
|
||||
|
||||
|
||||
+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.77.tar.gz"
|
||||
url "https://github.com/MervinPraison/PraisonAI/archive/refs/tags/2.0.80.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.77 gunicorn markdown\n")
|
||||
file.write("RUN pip install flask praisonai==2.0.80 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.77"
|
||||
version = "2.0.80"
|
||||
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.62",
|
||||
"praisonaiagents>=0.0.65",
|
||||
"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.77"
|
||||
version = "2.0.80"
|
||||
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.62"
|
||||
praisonaiagents = ">=0.0.65"
|
||||
python-dotenv = ">=0.19.0"
|
||||
instructor = ">=1.3.3"
|
||||
PyYAML = ">=6.0"
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
from praisonaiagents import Agent
|
||||
|
||||
agent = Agent(
|
||||
instructions="You are a Wikipedia Agent",
|
||||
llm="anthropic/claude-3-7-sonnet-20250219"
|
||||
)
|
||||
result = agent.start("Why Sky is Blue?")
|
||||
print(result)
|
||||
|
||||
from praisonaiagents import Agent
|
||||
from praisonaiagents.tools import internet_search
|
||||
|
||||
agent = Agent(
|
||||
instructions="You are a Wikipedia Agent",
|
||||
tools=[internet_search],
|
||||
llm="anthropic/claude-3-7-sonnet-20250219"
|
||||
)
|
||||
agent.start("What is Praison AI?")
|
||||
|
||||
from praisonaiagents import Agent, PraisonAIAgents
|
||||
from praisonaiagents.tools import internet_search
|
||||
|
||||
|
||||
research_agent = Agent(
|
||||
instructions="Search Information about Claude Sonnet 3.7",
|
||||
tools=[internet_search],
|
||||
llm="anthropic/claude-3-7-sonnet-20250219"
|
||||
)
|
||||
|
||||
editor_agent = Agent(
|
||||
instructions="Write a Blog Post with the provided information about Claude Sonnet 3.7",
|
||||
llm="anthropic/claude-3-7-sonnet-20250219"
|
||||
)
|
||||
|
||||
agents = PraisonAIAgents(agents=[research_agent, editor_agent])
|
||||
result = agents.start()
|
||||
print(result)
|
||||
@@ -1,10 +1,10 @@
|
||||
from praisonaiagents import Agent
|
||||
from praisonaiagents.tools import internet_search
|
||||
|
||||
agent = Agent(
|
||||
instructions="You are a helpful assistant",
|
||||
llm="gemini/gemini-1.5-flash-8b",
|
||||
self_reflect=True,
|
||||
verbose=True
|
||||
tools=[internet_search],
|
||||
llm="gemini/gemini-1.5-flash-8b"
|
||||
)
|
||||
|
||||
agent.start("Why sky is Blue?")
|
||||
agent.start("What is Praison AI?")
|
||||
@@ -477,8 +477,14 @@ Context:
|
||||
else:
|
||||
self.run_task(task_id)
|
||||
|
||||
async def astart(self, content=None, **kwargs):
|
||||
"""Async version of start method"""
|
||||
async def astart(self, content=None, return_dict=False, **kwargs):
|
||||
"""Async version of start method
|
||||
|
||||
Args:
|
||||
content: Optional content to add to all tasks' context
|
||||
return_dict: If True, returns the full results dictionary instead of only the final response
|
||||
**kwargs: Additional arguments
|
||||
"""
|
||||
if content:
|
||||
# Add content to context of all tasks
|
||||
for task in self.tasks.values():
|
||||
@@ -488,10 +494,25 @@ Context:
|
||||
task.context.append(content)
|
||||
|
||||
await self.arun_all_tasks()
|
||||
return {
|
||||
|
||||
# Get results
|
||||
results = {
|
||||
"task_status": self.get_all_tasks_status(),
|
||||
"task_results": {task_id: self.get_task_result(task_id) for task_id in self.tasks}
|
||||
}
|
||||
|
||||
# By default, return only the final agent's response
|
||||
if not return_dict:
|
||||
# Get the last task (assuming sequential processing)
|
||||
task_ids = list(self.tasks.keys())
|
||||
if task_ids:
|
||||
last_task_id = task_ids[-1]
|
||||
last_result = self.get_task_result(last_task_id)
|
||||
if last_result:
|
||||
return last_result.raw
|
||||
|
||||
# Return full results dict if return_dict is True or if no final result was found
|
||||
return results
|
||||
|
||||
def save_output_to_file(self, task, task_output):
|
||||
if task.output_file:
|
||||
@@ -801,8 +822,14 @@ Context:
|
||||
return str(agent[0])
|
||||
return None
|
||||
|
||||
def start(self, content=None, **kwargs):
|
||||
"""Start agent execution with optional content and config"""
|
||||
def start(self, content=None, return_dict=False, **kwargs):
|
||||
"""Start agent execution with optional content and config
|
||||
|
||||
Args:
|
||||
content: Optional content to add to all tasks' context
|
||||
return_dict: If True, returns the full results dictionary instead of only the final response
|
||||
**kwargs: Additional arguments
|
||||
"""
|
||||
if content:
|
||||
# Add content to context of all tasks
|
||||
for task in self.tasks.values():
|
||||
@@ -815,10 +842,25 @@ Context:
|
||||
|
||||
# Run tasks as before
|
||||
self.run_all_tasks()
|
||||
return {
|
||||
|
||||
# Get results
|
||||
results = {
|
||||
"task_status": self.get_all_tasks_status(),
|
||||
"task_results": {task_id: self.get_task_result(task_id) for task_id in self.tasks}
|
||||
}
|
||||
|
||||
# By default, return only the final agent's response
|
||||
if not return_dict:
|
||||
# Get the last task (assuming sequential processing)
|
||||
task_ids = list(self.tasks.keys())
|
||||
if task_ids:
|
||||
last_task_id = task_ids[-1]
|
||||
last_result = self.get_task_result(last_task_id)
|
||||
if last_result:
|
||||
return last_result.raw
|
||||
|
||||
# Return full results dict if return_dict is True or if no final result was found
|
||||
return results
|
||||
|
||||
def set_state(self, key: str, value: Any) -> None:
|
||||
"""Set a state value"""
|
||||
|
||||
@@ -171,6 +171,8 @@ class LLM:
|
||||
|
||||
# Enable error dropping for cleaner output
|
||||
litellm.drop_params = True
|
||||
# Enable parameter modification for providers like Anthropic
|
||||
litellm.modify_params = True
|
||||
self._setup_event_tracking(events)
|
||||
|
||||
# Log all initialization parameters when in debug mode
|
||||
@@ -438,20 +440,29 @@ class LLM:
|
||||
function_name = tool_call["function"]["name"]
|
||||
arguments = json.loads(tool_call["function"]["arguments"])
|
||||
|
||||
if verbose:
|
||||
display_tool_call(f"Agent {agent_name} is calling function '{function_name}' with arguments: {arguments}", console=console)
|
||||
|
||||
logging.debug(f"[TOOL_EXEC_DEBUG] About to execute tool {function_name} with args: {arguments}")
|
||||
tool_result = execute_tool_fn(function_name, arguments)
|
||||
logging.debug(f"[TOOL_EXEC_DEBUG] Tool execution result: {tool_result}")
|
||||
|
||||
if tool_result:
|
||||
if verbose:
|
||||
display_tool_call(f"Function '{function_name}' returned: {tool_result}", console=console)
|
||||
if verbose:
|
||||
display_message = f"Agent {agent_name} called function '{function_name}' with arguments: {arguments}\n"
|
||||
if tool_result:
|
||||
display_message += f"Function returned: {tool_result}"
|
||||
logging.debug(f"[TOOL_EXEC_DEBUG] Display message with result: {display_message}")
|
||||
else:
|
||||
display_message += "Function returned no output"
|
||||
logging.debug("[TOOL_EXEC_DEBUG] Tool returned no output")
|
||||
|
||||
logging.debug(f"[TOOL_EXEC_DEBUG] About to display tool call with message: {display_message}")
|
||||
display_tool_call(display_message, console=console)
|
||||
|
||||
messages.append({
|
||||
"role": "tool",
|
||||
"tool_call_id": tool_call["id"],
|
||||
"content": json.dumps(tool_result)
|
||||
})
|
||||
else:
|
||||
logging.debug("[TOOL_EXEC_DEBUG] Verbose mode off, not displaying tool call")
|
||||
messages.append({
|
||||
"role": "tool",
|
||||
"tool_call_id": tool_call["id"],
|
||||
@@ -923,14 +934,15 @@ Output MUST be JSON with 'reflection' and 'satisfactory'.
|
||||
function_name = tool_call.function.name
|
||||
arguments = json.loads(tool_call.function.arguments)
|
||||
|
||||
if verbose:
|
||||
display_tool_call(f"Agent {agent_name} is calling function '{function_name}' with arguments: {arguments}", console=console)
|
||||
|
||||
tool_result = await execute_tool_fn(function_name, arguments)
|
||||
|
||||
if tool_result:
|
||||
if verbose:
|
||||
display_tool_call(f"Function '{function_name}' returned: {tool_result}", console=console)
|
||||
if verbose:
|
||||
display_message = f"Agent {agent_name} called function '{function_name}' with arguments: {arguments}\n"
|
||||
if tool_result:
|
||||
display_message += f"Function returned: {tool_result}"
|
||||
else:
|
||||
display_message += "Function returned no output"
|
||||
display_tool_call(display_message, console=console)
|
||||
messages.append({
|
||||
"role": "tool",
|
||||
"tool_call_id": tool_call.id,
|
||||
|
||||
@@ -86,6 +86,7 @@ async def execute_callback(display_type: str, **kwargs):
|
||||
def _clean_display_content(content: str, max_length: int = 20000) -> str:
|
||||
"""Helper function to clean and truncate content for display."""
|
||||
if not content or not str(content).strip():
|
||||
logging.debug(f"Empty content received in _clean_display_content: {repr(content)}")
|
||||
return ""
|
||||
|
||||
content = str(content)
|
||||
@@ -174,11 +175,14 @@ def display_instruction(message: str, console=None, agent_name: str = None, agen
|
||||
console.print(Panel.fit(Text(message, style="bold blue"), title="Instruction", border_style="cyan"))
|
||||
|
||||
def display_tool_call(message: str, console=None):
|
||||
logging.debug(f"display_tool_call called with message: {repr(message)}")
|
||||
if not message or not message.strip():
|
||||
logging.debug("Empty message in display_tool_call, returning early")
|
||||
return
|
||||
if console is None:
|
||||
console = Console()
|
||||
message = _clean_display_content(str(message))
|
||||
logging.debug(f"Cleaned message in display_tool_call: {repr(message)}")
|
||||
|
||||
# Execute callback if registered
|
||||
if 'tool_call' in sync_display_callbacks:
|
||||
@@ -202,7 +206,8 @@ def display_error(message: str, console=None):
|
||||
|
||||
def display_generating(content: str = "", start_time: Optional[float] = None):
|
||||
if not content or not str(content).strip():
|
||||
return Panel("", title="", border_style="green")
|
||||
logging.debug("Empty content in display_generating, returning early")
|
||||
return None
|
||||
|
||||
elapsed_str = ""
|
||||
if start_time is not None:
|
||||
@@ -293,11 +298,14 @@ async def adisplay_instruction(message: str, console=None, agent_name: str = Non
|
||||
|
||||
async def adisplay_tool_call(message: str, console=None):
|
||||
"""Async version of display_tool_call."""
|
||||
logging.debug(f"adisplay_tool_call called with message: {repr(message)}")
|
||||
if not message or not message.strip():
|
||||
logging.debug("Empty message in adisplay_tool_call, returning early")
|
||||
return
|
||||
if console is None:
|
||||
console = Console()
|
||||
message = _clean_display_content(str(message))
|
||||
logging.debug(f"Cleaned message in adisplay_tool_call: {repr(message)}")
|
||||
|
||||
if 'tool_call' in async_display_callbacks:
|
||||
await async_display_callbacks['tool_call'](message=message)
|
||||
@@ -321,7 +329,8 @@ async def adisplay_error(message: str, console=None):
|
||||
async def adisplay_generating(content: str = "", start_time: Optional[float] = None):
|
||||
"""Async version of display_generating."""
|
||||
if not content or not str(content).strip():
|
||||
return Panel("", title="", border_style="green")
|
||||
logging.debug("Empty content in adisplay_generating, returning early")
|
||||
return None
|
||||
|
||||
elapsed_str = ""
|
||||
if start_time is not None:
|
||||
|
||||
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
||||
|
||||
[project]
|
||||
name = "praisonaiagents"
|
||||
version = "0.0.62"
|
||||
version = "0.0.65"
|
||||
description = "Praison AI agents for completing complex tasks with Self Reflection Agents"
|
||||
authors = [
|
||||
{ name="Mervin Praison" }
|
||||
|
||||
Generated
+1
-1
@@ -1868,7 +1868,7 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "praisonaiagents"
|
||||
version = "0.0.62"
|
||||
version = "0.0.65"
|
||||
source = { editable = "." }
|
||||
dependencies = [
|
||||
{ name = "openai" },
|
||||
|
||||
@@ -3060,7 +3060,7 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "praisonai"
|
||||
version = "2.0.77"
|
||||
version = "2.0.80"
|
||||
source = { editable = "." }
|
||||
dependencies = [
|
||||
{ name = "instructor" },
|
||||
@@ -3197,7 +3197,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.62" },
|
||||
{ name = "praisonaiagents", specifier = ">=0.0.65" },
|
||||
{ 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" },
|
||||
@@ -3250,16 +3250,16 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "praisonaiagents"
|
||||
version = "0.0.62"
|
||||
version = "0.0.65"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "openai" },
|
||||
{ name = "pydantic" },
|
||||
{ name = "rich" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/26/44/528286f187d8be35839382251407a3b5ec7ecf5fc9b1fafd7e4197b436cb/praisonaiagents-0.0.62.tar.gz", hash = "sha256:d461553d7dc64441544a6ad92e6e446531f1be8e5cbb95261407540756b2cb8a", size = 104636 }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/9e/58/6e07c4abf57d78be642f1517fe0692a003dfc253ad91a03c70521d246b5e/praisonaiagents-0.0.65.tar.gz", hash = "sha256:16627166f1b42bd8d21759fbd67015fff0b4730ca224b4a566cffe2b5bb770e8", size = 105128 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/42/34/c389ba1a9a45b0f7637b073e25717d2f9e0e6e727cc4946182fcf86e8c12/praisonaiagents-0.0.62-py3-none-any.whl", hash = "sha256:f6883ba12642bb3a7af277bfc1c0020276c3ac31bc251ed381f0388b3a61e73b", size = 123702 },
|
||||
{ url = "https://files.pythonhosted.org/packages/04/02/e4f2ef3c008a407d3b945256d1513bf0159989055e9462c691265be3d294/praisonaiagents-0.0.65-py3-none-any.whl", hash = "sha256:f53e9c3ddf31c575dd5f65315db70b35487adb0f9ae908596e74ed315c12afc5", size = 124306 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
||||
Reference in new issue
Block a user