Skip to content

Commit cc719e5

Browse files
committed
Release v4.5.22
1 parent e854a50 commit cc719e5

File tree

17 files changed

+636
-542
lines changed

17 files changed

+636
-542
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.21" \
19+
"praisonai>=4.5.22" \
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.21" \
23+
"praisonai>=4.5.22" \
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.21" \
19+
"praisonai>=4.5.22" \
2020
"praisonai[ui]" \
2121
"praisonai[crewai]"
2222

src/praisonai-agents/praisonaiagents/agent/agent.py

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5166,7 +5166,9 @@ def _chat_completion(self, messages, temperature=1.0, tools=None, stream=True, r
51665166
"display_fn": self._display_generating if self.verbose else None,
51675167
"reasoning_steps": reasoning_steps,
51685168
"verbose": self.verbose,
5169-
"max_iterations": 10
5169+
"max_iterations": 10,
5170+
"stream_callback": self.stream_emitter.emit,
5171+
"emit_events": True,
51705172
}
51715173
if response_format:
51725174
chat_kwargs["response_format"] = response_format
@@ -7419,11 +7421,31 @@ def _start_stream(self, prompt: str, **kwargs) -> Generator[str, None, None]:
74197421
if formatted_tools:
74207422
completion_args["tools"] = formatted_tools
74217423

7424+
# Import StreamEvent types for event emission
7425+
from ..streaming.events import StreamEvent, StreamEventType
7426+
import time as time_module
7427+
7428+
# Emit REQUEST_START event
7429+
request_start_perf = time_module.perf_counter()
7430+
self.stream_emitter.emit(StreamEvent(
7431+
type=StreamEventType.REQUEST_START,
7432+
timestamp=request_start_perf,
7433+
metadata={"model": self.llm, "message_count": len(messages)}
7434+
))
7435+
74227436
completion = self._openai_client.sync_client.chat.completions.create(**completion_args)
74237437

7438+
# Emit HEADERS_RECEIVED event
7439+
self.stream_emitter.emit(StreamEvent(
7440+
type=StreamEventType.HEADERS_RECEIVED,
7441+
timestamp=time_module.perf_counter()
7442+
))
7443+
74247444
# Stream the response chunks without display
74257445
response_text = ""
74267446
tool_calls_data = []
7447+
first_token_emitted = False
7448+
last_content_time = None
74277449

74287450
for chunk in completion:
74297451
delta = chunk.choices[0].delta
@@ -7432,6 +7454,24 @@ def _start_stream(self, prompt: str, **kwargs) -> Generator[str, None, None]:
74327454
if delta.content is not None:
74337455
chunk_content = delta.content
74347456
response_text += chunk_content
7457+
last_content_time = time_module.perf_counter()
7458+
7459+
# Emit FIRST_TOKEN on first content
7460+
if not first_token_emitted:
7461+
self.stream_emitter.emit(StreamEvent(
7462+
type=StreamEventType.FIRST_TOKEN,
7463+
timestamp=last_content_time,
7464+
content=chunk_content
7465+
))
7466+
first_token_emitted = True
7467+
else:
7468+
# Emit DELTA_TEXT for subsequent tokens
7469+
self.stream_emitter.emit(StreamEvent(
7470+
type=StreamEventType.DELTA_TEXT,
7471+
timestamp=last_content_time,
7472+
content=chunk_content
7473+
))
7474+
74357475
yield chunk_content
74367476

74377477
# Handle tool calls (accumulate but don't yield as chunks)
@@ -7449,6 +7489,18 @@ def _start_stream(self, prompt: str, **kwargs) -> Generator[str, None, None]:
74497489
if tool_call_delta.function.arguments:
74507490
tool_calls_data[tool_call_delta.index]['function']['arguments'] += tool_call_delta.function.arguments
74517491

7492+
# Emit LAST_TOKEN and STREAM_END events after streaming loop
7493+
if last_content_time:
7494+
self.stream_emitter.emit(StreamEvent(
7495+
type=StreamEventType.LAST_TOKEN,
7496+
timestamp=last_content_time
7497+
))
7498+
self.stream_emitter.emit(StreamEvent(
7499+
type=StreamEventType.STREAM_END,
7500+
timestamp=time_module.perf_counter(),
7501+
metadata={"response_length": len(response_text)}
7502+
))
7503+
74527504
# Handle any tool calls that were accumulated
74537505
if tool_calls_data:
74547506
# Add assistant message with tool calls to chat history

