Fix stream ai bug
This commit is contained in:
+1
-1
@@ -1 +1 @@
|
||||
__version__ = "6.0.0b4"
|
||||
__version__ = "6.0.0b5"
|
||||
|
||||
+14
-5
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user