Fix stream ai bug

This commit is contained in:
2026-05-01 23:54:24 -03:00
parent a192bd1912
commit 16868828c6
3 changed files with 59 additions and 16 deletions
+1 -1
View File
@@ -1 +1 @@
__version__ = "6.0.0b4"
__version__ = "6.0.0b5"
+14 -5
View File
@@ -271,7 +271,7 @@ class ai:
raise KeyboardInterrupt
chunk_callback(delta.content)
if not debug and not chunk_callback:
if not chunk_callback:
if not is_streaming_text:
# Stop spinner definitively
if status:
@@ -279,9 +279,15 @@ class ai:
status.stop()
except Exception:
pass
# Create a stable, direct Console to bypass _ConsoleProxy recreation bugs
from rich.console import Console as RichConsole
from .printer import connpy_theme, get_original_stdout
stable_console = RichConsole(theme=connpy_theme, file=get_original_stdout())
live_display = Live(
Panel(Markdown(full_content), title=title, border_style=border, expand=False),
console=self.console,
console=stable_console,
refresh_per_second=8,
transient=False
)
@@ -303,7 +309,10 @@ class ai:
)
except Exception:
pass
try:
live_display.stop()
except Exception:
pass
# Rebuild complete response from chunks
try:
@@ -989,7 +998,7 @@ class ai:
streamed_response = False
try:
safe_messages = self._sanitize_messages(messages)
if stream and chunk_callback:
if stream:
response, streamed_response = self._stream_completion(
model=model, messages=safe_messages, tools=tools, api_key=key,
status=status, label=label, debug=debug, num_retries=3,
@@ -1028,8 +1037,8 @@ class ai:
if msg_dict.get("tool_calls") and msg_dict.get("content") == "": msg_dict["content"] = None
messages.append(msg_dict)
if debug and resp_msg.content:
# In CLI debug mode, only print intermediate reasoning if there are tool calls.
if debug and resp_msg.content and not streamed_response:
# In CLI debug mode, only print intermediate reasoning if there are tool calls AND it wasn't already streamed.
# If there are no tool calls, this content is the final answer and will be printed by the caller.
if resp_msg.tool_calls:
if status:
+42 -8
View File
@@ -604,21 +604,33 @@ class AIStub:
if response.debug_message:
if debug:
if live_display:
try: live_display.stop()
except: pass
if status:
try: status.stop()
except: pass
printer.console.print(Text.from_ansi(response.debug_message))
if status:
if live_display:
try: live_display.start()
except: pass
elif status:
try: status.start()
except: pass
continue
if response.important_message:
if live_display:
try: live_display.stop()
except: pass
if status:
try: status.stop()
except: pass
printer.console.print(Text.from_ansi(response.important_message))
if status:
if live_display:
try: live_display.start()
except: pass
elif status:
try: status.start()
except: pass
continue
@@ -627,14 +639,33 @@ class AIStub:
if response.text_chunk:
full_content += response.text_chunk
if status and not debug:
# Update the spinner line with a preview of the response
preview = full_content.replace("\n", " ").strip()
if len(preview) > 60: preview = preview[:57] + "..."
status.update(f"[ai_status]{preview}")
if not live_display:
if status:
try: status.stop()
except: pass
from rich.console import Console as RichConsole
from ..printer import connpy_theme, get_original_stdout
stable_console = RichConsole(theme=connpy_theme, file=get_original_stdout())
# We default to Engineer title during stream, final result will correct it if needed
live_display = Live(
Panel(Markdown(full_content), title="[bold engineer]Network Engineer[/bold engineer]", border_style="engineer", expand=False),
console=stable_console,
refresh_per_second=8,
transient=False
)
live_display.start()
else:
live_display.update(
Panel(Markdown(full_content), title="[bold engineer]Network Engineer[/bold engineer]", border_style="engineer", expand=False)
)
continue
if response.is_final:
if live_display:
try: live_display.stop()
except: pass
# Final stop for status to ensure it disappears before the panel
if status:
try: status.stop()
@@ -646,9 +677,12 @@ class AIStub:
role_label = "Network Architect" if responder == "architect" else "Network Engineer"
title = f"[bold {alias}]{role_label}[/bold {alias}]"
# Always print the final Panel
content_to_print = full_content or final_result.get("response", "")
if content_to_print:
if live_display:
# Re-render the final frame with correct title/colors
live_display.update(Panel(Markdown(content_to_print), title=title, border_style=alias, expand=False))
else:
printer.console.print(Panel(Markdown(content_to_print), title=title, border_style=alias, expand=False))
break
except Exception as e: