Skip to content

Commit 0379e9f

Browse files
committed
Release v4.5.38
1 parent c841d46 commit 0379e9f

File tree

19 files changed

+629
-27
lines changed

19 files changed

+629
-27
lines changed

docker/Dockerfile.chat

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ RUN mkdir -p /root/.praison
1616
# Install Python packages (using latest versions)
1717
RUN pip install --no-cache-dir \
1818
praisonai_tools \
19-
"praisonai>=4.5.37" \
19+
"praisonai>=4.5.38" \
2020
"praisonai[chat]" \
2121
"embedchain[github,youtube]"
2222

docker/Dockerfile.dev

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ RUN mkdir -p /root/.praison
2020
# Install Python packages (using latest versions)
2121
RUN pip install --no-cache-dir \
2222
praisonai_tools \
23-
"praisonai>=4.5.37" \
23+
"praisonai>=4.5.38" \
2424
"praisonai[ui]" \
2525
"praisonai[chat]" \
2626
"praisonai[realtime]" \

docker/Dockerfile.ui

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ RUN mkdir -p /root/.praison
1616
# Install Python packages (using latest versions)
1717
RUN pip install --no-cache-dir \
1818
praisonai_tools \
19-
"praisonai>=4.5.37" \
19+
"praisonai>=4.5.38" \
2020
"praisonai[ui]" \
2121
"praisonai[crewai]"
2222

src/praisonai-agents/praisonaiagents/guardrails/llm_guardrail.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,16 +67,22 @@ def _get_llm_class():
6767
self.logger.warning(f"Unknown LLM type: {type(llm)}, treating as-is")
6868
return llm
6969

