Compare commits

...
3 Commits
Author SHA1 Message Date
Mervin Praison 9df792b218 Release v4.2.4 2026-02-01 06:26:04 +00:00
Mervin Praison 0526cdc528 Add when and If to top-level exports for friendly imports 2026-02-01 06:19:33 +00:00
Mervin Praison e6f3438cfa Release v4.2.3 2026-01-31 22:18:09 +00:00
13 changed files with 150 additions and 14 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>=4.2.2" \
"praisonai>=4.2.4" \
"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>=4.2.2" \
"praisonai>=4.2.4" \
"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>=4.2.2" \
"praisonai>=4.2.4" \
"praisonai[ui]" \
"praisonai[crewai]"
@@ -150,10 +150,12 @@ _LAZY_IMPORTS = {
'Parallel': ('praisonaiagents.workflows', 'Parallel'),
'Loop': ('praisonaiagents.workflows', 'Loop'),
'Repeat': ('praisonaiagents.workflows', 'Repeat'),
'If': ('praisonaiagents.workflows', 'If'),
'route': ('praisonaiagents.workflows', 'route'),
'parallel': ('praisonaiagents.workflows', 'parallel'),
'loop': ('praisonaiagents.workflows', 'loop'),
'repeat': ('praisonaiagents.workflows', 'repeat'),
'when': ('praisonaiagents.workflows', 'when'),
# Handoff
'Handoff': ('praisonaiagents.agent.handoff', 'Handoff'),
@@ -16,6 +16,7 @@ from typing import Any, Dict
# =============================================================================
MEMORY_PRESETS: Dict[str, Dict[str, Any]] = {
# Backend presets
"file": {"backend": "file"},
"sqlite": {"backend": "sqlite"},
"redis": {"backend": "redis"},
@@ -23,6 +24,8 @@ MEMORY_PRESETS: Dict[str, Dict[str, Any]] = {
"postgresql": {"backend": "postgres"},
"mem0": {"backend": "mem0"},
"mongodb": {"backend": "mongodb"},
# Feature presets
"learn": {"backend": "file", "learn": True}, # Enable Agent Learn with file backend
}
MEMORY_URL_SCHEMES: Dict[str, str] = {
+1 -1
View File
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
[project]
name = "praisonaiagents"
version = "1.2.2"
version = "1.2.4"
description = "Praison AI agents for completing complex tasks with Self Reflection Agents"
readme = "README.md"
requires-python = ">=3.10"
@@ -0,0 +1,131 @@
"""
Tests for memory="learn" shorthand preset.
Tests that memory="learn" enables Agent Learn functionality with a simple string parameter.
"""
import pytest
class TestMemoryLearnPreset:
"""Test that 'learn' preset exists in MEMORY_PRESETS."""
def test_learn_preset_exists(self):
"""MEMORY_PRESETS should contain 'learn' key."""
from praisonaiagents.config.presets import MEMORY_PRESETS
assert "learn" in MEMORY_PRESETS, "MEMORY_PRESETS should have 'learn' preset"
def test_learn_preset_has_learn_true(self):
"""Learn preset should have learn=True."""
from praisonaiagents.config.presets import MEMORY_PRESETS
preset = MEMORY_PRESETS.get("learn", {})
assert preset.get("learn") is True, "Learn preset should have learn=True"
def test_learn_preset_has_backend(self):
"""Learn preset should have a backend (file by default)."""
from praisonaiagents.config.presets import MEMORY_PRESETS
preset = MEMORY_PRESETS.get("learn", {})
assert "backend" in preset, "Learn preset should have backend"
assert preset["backend"] == "file", "Learn preset should use file backend by default"
class TestMemoryLearnResolution:
"""Test that memory='learn' resolves correctly."""
def test_resolve_memory_learn_string(self):
"""resolve() should convert 'learn' string to MemoryConfig with learn=True."""
from praisonaiagents.config.param_resolver import resolve, ArrayMode
from praisonaiagents.config.presets import MEMORY_PRESETS, MEMORY_URL_SCHEMES
from praisonaiagents.config.feature_configs import MemoryConfig
result = resolve(
value="learn",
param_name="memory",
config_class=MemoryConfig,
presets=MEMORY_PRESETS,
url_schemes=MEMORY_URL_SCHEMES,
array_mode=ArrayMode.SINGLE_OR_LIST,
default=None,
)
assert result is not None, "Should resolve 'learn' to a config"
assert isinstance(result, MemoryConfig), f"Should be MemoryConfig, got {type(result)}"
assert result.learn is True, "MemoryConfig should have learn=True"
def test_memory_config_from_preset_dict(self):
"""MemoryConfig should accept learn field from preset dict."""
from praisonaiagents.config.feature_configs import MemoryConfig
# Simulate what happens when preset is converted to MemoryConfig
preset_dict = {"backend": "file", "learn": True}
config = MemoryConfig(**preset_dict)
assert config.backend == "file"
assert config.learn is True
class TestAgentMemoryLearnShorthand:
"""Test Agent accepts memory='learn' parameter."""
def test_agent_accepts_memory_learn_string(self):
"""Agent should accept memory='learn' without error."""
from praisonaiagents import Agent
# Should not raise
agent = Agent(
instructions="Test agent with learn memory",
memory="learn"
)
assert agent is not None
def test_agent_memory_learn_sets_learn_config(self):
"""Agent with memory='learn' should have memory enabled."""
from praisonaiagents import Agent
agent = Agent(
instructions="Test agent",
memory="learn"
)
# Agent should have memory enabled (truthy value)
assert agent.memory, "Agent.memory should be enabled when using memory='learn'"
class TestMemoryLearnIntegration:
"""Integration tests for memory='learn' with Memory class."""
def test_memory_class_with_learn_config(self):
"""Memory class should initialize LearnManager when learn=True in config."""
from praisonaiagents.memory.memory import Memory
memory = Memory({"provider": "rag", "learn": True, "use_embedding": False})
# Access learn property (lazy-loaded)
learn_manager = memory.learn
assert learn_manager is not None, "Memory.learn should return LearnManager instance"
def test_memory_learn_captures_persona(self):
"""LearnManager should capture persona entries."""
import tempfile
import shutil
from praisonaiagents.memory.memory import Memory
temp_dir = tempfile.mkdtemp()
try:
memory = Memory({
"provider": "rag",
"learn": True,
"use_embedding": False,
"user_id": "test_user"
})
if memory.learn:
entry = memory.learn.capture_persona("User prefers concise responses")
assert entry is not None
finally:
shutil.rmtree(temp_dir, ignore_errors=True)
+1 -1
View File
@@ -2549,7 +2549,7 @@ wheels = [
[[package]]
name = "praisonaiagents"
version = "1.2.2"
version = "1.2.4"
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/v4.2.2.tar.gz"
sha256 `curl -sL https://github.com/MervinPraison/PraisonAI/archive/refs/tags/v4.2.2.tar.gz | shasum -a 256`.split.first
url "https://github.com/MervinPraison/PraisonAI/archive/refs/tags/v4.2.4.tar.gz"
sha256 `curl -sL https://github.com/MervinPraison/PraisonAI/archive/refs/tags/v4.2.4.tar.gz | shasum -a 256`.split.first
license "MIT"
depends_on "[email protected]"
+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==4.2.2 gunicorn markdown\n")
file.write("RUN pip install flask praisonai==4.2.4 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__ = "4.2.2"
__version__ = "4.2.4"
+1 -1
View File
@@ -12,7 +12,7 @@ dependencies = [
"rich>=13.7",
"markdown>=3.5",
"pyparsing>=3.0.0",
"praisonaiagents>=1.2.2",
"praisonaiagents>=1.2.4",
"python-dotenv>=0.19.0",
"litellm>=1.81.0",
"PyYAML>=6.0",
+4 -4
View File
@@ -4047,7 +4047,7 @@ requires-dist = [
{ name = "praisonai-tools", marker = "extra == 'autogen'", specifier = ">=0.1.0" },
{ name = "praisonai-tools", marker = "extra == 'autogen-v4'", specifier = ">=0.1.0" },
{ name = "praisonai-tools", marker = "extra == 'crewai'", specifier = ">=0.1.0" },
{ name = "praisonaiagents", specifier = ">=1.2.2" },
{ name = "praisonaiagents", specifier = ">=1.2.4" },
{ name = "pyautogen", marker = "extra == 'autogen'", specifier = "==0.2.29" },
{ name = "pyngrok", marker = "extra == 'call'", specifier = ">=1.4.0" },
{ name = "pyparsing", specifier = ">=3.0.0" },
@@ -4100,7 +4100,7 @@ wheels = [
[[package]]
name = "praisonaiagents"
version = "1.2.2"
version = "1.2.4"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "aiohttp" },
@@ -4109,9 +4109,9 @@ dependencies = [
{ name = "pydantic" },
{ name = "rich" },
]
sdist = { url = "https://files.pythonhosted.org/packages/a5/fd/dc1591930e10108c04b21de9e620ef0910ad0d7c34ecb1a7616ce0ccc8c7/praisonaiagents-1.2.2.tar.gz", hash = "sha256:c790107dfd278a46c52a0191b77c13900f091fb5a7051195cb1926d9ca19e991", size = 1163165, upload-time = "2026-01-31T20:23:29.288Z" }
sdist = { url = "https://files.pythonhosted.org/packages/f4/59/1a78c3e96abdad3c6cffaf90e5ce2f2a0aaa61ef03a4d6cd3f7708225d33/praisonaiagents-1.2.4.tar.gz", hash = "sha256:5f9a673b28f66a54bde1b2f88497197265adbbf79edee2377f06e39425085ebd", size = 1163266, upload-time = "2026-02-01T06:24:14.499Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/0b/21/406275ba1c6f1d7dcef710c7aa62a6fccb5cafbbb4883a39fe48715837ea/praisonaiagents-1.2.2-py3-none-any.whl", hash = "sha256:8732cdd90526b1fba0feb192c97b8c0b2387eda2827cf89d7d9867cd02aeaad8", size = 1156030, upload-time = "2026-01-31T20:23:27.414Z" },
{ url = "https://files.pythonhosted.org/packages/a9/12/98ed5fdc0235377e2a602f5265073e8c7a53264bd5fa4ff5173cc4de19cf/praisonaiagents-1.2.4-py3-none-any.whl", hash = "sha256:56d912018941c201577bd63e312acf1f39543a51e06f42cf576588b1ccdf29de", size = 1156085, upload-time = "2026-02-01T06:24:12.167Z" },
]
[[package]]