Compare commits

...
1 Commits
Author SHA1 Message Date
Mervin Praison 6709ae17e9 Release v4.5.3 2026-02-14 14:24:05 +00:00
14 changed files with 52 additions and 18 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.5.2" \
"praisonai>=4.5.3" \
"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.5.2" \
"praisonai>=4.5.3" \
"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.5.2" \
"praisonai>=4.5.3" \
"praisonai[ui]" \
"praisonai[crewai]"
@@ -72,6 +72,11 @@ class ShellTools:
if cwd:
cwd = os.path.expanduser(cwd)
cwd = os.path.expandvars(cwd) # Also expand $HOME, $USER, etc.
if not os.path.isdir(cwd):
# Fallback: try home directory, then current working directory
fallback = os.path.expanduser("~") if os.path.isdir(os.path.expanduser("~")) else os.getcwd()
logging.warning(f"Working directory '{cwd}' does not exist, using '{fallback}'")
cwd = fallback
# Set up process environment
process_env = os.environ.copy()
+1 -1
View File
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
[project]
name = "praisonaiagents"
version = "1.5.2"
version = "1.5.3"
description = "Praison AI agents for completing complex tasks with Self Reflection Agents"
readme = "README.md"
requires-python = ">=3.10"
+1 -1
View File
@@ -2549,7 +2549,7 @@ wheels = [
[[package]]
name = "praisonaiagents"
version = "1.5.2"
version = "1.5.3"
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.5.2.tar.gz"
sha256 `curl -sL https://github.com/MervinPraison/PraisonAI/archive/refs/tags/v4.5.2.tar.gz | shasum -a 256`.split.first
url "https://github.com/MervinPraison/PraisonAI/archive/refs/tags/v4.5.3.tar.gz"
sha256 `curl -sL https://github.com/MervinPraison/PraisonAI/archive/refs/tags/v4.5.3.tar.gz | shasum -a 256`.split.first
license "MIT"
depends_on "[email protected]"
@@ -112,13 +112,19 @@ class WhatsAppWebAdapter:
# ── Suppress noisy Go-backend warnings ─────────────────────
# whatsmeow emits non-actionable warnings (websocket EOF on
# close, LTHash mismatches during state sync, duplicate
# contacts, missing MAC values). These are protocol-level
# quirks, not bugs in our code — suppress to reduce noise.
# contacts, missing MAC values, decryption failures for old
# keys). These are protocol-level quirks, not bugs in our
# code — suppress to reduce noise.
_known_noise = (
"failed to close WebSocket",
"Error sending close to websocket",
"duplicate contacts found",
"mismatching LTHash",
"missing value MAC",
"failed to decrypt prekey message",
"failed to decrypt group message",
"received message with old counter",
"failed to read frame header",
)
class _WhatsmeowNoiseFilter(logging.Filter):
@@ -126,9 +132,13 @@ class WhatsAppWebAdapter:
msg = record.getMessage()
return not any(pat in msg for pat in _known_noise)
for _logger_name in ("whatsmeow.Client", "whatsmeow.Database", "whatsmeow"):
# Apply to the root "whatsmeow" logger so ALL child loggers
# (whatsmeow.Client, whatsmeow.Database, etc.) inherit it.
# Also apply to neonize's own log module logger.
_noise_filter = _WhatsmeowNoiseFilter()
for _logger_name in ("whatsmeow", "neonize.utils.log"):
_wm_logger = logging.getLogger(_logger_name)
_wm_logger.addFilter(_WhatsmeowNoiseFilter())
_wm_logger.addFilter(_noise_filter)
# ── Critical: bridge neonize's event loop to ours ──────────
# neonize creates event_global_loop = asyncio.new_event_loop()
+9
View File
@@ -457,10 +457,19 @@ class WhatsAppBot(ChatCommandMixin, MessageHookMixin):
await asyncio.sleep(1)
except asyncio.CancelledError:
pass
except KeyboardInterrupt:
pass
except Exception as e:
logger.error(f"WhatsApp Web mode error: {e}")
raise
finally:
# Graceful shutdown: stop the neonize log worker thread to
# prevent "threading._shutdown" errors on Ctrl+C.
try:
from neonize.utils.log import shutdown_log_worker
shutdown_log_worker()
except Exception:
pass
await self.stop()
async def _web_send(self, to: Any, text: str) -> None:
@@ -286,6 +286,9 @@ def bot_whatsapp(
auto_tts: bool = typer.Option(False, "--auto-tts", help="Auto-convert all responses to speech"),
stt: bool = typer.Option(False, "--stt", help="Enable STT tool for speech-to-text"),
stt_model: Optional[str] = typer.Option(None, "--stt-model", help="STT model (default: openai/whisper-1)"),
respond_to: Optional[str] = typer.Option(None, "--respond-to", help="Comma-separated phone numbers the bot responds to (besides self)"),
respond_to_groups: Optional[str] = typer.Option(None, "--respond-to-groups", help="Comma-separated group JIDs the bot responds in"),
respond_to_all: bool = typer.Option(False, "--respond-to-all", help="Respond to ALL messages (default: self-only)"),
):
"""Start a WhatsApp bot with full agent capabilities.
@@ -328,6 +331,10 @@ def bot_whatsapp(
user_id=user_id,
)
# Parse comma-separated filtering values
allowed_numbers = [n.strip() for n in respond_to.split(",") if n.strip()] if respond_to else None
allowed_groups = [g.strip() for g in respond_to_groups.split(",") if g.strip()] if respond_to_groups else None
handler = BotHandler()
handler.start_whatsapp(
token=token,
@@ -338,6 +345,9 @@ def bot_whatsapp(
capabilities=capabilities,
mode=mode,
creds_dir=creds_dir,
allowed_numbers=allowed_numbers,
allowed_groups=allowed_groups,
respond_to_all=respond_to_all,
)
+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.5.2 gunicorn markdown\n")
file.write("RUN pip install flask praisonai==4.5.3 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.5.2"
__version__ = "4.5.3"
+1 -1
View File
@@ -12,7 +12,7 @@ dependencies = [
"rich>=13.7",
"markdown>=3.5",
"pyparsing>=3.0.0",
"praisonaiagents>=1.5.2",
"praisonaiagents>=1.5.3",
"python-dotenv>=0.19.0",
"litellm>=1.81.0",
"PyYAML>=6.0",
+4 -4
View File
@@ -4016,7 +4016,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.5.2" },
{ name = "praisonaiagents", specifier = ">=1.5.3" },
{ name = "pyautogen", marker = "extra == 'autogen'", specifier = "==0.2.29" },
{ name = "pyjwt", marker = "extra == 'os'", specifier = ">=2.8.0" },
{ name = "pyngrok", marker = "extra == 'call'", specifier = ">=1.4.0" },
@@ -4074,7 +4074,7 @@ wheels = [
[[package]]
name = "praisonaiagents"
version = "1.5.2"
version = "1.5.3"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "aiohttp" },
@@ -4083,9 +4083,9 @@ dependencies = [
{ name = "pydantic" },
{ name = "rich" },
]
sdist = { url = "https://files.pythonhosted.org/packages/f1/b4/1a2f31d403d122eed660d0eb672f6867560f4922cb08320a56e9fa9ebfa8/praisonaiagents-1.5.2.tar.gz", hash = "sha256:47023e4a47099972c8e52d6effc1731add07a50dc6fdf33f7d13584a7580c04e", size = 1202584, upload-time = "2026-02-14T00:05:51.824Z" }
sdist = { url = "https://files.pythonhosted.org/packages/93/54/3c78653c55919175f133bad97da1769c97315b65cb859a654185570a4fed/praisonaiagents-1.5.3.tar.gz", hash = "sha256:9210d987e30f6ddb05d04712d7f9015922e3ec2be4e4ccda6876204473b1ecce", size = 1202707, upload-time = "2026-02-14T14:21:26.837Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/b9/fa/dac2e479897a41f9706f84efc1df7687f8ef9dee6582a5298346cd0dbaf3/praisonaiagents-1.5.2-py3-none-any.whl", hash = "sha256:4e4ee5dc268727850f85fece9749e300d3af421dbc07900a8310f95f5d4ee245", size = 1201020, upload-time = "2026-02-14T00:05:49.544Z" },
{ url = "https://files.pythonhosted.org/packages/ab/e6/f93bff2064ca59044656d379fc7240ca9311e553a818daa851c95848dea7/praisonaiagents-1.5.3-py3-none-any.whl", hash = "sha256:72d4ac3d3ba99a78ba28e327b9b94a250ad14e412fa0bac613983b669b2efe12", size = 1201132, upload-time = "2026-02-14T14:21:25.065Z" },
]
[[package]]