feat(agent): add streaming groundwork for future TUI
Preserve the provider and agent-loop streaming primitives plus the CLI experiment scaffolding so this work can be resumed later without blocking urgent bug fixes on main. Made-with: Cursor
This commit is contained in:
+26
-13
@@ -207,6 +207,10 @@ class _ThinkingSpinner:
|
||||
self._active = False
|
||||
if self._spinner:
|
||||
self._spinner.stop()
|
||||
# Force-clear the spinner line: Rich Live's transient cleanup
|
||||
# occasionally loses a race with its own render thread.
|
||||
console.file.write("\033[2K\r")
|
||||
console.file.flush()
|
||||
return False
|
||||
|
||||
@contextmanager
|
||||
@@ -214,6 +218,8 @@ class _ThinkingSpinner:
|
||||
"""Temporarily stop spinner while printing progress."""
|
||||
if self._spinner and self._active:
|
||||
self._spinner.stop()
|
||||
console.file.write("\033[2K\r")
|
||||
console.file.flush()
|
||||
try:
|
||||
yield
|
||||
finally:
|
||||
@@ -770,16 +776,25 @@ def agent(
|
||||
async def run_once():
|
||||
nonlocal _thinking
|
||||
_thinking = _ThinkingSpinner(enabled=not logs)
|
||||
with _thinking:
|
||||
|
||||
with _thinking or nullcontext():
|
||||
response = await agent_loop.process_direct(
|
||||
message, session_id, on_progress=_cli_progress,
|
||||
message, session_id,
|
||||
on_progress=_cli_progress,
|
||||
)
|
||||
_thinking = None
|
||||
_print_agent_response(
|
||||
response.content if response else "",
|
||||
render_markdown=markdown,
|
||||
metadata=response.metadata if response else None,
|
||||
)
|
||||
|
||||
if _thinking:
|
||||
_thinking.__exit__(None, None, None)
|
||||
_thinking = None
|
||||
|
||||
if response and response.content:
|
||||
_print_agent_response(
|
||||
response.content,
|
||||
render_markdown=markdown,
|
||||
metadata=response.metadata,
|
||||
)
|
||||
else:
|
||||
console.print()
|
||||
await agent_loop.close_mcp()
|
||||
|
||||
asyncio.run(run_once())
|
||||
@@ -820,6 +835,7 @@ def agent(
|
||||
while True:
|
||||
try:
|
||||
msg = await asyncio.wait_for(bus.consume_outbound(), timeout=1.0)
|
||||
|
||||
if msg.metadata.get("_progress"):
|
||||
is_tool_hint = msg.metadata.get("_tool_hint", False)
|
||||
ch = agent_loop.channels_config
|
||||
@@ -834,6 +850,7 @@ def agent(
|
||||
if msg.content:
|
||||
turn_response.append((msg.content, dict(msg.metadata or {})))
|
||||
turn_done.set()
|
||||
|
||||
elif msg.content:
|
||||
await _print_interactive_response(
|
||||
msg.content,
|
||||
@@ -872,11 +889,7 @@ def agent(
|
||||
content=user_input,
|
||||
))
|
||||
|
||||
nonlocal _thinking
|
||||
_thinking = _ThinkingSpinner(enabled=not logs)
|
||||
with _thinking:
|
||||
await turn_done.wait()
|
||||
_thinking = None
|
||||
await turn_done.wait()
|
||||
|
||||
if turn_response:
|
||||
content, meta = turn_response[0]
|
||||
|
||||
Reference in New Issue
Block a user