fix(agent): refine status output and CLI rendering

Keep status output responsive while estimating current context from session history, dropping low-value queue/subagent counters, and marking command-style replies for plain-text rendering in CLI. Also route direct CLI calls through outbound metadata so help/status formatting stays explicit instead of relying on content heuristics.

Made-with: Cursor
This commit is contained in:
Xubin Ren
2026-03-21 15:52:10 +00:00
parent 4d1897609d
commit e430b1daf5
4 changed files with 142 additions and 24 deletions
+40 -10
View File
@@ -131,17 +131,30 @@ def _render_interactive_ansi(render_fn) -> str:
return capture.get()
def _print_agent_response(response: str, render_markdown: bool) -> None:
def _print_agent_response(
response: str,
render_markdown: bool,
metadata: dict | None = None,
) -> None:
"""Render assistant response with consistent terminal styling."""
console = _make_console()
content = response or ""
body = Markdown(content) if render_markdown else Text(content)
body = _response_renderable(content, render_markdown, metadata)
console.print()
console.print(f"[cyan]{__logo__} nanobot[/cyan]")
console.print(body)
console.print()
def _response_renderable(content: str, render_markdown: bool, metadata: dict | None = None):
"""Render plain-text command output without markdown collapsing newlines."""
if not render_markdown:
return Text(content)
if (metadata or {}).get("render_as") == "text":
return Text(content)
return Markdown(content)
async def _print_interactive_line(text: str) -> None:
"""Print async interactive updates with prompt_toolkit-safe Rich styling."""
def _write() -> None:
@@ -153,7 +166,11 @@ async def _print_interactive_line(text: str) -> None:
await run_in_terminal(_write)
async def _print_interactive_response(response: str, render_markdown: bool) -> None:
async def _print_interactive_response(
response: str,
render_markdown: bool,
metadata: dict | None = None,
) -> None:
"""Print async interactive replies with prompt_toolkit-safe Rich styling."""
def _write() -> None:
content = response or ""
@@ -161,7 +178,7 @@ async def _print_interactive_response(response: str, render_markdown: bool) -> N
lambda c: (
c.print(),
c.print(f"[cyan]{__logo__} nanobot[/cyan]"),
c.print(Markdown(content) if render_markdown else Text(content)),
c.print(_response_renderable(content, render_markdown, metadata)),
c.print(),
)
)
@@ -750,9 +767,17 @@ def agent(
nonlocal _thinking
_thinking = _ThinkingSpinner(enabled=not logs)
with _thinking:
response = await agent_loop.process_direct(message, session_id, on_progress=_cli_progress)
response = await agent_loop.process_direct_outbound(
message,
session_id,
on_progress=_cli_progress,
)
_thinking = None
_print_agent_response(response, render_markdown=markdown)
_print_agent_response(
response.content if response else "",
render_markdown=markdown,
metadata=response.metadata if response else None,
)
await agent_loop.close_mcp()
asyncio.run(run_once())
@@ -787,7 +812,7 @@ def agent(
bus_task = asyncio.create_task(agent_loop.run())
turn_done = asyncio.Event()
turn_done.set()
turn_response: list[str] = []
turn_response: list[tuple[str, dict]] = []
async def _consume_outbound():
while True:
@@ -805,10 +830,14 @@ def agent(
elif not turn_done.is_set():
if msg.content:
turn_response.append(msg.content)
turn_response.append((msg.content, dict(msg.metadata or {})))
turn_done.set()
elif msg.content:
await _print_interactive_response(msg.content, render_markdown=markdown)
await _print_interactive_response(
msg.content,
render_markdown=markdown,
metadata=msg.metadata,
)
except asyncio.TimeoutError:
continue
@@ -848,7 +877,8 @@ def agent(
_thinking = None
if turn_response:
_print_agent_response(turn_response[0], render_markdown=markdown)
content, meta = turn_response[0]
_print_agent_response(content, render_markdown=markdown, metadata=meta)
except KeyboardInterrupt:
_restore_terminal()
console.print("\nGoodbye!")