src/praisonai-agents/praisonaiagents/llm/openai_client.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1156,6 +1156,8 @@ def chat_completion_with_tools(
11561156
reasoning_steps: bool = False,
11571157
verbose: bool = True,
11581158
max_iterations: int = 10,
1159+
stream_callback: Optional[Callable] = None,
1160+
emit_events: bool = False,
11591161
**kwargs
11601162
) -> Optional[ChatCompletion]:
11611163
"""
@@ -1179,6 +1181,8 @@ def chat_completion_with_tools(
11791181
reasoning_steps: Whether to show reasoning
11801182
verbose: Whether to show verbose output
11811183
max_iterations: Maximum tool calling iterations
1184+
stream_callback: Optional callback for StreamEvent emission
1185+
emit_events: Whether to emit StreamEvents (requires stream_callback)
11821186
**kwargs: Additional API parameters
11831187
11841188
Returns:
@@ -1208,6 +1212,8 @@ def chat_completion_with_tools(
12081212
console=console,
12091213
display_fn=display_fn,
12101214
reasoning_steps=reasoning_steps,
1215+
stream_callback=stream_callback,
1216+
emit_events=emit_events,
12111217
**kwargs
12121218
)
12131219
else:
@@ -1377,6 +1383,8 @@ async def achat_completion_with_tools(
13771383
reasoning_steps: bool = False,
13781384
verbose: bool = True,
13791385
max_iterations: int = 10,
1386+
stream_callback: Optional[Callable] = None,
1387+
emit_events: bool = False,
13801388
**kwargs
13811389
) -> Optional[ChatCompletion]:
13821390
"""
@@ -1394,6 +1402,8 @@ async def achat_completion_with_tools(
13941402
reasoning_steps: Whether to show reasoning
13951403
verbose: Whether to show verbose output
13961404
max_iterations: Maximum tool calling iterations
1405+
stream_callback: Optional callback for StreamEvent emission (can be sync or async)
1406+
emit_events: Whether to emit StreamEvents (requires stream_callback)
13971407
**kwargs: Additional API parameters
13981408
13991409
Returns:
@@ -1419,6 +1429,8 @@ async def achat_completion_with_tools(
14191429
console=console,
14201430
display_fn=display_fn,
14211431
reasoning_steps=reasoning_steps,
1432+
stream_callback=stream_callback,
1433+
emit_events=emit_events,
14221434
**kwargs
14231435
)
14241436
else:

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

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,15 @@
4949
"disable_trace_output",
5050
"is_trace_output_enabled",
5151
"get_trace_output",
52+
# Editor output (for editor preset - beginner-friendly numbered steps)
53+
"EditorOutput",
54+
"enable_editor_output",
55+
"disable_editor_output",
56+
"is_editor_output_enabled",
57+
"get_editor_output",
58+
"TOOL_LABELS",
59+
"BlockType",
60+
"DisplayBlock",
5261
]
5362

5463

@@ -112,4 +121,37 @@ def __getattr__(name: str):
112121
from .trace import get_trace_output
113122
return get_trace_output
114123

124+
# Editor output (for editor preset - beginner-friendly numbered steps)
125+
if name == "EditorOutput":
126+
from .editor import EditorOutput
127+
return EditorOutput
128+
129+
if name == "enable_editor_output":
130+
from .editor import enable_editor_output
131+
return enable_editor_output
132+
133+
if name == "disable_editor_output":
134+
from .editor import disable_editor_output
135+
return disable_editor_output
136+
137+
if name == "is_editor_output_enabled":
138+
from .editor import is_editor_output_enabled
139+
return is_editor_output_enabled
140+
141+
if name == "get_editor_output":
142+
from .editor import get_editor_output
143+
return get_editor_output
144+
145+
if name == "TOOL_LABELS":
146+
from .editor import TOOL_LABELS
147+
return TOOL_LABELS
148+
149+
if name == "BlockType":
150+
from .editor import BlockType
151+
return BlockType
152+
153+
if name == "DisplayBlock":
154+
from .editor import DisplayBlock
155+
return DisplayBlock
156+
115157
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")

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.21"
7+
version = "1.5.22"
88
description = "Praison AI agents for completing complex tasks with Self Reflection Agents"
99
readme = "README.md"
1010
requires-python = ">=3.10"

0 commit comments

Comments
 (0)