Compare commits

...
1 Commits
Author SHA1 Message Date
Mervin Praison e3b48c2526 Release v2.3.74 2025-12-22 17:01:50 +00:00
19 changed files with 324 additions and 167 deletions

No files matched your search

+1 -1
View File
@@ -16,7 +16,7 @@ RUN mkdir -p /root/.praison
# Install Python packages (using latest versions)
RUN pip install --no-cache-dir \
praisonai_tools \
"praisonai>=2.3.73" \
"praisonai>=2.3.74" \
"praisonai[chat]" \
"embedchain[github,youtube]"
+1 -1
View File
@@ -20,7 +20,7 @@ RUN mkdir -p /root/.praison
# Install Python packages (using latest versions)
RUN pip install --no-cache-dir \
praisonai_tools \
"praisonai>=2.3.73" \
"praisonai>=2.3.74" \
"praisonai[ui]" \
"praisonai[chat]" \
"praisonai[realtime]" \
+1 -1
View File
@@ -16,7 +16,7 @@ RUN mkdir -p /root/.praison
# Install Python packages (using latest versions)
RUN pip install --no-cache-dir \
praisonai_tools \
"praisonai>=2.3.73" \
"praisonai>=2.3.74" \
"praisonai[ui]" \
"praisonai[crewai]"
+53 -18
View File
@@ -5,30 +5,65 @@ This example demonstrates how to evaluate agent output accuracy
by comparing against expected outputs using LLM-as-judge.
"""
import os
from praisonaiagents import Agent
from praisonaiagents.eval import AccuracyEvaluator
# Create a simple math tutor agent
agent = Agent(
instructions="You are a math tutor. Answer math questions concisely with just the number."
)
# Check if we have an API key
has_api_key = os.getenv("OPENAI_API_KEY") is not None
# Create accuracy evaluator
evaluator = AccuracyEvaluator(
agent=agent,
input_text="What is 2 + 2?",
expected_output="4",
num_iterations=3, # Run 3 times for statistical significance
verbose=True
)
if has_api_key:
# Create a simple math tutor agent
agent = Agent(
instructions="You are a math tutor. Answer math questions concisely with just the number."
)
# Run evaluation
result = evaluator.run(print_summary=True)
# Create accuracy evaluator
evaluator = AccuracyEvaluator(
agent=agent,
input_text="What is 2 + 2?",
expected_output="4",
num_iterations=3, # Run 3 times for statistical significance
verbose=True
)
# Check results
print(f"\nAverage Score: {result.avg_score}/10")
print(f"Passed: {result.passed}")
# Run evaluation
result = evaluator.run(print_summary=True)
# Check results
print(f"\nAverage Score: {result.avg_score}/10")
print(f"Passed: {result.passed}")
else:
print("⚠️ No OPENAI_API_KEY found. Using mock evaluation...")
# Create evaluator without agent for mock testing
evaluator = AccuracyEvaluator(
func=lambda x: "4", # Mock function
input_text="What is 2 + 2?",
expected_output="4",
num_iterations=1,
verbose=True
)
# Test with mock output
try:
result = evaluator.run(print_summary=True)
print(f"\nMock Average Score: {result.avg_score}/10")
print(f"Mock Passed: {result.passed}")
except Exception as e:
print(f"Mock evaluation failed: {e}")
print("This is expected without an API key")
# You can also evaluate pre-generated outputs
print("\n--- Testing pre-generated output evaluation ---")
output = "The answer is 4"
result2 = evaluator.evaluate_output(output, print_summary=True)
if has_api_key:
try:
result2 = evaluator.evaluate_output(output, print_summary=True)
print(f"Pre-generated output score: {result2.avg_score}/10")
except Exception as e:
print(f"Pre-generated evaluation failed: {e}")
else:
print("⚠️ Skipping pre-generated evaluation (no API key)")
print("To run full evaluation, set OPENAI_API_KEY environment variable")
+67 -34
View File
@@ -5,9 +5,13 @@ This example demonstrates how to run batch evaluations
from a JSON test file.
"""
import os
import json
import tempfile
from praisonaiagents.eval import AccuracyEvaluator, CriteriaEvaluator
from praisonaiagents.eval import AccuracyEvaluator
# Check if we have an API key
has_api_key = os.getenv("OPENAI_API_KEY") is not None
# Create a test file with multiple test cases
test_cases = [
@@ -33,40 +37,69 @@ with tempfile.NamedTemporaryFile(mode='w', suffix='.json', delete=False) as f:
print(f"Test file created: {test_file}")
print(f"Running {len(test_cases)} test cases...")
# You can use the CLI for batch evaluation:
# praisonai eval batch --agent agents.yaml --test-file tests.json --batch-type accuracy
if has_api_key:
# You can use the CLI for batch evaluation:
# praisonai eval batch --agent agents.yaml --test-file tests.json --batch-type accuracy
# Or programmatically:
from praisonaiagents import Agent
# Or programmatically:
from praisonaiagents import Agent
agent = Agent(
instructions="You are a helpful assistant. Answer questions concisely."
)
results = []
for i, test_case in enumerate(test_cases):
print(f"\nTest {i + 1}: {test_case['input']}")
evaluator = AccuracyEvaluator(
agent=agent,
input_text=test_case["input"],
expected_output=test_case["expected"],
num_iterations=1
agent = Agent(
instructions="You are a helpful assistant. Answer questions concisely."
)
result = evaluator.run()
results.append({
"input": test_case["input"],
"expected": test_case["expected"],
"score": result.avg_score,
"passed": result.passed
})
print(f" Score: {result.avg_score}/10")
print(f" Passed: {result.passed}")
# Summary
passed = sum(1 for r in results if r["passed"])
print(f"\n{'='*50}")
print(f"Summary: {passed}/{len(results)} tests passed")
print(f"Pass Rate: {passed/len(results):.1%}")
results = []
for i, test_case in enumerate(test_cases):
print(f"\nTest {i + 1}: {test_case['input']}")
evaluator = AccuracyEvaluator(
agent=agent,
input_text=test_case["input"],
expected_output=test_case["expected"],
num_iterations=1
)
result = evaluator.run()
results.append({
"input": test_case["input"],
"expected": test_case["expected"],
"score": result.avg_score,
"passed": result.passed
})
print(f" Score: {result.avg_score}/10")
print(f" Passed: {result.passed}")
# Summary
passed = sum(1 for r in results if r["passed"])
print(f"\n{'='*50}")
print(f"Summary: {passed}/{len(results)} tests passed")
print(f"Pass Rate: {passed/len(results):.1%}")
else:
print("⚠️ No OPENAI_API_KEY found. Running mock batch evaluation...")
# Mock evaluation without API key
results = []
for i, test_case in enumerate(test_cases):
print(f"\nTest {i + 1}: {test_case['input']}")
# Mock result (all would fail without API key)
mock_score = 0.0
mock_passed = False
results.append({
"input": test_case["input"],
"expected": test_case["expected"],
"score": mock_score,
"passed": mock_passed
})
print(f" Score: {mock_score}/10 (mock)")
print(f" Passed: {mock_passed} (expected without API key)")
# Summary
passed = sum(1 for r in results if r["passed"])
print(f"\n{'='*50}")
print(f"Summary: {passed}/{len(results)} tests passed (mock evaluation)")
print(f"Pass Rate: {passed/len(results):.1%}")
print("\nTo run real batch evaluation, set OPENAI_API_KEY environment variable")
+63 -43
View File
@@ -5,58 +5,78 @@ This example demonstrates how to evaluate agent outputs
against custom criteria using LLM-as-judge.
"""
import os
from praisonaiagents import Agent
from praisonaiagents.eval import CriteriaEvaluator
# Create a customer service agent
agent = Agent(
instructions="You are a friendly customer service agent. Be helpful and empathetic."
)
# Check if we have an API key
has_api_key = os.getenv("OPENAI_API_KEY") is not None
# Create criteria evaluator with numeric scoring
evaluator = CriteriaEvaluator(
criteria="Response is helpful, empathetic, and provides a clear solution",
agent=agent,
input_text="I'm frustrated because my order hasn't arrived yet.",
scoring_type="numeric", # Score 1-10
threshold=7.0, # Pass if score >= 7
num_iterations=2,
verbose=True
)
if has_api_key:
print("--- Testing Criteria Evaluation with Agent ---")
# Create a customer service agent
agent = Agent(
instructions="You are a friendly customer service agent. Be helpful and empathetic."
)
# Run evaluation
result = evaluator.run(print_summary=True)
# Create criteria evaluator with numeric scoring
evaluator = CriteriaEvaluator(
criteria="Response is helpful, empathetic, and provides a clear solution",
agent=agent,
input_text="I'm frustrated because my order hasn't arrived yet.",
scoring_type="numeric", # Score 1-10
threshold=7.0, # Pass if score >= 7
num_iterations=2,
verbose=True
)
print(f"\nAverage Score: {result.avg_score}/10")
print(f"Pass Rate: {result.pass_rate:.1%}")
print(f"Passed: {result.passed}")
# Run evaluation
result = evaluator.run(print_summary=True)
# Binary scoring example (pass/fail)
binary_evaluator = CriteriaEvaluator(
criteria="Response does not contain any offensive language",
agent=agent,
input_text="Tell me a joke",
scoring_type="binary", # Pass or Fail
verbose=True
)
print("\nNumeric Scoring Results:")
print(f" Average Score: {result.avg_score}/10")
print(f" Pass Rate: {result.pass_rate:.1%}")
print(f" Passed: {result.passed}")
binary_result = binary_evaluator.run(print_summary=True)
# Binary scoring example (pass/fail)
print("\n--- Testing Binary Scoring ---")
binary_evaluator = CriteriaEvaluator(
criteria="Response does not contain any offensive language",
agent=agent,
input_text="Tell me a joke",
scoring_type="binary", # Pass or Fail
verbose=True
)
# Evaluate pre-generated output
output = "I understand your frustration. Let me check on your order right away."
result2 = evaluator.evaluate_output(output, print_summary=True)
binary_result = binary_evaluator.run(print_summary=True)
# With on_fail callback
print("\n--- Testing Failure Callback ---")
def handle_failure(score):
print(f"ALERT: Evaluation failed with score {score.score}")
print(f"Reasoning: {score.reasoning}")
# With on_fail callback
def handle_failure(score):
print(f"ALERT: Evaluation failed with score {score.score}")
print(f"Reasoning: {score.reasoning}")
callback_evaluator = CriteriaEvaluator(
criteria="Response is professional and helpful",
agent=agent,
input_text="Help me",
on_fail=handle_failure,
threshold=8.0
)
callback_evaluator = CriteriaEvaluator(
criteria="Response is professional and helpful",
agent=agent,
input_text="Help me",
on_fail=handle_failure,
threshold=8.0
)
callback_evaluator.run()
else:
print("⚠️ No OPENAI_API_KEY found. Skipping agent-based criteria evaluation...")
callback_evaluator.run()
# Test pre-generated output evaluation (doesn't need agent)
print("\n--- Testing Pre-generated Output Evaluation ---")
if has_api_key:
output = "I understand your frustration. Let me check on your order right away."
try:
result2 = evaluator.evaluate_output(output, print_summary=True)
print(f"Pre-generated output score: {result2.avg_score}/10")
except Exception as e:
print(f"Pre-generated evaluation failed: {e}")
else:
print("⚠️ Skipping pre-generated evaluation (no API key)")
print("To run full evaluation, set OPENAI_API_KEY environment variable")
+31 -23
View File
@@ -5,35 +5,43 @@ This example demonstrates how to benchmark agent performance
by measuring runtime and memory usage across multiple iterations.
"""
import os
from praisonaiagents import Agent
from praisonaiagents.eval import PerformanceEvaluator
# Create a simple agent
agent = Agent(
instructions="You are a helpful assistant. Answer questions briefly."
)
# Check if we have an API key
has_api_key = os.getenv("OPENAI_API_KEY") is not None
# Create performance evaluator
evaluator = PerformanceEvaluator(
agent=agent,
input_text="What is the capital of France?",
num_iterations=10, # Run 10 benchmark iterations
warmup_runs=2, # 2 warmup runs before measurement
track_memory=True, # Track memory usage
verbose=True
)
if has_api_key:
print("--- Testing Agent Performance ---")
# Create a simple agent
agent = Agent(
instructions="You are a helpful assistant. Answer questions briefly."
)
# Run evaluation
result = evaluator.run(print_summary=True)
# Create performance evaluator
evaluator = PerformanceEvaluator(
agent=agent,
input_text="What is the capital of France?",
num_iterations=10, # Run 10 benchmark iterations
warmup_runs=2, # 2 warmup runs before measurement
track_memory=True, # Track memory usage
verbose=True
)
# Access detailed metrics
print(f"\nDetailed Results:")
print(f" Average Time: {result.avg_run_time:.4f}s")
print(f" Min Time: {result.min_run_time:.4f}s")
print(f" Max Time: {result.max_run_time:.4f}s")
print(f" Median Time: {result.median_run_time:.4f}s")
print(f" P95 Time: {result.p95_run_time:.4f}s")
print(f" Avg Memory: {result.avg_memory:.2f} MB")
# Run evaluation
result = evaluator.run(print_summary=True)
# Access detailed metrics
print("\nAgent Performance Results:")
print(f" Average Time: {result.avg_run_time:.4f}s")
print(f" Min Time: {result.min_run_time:.4f}s")
print(f" Max Time: {result.max_run_time:.4f}s")
print(f" Median Time: {result.median_run_time:.4f}s")
print(f" P95 Time: {result.p95_run_time:.4f}s")
print(f" Avg Memory: {result.avg_memory:.2f} MB")
else:
print("⚠️ No OPENAI_API_KEY found. Skipping agent performance test...")
# You can also benchmark any function
def my_function():
+40 -16
View File
@@ -5,6 +5,7 @@ This example demonstrates how to verify that agents call
the expected tools during execution.
"""
import os
from praisonaiagents import Agent
from praisonaiagents.eval import ReliabilityEvaluator
@@ -19,30 +20,53 @@ def calculate(expression: str) -> str:
return str(eval(expression))
# Create an agent with tools
agent = Agent(
instructions="You are a helpful assistant with access to search and calculator tools.",
tools=[search_web, calculate]
)
# Check if we have an API key
has_api_key = os.getenv("OPENAI_API_KEY") is not None
# Create reliability evaluator
if has_api_key:
print("--- Testing Agent Tool Call Reliability ---")
# Create an agent with tools
agent = Agent(
instructions="You are a helpful assistant with access to search and calculator tools.",
tools=[search_web, calculate]
)
# Create reliability evaluator
evaluator = ReliabilityEvaluator(
agent=agent,
input_text="Search for the weather in Paris and calculate 25 * 4",
expected_tools=["search_web", "calculate"], # Tools that should be called
forbidden_tools=["delete_file"], # Tools that should NOT be called
verbose=True
)
# Run evaluation
result = evaluator.run(print_summary=True)
# Check results
print("\nAgent Reliability Results:")
print(f" Passed: {result.passed}")
print(f" Pass Rate: {result.pass_rate:.1%}")
else:
print("⚠️ No OPENAI_API_KEY found. Skipping agent reliability test...")
print("Agent would fail to call tools without API key (expected behavior)")
# You can also evaluate pre-recorded tool calls (doesn't need API key)
print("\n--- Testing Pre-recorded Tool Call Evaluation ---")
# Create a mock agent for tool call evaluation
mock_agent = Agent(instructions="Mock agent")
evaluator = ReliabilityEvaluator(
agent=agent,
input_text="Search for the weather in Paris and calculate 25 * 4",
agent=mock_agent,
expected_tools=["search_web", "calculate"], # Tools that should be called
forbidden_tools=["delete_file"], # Tools that should NOT be called
verbose=True
)
# Run evaluation
result = evaluator.run(print_summary=True)
# Check results
print(f"\nPassed: {result.passed}")
print(f"Pass Rate: {result.pass_rate:.1%}")
# You can also evaluate pre-recorded tool calls
result2 = evaluator.evaluate_tool_calls(
actual_tools=["search_web", "calculate"],
print_summary=True
)
print("\nPre-recorded Tool Call Results:")
print(f" Passed: {result2.passed}")
print(f" Pass Rate: {result2.pass_rate:.1%}")
@@ -3,7 +3,7 @@ Praison AI Agents - A package for hierarchical AI agent task execution
"""
# Apply warning patch BEFORE any imports to intercept warnings at the source
from . import _warning_patch
from . import _warning_patch # noqa: F401
# Import centralized logging configuration FIRST
from . import _logging
@@ -302,6 +302,23 @@ __all__ = [
'ExpandResult'
]
# Add workflow exports
__all__.extend([
'Workflow',
'WorkflowStep',
'WorkflowContext',
'StepResult',
'Route',
'Parallel',
'Loop',
'Repeat',
'route',
'parallel',
'loop',
'repeat',
'Pipeline'
])
# Add MCP to __all__ if available
if _mcp_available:
__all__.append('MCP')
@@ -318,6 +335,14 @@ __all__.extend([
'LineRange'
])
# Add Agent Skills exports (lazy loaded)
__all__.extend([
'SkillManager',
'SkillProperties',
'SkillMetadata',
'SkillLoader'
])
# AG-UI support (optional, lazy loaded)
try:
from praisonaiagents.ui.agui import AGUI
@@ -8,6 +8,7 @@ import functools
import sys
# Apply aggressive warning filters first
warnings.filterwarnings("ignore", message=".*There is no current event loop.*", category=DeprecationWarning)
warnings.filterwarnings("ignore", message=".*Pydantic serializer warnings.*")
warnings.filterwarnings("ignore", message=".*PydanticSerializationUnexpectedValue.*")
warnings.filterwarnings("ignore", message=".*Expected 9 fields but got.*")
@@ -31,7 +32,8 @@ SUPPRESSED_PATTERNS = [
"Expected `StreamingChoices` but got `Choices`",
"serialized value may not be as expected",
"Mixing V1 models and V2 models",
"Please upgrade `Settings` to V2"
"Please upgrade `Settings` to V2",
"There is no current event loop"
]
@functools.wraps(_original_warn)
@@ -43,7 +45,7 @@ def _patched_warn(message, category=None, stacklevel=1, source=None):
if pattern in msg_str:
return
if category == UserWarning and "pydantic" in msg_str.lower():
if category is UserWarning and "pydantic" in msg_str.lower():
return
_original_warn(message, category, stacklevel, source)
@@ -57,7 +59,7 @@ def _patched_warn_explicit(message, category, filename, lineno, module=None, reg
if pattern in msg_str:
return
if category == UserWarning and "pydantic" in msg_str.lower():
if category is UserWarning and "pydantic" in msg_str.lower():
return
if module and "pydantic" in str(module):
+1 -1
View File
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
[project]
name = "praisonaiagents"
version = "0.1.22"
version = "0.1.23"
description = "Praison AI agents for completing complex tasks with Self Reflection Agents"
readme = "README.md"
requires-python = ">=3.10"
+1 -1
View File
@@ -2422,7 +2422,7 @@ wheels = [
[[package]]
name = "praisonaiagents"
version = "0.1.22"
version = "0.1.23"
source = { editable = "." }
dependencies = [
{ name = "aiohttp" },
+2 -2
View File
@@ -3,8 +3,8 @@ 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/v2.3.73.tar.gz"
sha256 `curl -sL https://github.com/MervinPraison/PraisonAI/archive/refs/tags/v2.3.73.tar.gz | shasum -a 256`.split.first
url "https://github.com/MervinPraison/PraisonAI/archive/refs/tags/v2.3.74.tar.gz"
sha256 `curl -sL https://github.com/MervinPraison/PraisonAI/archive/refs/tags/v2.3.74.tar.gz | shasum -a 256`.split.first
license "MIT"
depends_on "[email protected]"
+6 -13
View File
@@ -253,18 +253,11 @@ def add_skills_parser(subparsers) -> None:
Args:
subparsers: Subparsers object from argparse
"""
skills_parser = subparsers.add_parser(
'skills',
help='Manage Agent Skills'
)
skills_subparsers = skills_parser.add_subparsers(
dest='skills_command',
help='Skills commands'
)
# subparsers is already the skills subparsers object
# We just need to add the subcommands to it
# list command
list_parser = skills_subparsers.add_parser(
list_parser = subparsers.add_parser(
'list',
help='List available skills'
)
@@ -275,7 +268,7 @@ def add_skills_parser(subparsers) -> None:
)
# validate command
validate_parser = skills_subparsers.add_parser(
validate_parser = subparsers.add_parser(
'validate',
help='Validate a skill directory'
)
@@ -286,7 +279,7 @@ def add_skills_parser(subparsers) -> None:
)
# create command
create_parser = skills_subparsers.add_parser(
create_parser = subparsers.add_parser(
'create',
help='Create a new skill from template'
)
@@ -306,7 +299,7 @@ def add_skills_parser(subparsers) -> None:
)
# prompt command
prompt_parser = skills_subparsers.add_parser(
prompt_parser = subparsers.add_parser(
'prompt',
help='Generate prompt XML for skills'
)
+19 -2
View File
@@ -613,7 +613,7 @@ class PraisonAI:
return default_args
# Define special commands
special_commands = ['chat', 'code', 'call', 'realtime', 'train', 'ui', 'context', 'research', 'memory', 'rules', 'workflow', 'hooks', 'knowledge', 'session', 'tools', 'todo', 'docs', 'mcp', 'commit', 'serve', 'schedule']
special_commands = ['chat', 'code', 'call', 'realtime', 'train', 'ui', 'context', 'research', 'memory', 'rules', 'workflow', 'hooks', 'knowledge', 'session', 'tools', 'todo', 'docs', 'mcp', 'commit', 'serve', 'schedule', 'skills']
parser = argparse.ArgumentParser(prog="praisonai", description="praisonAI command-line interface")
parser.add_argument("--framework", choices=["crewai", "autogen", "praisonai"], help="Specify the framework")
@@ -814,7 +814,7 @@ class PraisonAI:
except ModuleNotFoundError as e:
missing_module = str(e).split("'")[1]
print(f"[red]ERROR: Missing dependency {missing_module}. Install with:[/red]")
print(f"\npip install \"praisonai[chat]\"\n")
print("\npip install \"praisonai[chat]\"\n")
sys.exit(1)
sys.exit(0)
@@ -1042,6 +1042,23 @@ class PraisonAI:
self.handle_commit_command(unknown_args)
sys.exit(0)
elif args.command == 'skills':
if not PRAISONAI_AVAILABLE:
print("[red]ERROR: PraisonAI Agents is not installed. Install with:[/red]")
print("\npip install praisonaiagents\n")
sys.exit(1)
from .features.skills import handle_skills_command, add_skills_parser
# Create a parser for skills command
skills_parser = argparse.ArgumentParser(prog="praisonai skills")
skills_subparsers = skills_parser.add_subparsers(dest='skills_command', help='Skills commands')
add_skills_parser(skills_subparsers)
skills_args = skills_parser.parse_args(unknown_args)
exit_code = handle_skills_command(skills_args)
sys.exit(exit_code)
# Only check framework availability for agent-related operations
if not args.command and (args.init or args.auto or args.framework):
if not CREWAI_AVAILABLE and not AUTOGEN_AVAILABLE and not PRAISONAI_AVAILABLE:
+1 -1
View File
@@ -57,7 +57,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.3.73 gunicorn markdown\n")
file.write("RUN pip install flask praisonai==2.3.74 gunicorn markdown\n")
file.write("EXPOSE 8080\n")
file.write('CMD ["gunicorn", "-b", "0.0.0.0:8080", "api:app"]\n')
+1 -1
View File
@@ -1 +1 @@
__version__ = "2.3.73"
__version__ = "2.3.74"
+1 -1
View File
@@ -12,7 +12,7 @@ dependencies = [
"rich>=13.7",
"markdown>=3.5",
"pyparsing>=3.0.0",
"praisonaiagents>=0.1.22",
"praisonaiagents>=0.1.23",
"python-dotenv>=0.19.0",
"instructor>=1.3.3",
"PyYAML>=6.0",
+4 -4
View File
@@ -4197,7 +4197,7 @@ requires-dist = [
{ name = "praisonai-tools", marker = "extra == 'autogen'", specifier = ">=0.0.22" },
{ name = "praisonai-tools", marker = "extra == 'autogen-v4'", specifier = ">=0.0.22" },
{ name = "praisonai-tools", marker = "extra == 'crewai'", specifier = ">=0.0.22" },
{ name = "praisonaiagents", specifier = ">=0.1.22" },
{ name = "praisonaiagents", specifier = ">=0.1.23" },
{ name = "pyautogen", marker = "extra == 'autogen'", specifier = "==0.2.29" },
{ name = "pydantic", marker = "extra == 'chat'", specifier = "<=2.10.1" },
{ name = "pydantic", marker = "extra == 'code'", specifier = "<=2.10.1" },
@@ -4252,7 +4252,7 @@ wheels = [
[[package]]
name = "praisonaiagents"
version = "0.1.22"
version = "0.1.23"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "aiohttp" },
@@ -4261,9 +4261,9 @@ dependencies = [
{ name = "pydantic" },
{ name = "rich" },
]
sdist = { url = "https://files.pythonhosted.org/packages/c5/fd/ddc0a0dc7d3d67d49a6e941aa7fbd1fce9c88d27c91f872679b694a3f75a/praisonaiagents-0.1.22.tar.gz", hash = "sha256:673dd4ffc5cc4910642e85da50eb238ae532a179e377fc6d7f0b98a1f8656a54", size = 677941, upload-time = "2025-12-22T15:46:13.8Z" }
sdist = { url = "https://files.pythonhosted.org/packages/79/5e/563a931f0d79f6c64fa8f891ad6eb88cacbbd3f26af5efe52c07a31f11b4/praisonaiagents-0.1.23.tar.gz", hash = "sha256:7a840172892c67feb68e04167db827017d5df8a0e496eb91e309d0e272db60c9", size = 678076, upload-time = "2025-12-22T17:00:28.27Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/47/e0/0008cd7b6c8739abfb754986cec83d10a2e3030deffa39dcc19f7689aa3c/praisonaiagents-0.1.22-py3-none-any.whl", hash = "sha256:9a938116fc9312f12e739b5a9a5a5971cd545082b01512b43af4f30d4d5fec87", size = 616650, upload-time = "2025-12-22T15:46:11.677Z" },
{ url = "https://files.pythonhosted.org/packages/b4/b3/bf02847078595ab1cf109dfd3c7282eaece21f7b879fe96a3ae0d23e8571/praisonaiagents-0.1.23-py3-none-any.whl", hash = "sha256:a455c8fd04fdbd7dd7bf9755c24f19c9c496c404ef60a4fdfc4d4a51decb2e60", size = 616785, upload-time = "2025-12-22T17:00:26.55Z" },
]
[[package]]