70-
def __call__(self, task_output: TaskOutput) -> Tuple[bool, Union[str, TaskOutput]]:
70+
def __call__(self, task_output) -> Tuple[bool, Union[str, "TaskOutput"]]:
7171
"""Validate the task output using the LLM.
7272
7373
Args:
74-
task_output: The task output to validate
74+
task_output: The task output to validate (TaskOutput or plain str)
7575
7676
Returns:
7777
Tuple of (success, result) where result is the output or error message
7878
"""
7979
try:
80+
# Accept plain str for convenience (e.g. chat-input screening)
81+
if isinstance(task_output, str):
82+
raw_text = task_output
83+
else:
84+
raw_text = task_output.raw
85+
8086
if not self.llm:
8187
self.logger.warning("No LLM provided for guardrail validation")
8288
return True, task_output
@@ -88,7 +94,7 @@ def __call__(self, task_output: TaskOutput) -> Tuple[bool, Union[str, TaskOutput
8894
Validation Criteria: {self.description}
8995
9096
Output to Validate:
91-
{task_output.raw}
97+
{raw_text}
9298
9399
Please evaluate if this output meets the criteria. Respond with:
94100
1. "PASS" if the output meets all criteria

src/praisonai-agents/praisonaiagents/scheduler/__init__.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
from typing import TYPE_CHECKING
2121

2222
if TYPE_CHECKING:
23-
from .models import Schedule, ScheduleJob
23+
from .models import Schedule, ScheduleJob, DeliveryTarget
2424
from .store import FileScheduleStore
2525
from .parser import parse_schedule
2626
from .runner import ScheduleRunner
@@ -33,10 +33,11 @@ def __getattr__(name: str):
3333
if name in _module_cache:
3434
return _module_cache[name]
3535

36-
if name in ("Schedule", "ScheduleJob"):
37-
from .models import Schedule, ScheduleJob
36+
if name in ("Schedule", "ScheduleJob", "DeliveryTarget"):
37+
from .models import Schedule, ScheduleJob, DeliveryTarget
3838
_module_cache["Schedule"] = Schedule
3939
_module_cache["ScheduleJob"] = ScheduleJob
40+
_module_cache["DeliveryTarget"] = DeliveryTarget
4041
return _module_cache[name]
4142

4243
if name == "FileScheduleStore":
@@ -60,6 +61,7 @@ def __getattr__(name: str):
6061
__all__ = [
6162
"Schedule",
6263
"ScheduleJob",
64+
"DeliveryTarget",
6365
"FileScheduleStore",
6466
"parse_schedule",
6567
"ScheduleRunner",

src/praisonai-agents/praisonaiagents/scheduler/models.py

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,39 @@ def from_dict(cls, d: Dict[str, Any]) -> "Schedule":
5151
)
5252

5353

54+
@dataclass
55+
class DeliveryTarget:
56+
"""Where to deliver the result when a scheduled job fires.
57+
58+
Attributes:
59+
channel: Platform name (``"telegram"``, ``"discord"``,
60+
``"slack"``, ``"whatsapp"``).
61+
channel_id: Platform-specific chat / channel / group ID.
62+
thread_id: Optional thread ID for threaded delivery.
63+
"""
64+
65+
channel: str = ""
66+
channel_id: str = ""
67+
thread_id: Optional[str] = None
68+
69+
def to_dict(self) -> Dict[str, Any]:
70+
d: Dict[str, Any] = {
71+
"channel": self.channel,
72+
"channel_id": self.channel_id,
73+
}
74+
if self.thread_id is not None:
75+
d["thread_id"] = self.thread_id
76+
return d
77+
78+
@classmethod
79+
def from_dict(cls, d: Dict[str, Any]) -> "DeliveryTarget":
80+
return cls(
81+
channel=d.get("channel", ""),
82+
channel_id=d.get("channel_id", ""),
83+
thread_id=d.get("thread_id"),
84+
)
85+
86+
5487
@dataclass
5588
class ScheduleJob:
5689
"""A persisted scheduled job.
@@ -67,6 +100,8 @@ class ScheduleJob:
67100
delete_after_run: Auto-remove after first execution (one-shot).
68101
created_at: Epoch timestamp.
69102
last_run_at: Epoch timestamp of most recent execution.
103+
delivery: Optional delivery target for routing results back
104+
to a channel bot (e.g. Telegram chat).
70105
"""
71106

72107
name: str = ""
@@ -79,11 +114,12 @@ class ScheduleJob:
79114
delete_after_run: bool = False
80115
created_at: float = field(default_factory=time.time)
81116
last_run_at: Optional[float] = None
117+
delivery: Optional[DeliveryTarget] = None
82118

83119
# ── serialisation ────────────────────────────────────────────────
84120

85121
def to_dict(self) -> Dict[str, Any]:
86-
return {
122+
d: Dict[str, Any] = {
87123
"id": self.id,
88124
"name": self.name,
89125
"schedule": self.schedule.to_dict(),
@@ -95,10 +131,14 @@ def to_dict(self) -> Dict[str, Any]:
95131
"created_at": self.created_at,
96132
"last_run_at": self.last_run_at,
97133
}
134+
if self.delivery is not None:
135+
d["delivery"] = self.delivery.to_dict()
136+
return d
98137

99138
@classmethod
100139
def from_dict(cls, d: Dict[str, Any]) -> "ScheduleJob":
101140
sched_data = d.get("schedule", {})
141+
delivery_data = d.get("delivery")
102142
return cls(
103143
id=d.get("id", uuid.uuid4().hex[:12]),
104144
name=d.get("name", ""),
@@ -110,4 +150,5 @@ def from_dict(cls, d: Dict[str, Any]) -> "ScheduleJob":
110150
delete_after_run=d.get("delete_after_run", False),
111151
created_at=d.get("created_at", time.time()),
112152
last_run_at=d.get("last_run_at"),
153+
delivery=DeliveryTarget.from_dict(delivery_data) if isinstance(delivery_data, dict) else None,
113154
)

src/praisonai-agents/praisonaiagents/tools/schedule_tools.py

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ def schedule_add(
4141
name: str,
4242
schedule: str,
4343
message: str = "",
44+
channel: str = "",
45+
channel_id: str = "",
4446
) -> str:
4547
"""Add a new scheduled job.
4648
@@ -53,16 +55,29 @@ def schedule_add(
5355
- "at:2026-03-01T09:00:00" (one-shot ISO timestamp)
5456
- "in 20 minutes" (relative one-shot)
5557
message: The prompt or reminder text to deliver when triggered.
58+
channel: Delivery platform ("telegram", "discord", "slack",
59+
"whatsapp"). If set with channel_id, the result will
60+
be sent back to that chat when the job fires.
61+
channel_id: Target chat/channel/group ID on the platform.
5662
5763
Returns:
5864
Confirmation string with the job id.
5965
"""
6066
try:
6167
from ..scheduler.parser import parse_schedule
62-
from ..scheduler.models import ScheduleJob
68+
from ..scheduler.models import ScheduleJob, DeliveryTarget
6369

6470
sched = parse_schedule(schedule)
65-
job = ScheduleJob(name=name, schedule=sched, message=message)
71+
72+
delivery = None
73+
if channel and channel_id:
74+
delivery = DeliveryTarget(
75+
channel=channel, channel_id=channel_id,
76+
)
77+
78+
job = ScheduleJob(
79+
name=name, schedule=sched, message=message, delivery=delivery,
80+
)
6681

6782
store = _get_store()
6883

@@ -72,7 +87,8 @@ def schedule_add(
7287
return f"A schedule named '{name}' already exists (id: {existing.id}). Remove it first or choose a different name."
7388

7489
store.add(job)
75-
return f"Schedule '{name}' added (id: {job.id}, {schedule})."
90+
delivery_note = f" → deliver to {channel}:{channel_id}" if delivery else ""
91+
return f"Schedule '{name}' added (id: {job.id}, {schedule}{delivery_note})."
7692
except ValueError as e:
7793
return f"Error adding schedule: {e}"
7894
except Exception as e:

src/praisonai-agents/pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
44

55
[project]
66
name = "praisonaiagents"
7-
version = "1.5.37"
7+
version = "1.5.38"
88
description = "Praison AI agents for completing complex tasks with Self Reflection Agents"
99
readme = "README.md"
1010
requires-python = ">=3.10"

src/praisonai-agents/uv.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/praisonai/praisonai.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ class Praisonai < Formula
33

44
desc "AI tools for various AI applications"
55
homepage "https://github.com/MervinPraison/PraisonAI"
6-
url "https://github.com/MervinPraison/PraisonAI/archive/refs/tags/v4.5.37.tar.gz"
7-
sha256 `curl -sL https://github.com/MervinPraison/PraisonAI/archive/refs/tags/v4.5.37.tar.gz | shasum -a 256`.split.first
6+
url "https://github.com/MervinPraison/PraisonAI/archive/refs/tags/v4.5.38.tar.gz"
7+
sha256 `curl -sL https://github.com/MervinPraison/PraisonAI/archive/refs/tags/v4.5.38.tar.gz | shasum -a 256`.split.first
88
license "MIT"
99

1010
depends_on "python@3.11"

0 commit comments

Comments
 (0)