mirror of
https://github.com/NCBM/plyngent.git
synced 2026-07-23 22:44:59 +08:00
core/cli: update display and state for streaming, error, cancel events
This commit is contained in:
@@ -5,6 +5,8 @@ from typing import TYPE_CHECKING
|
||||
import click
|
||||
|
||||
from plyngent.agent import (
|
||||
CancelledEvent,
|
||||
ErrorEvent,
|
||||
MaxRoundsEvent,
|
||||
TextDeltaEvent,
|
||||
ToolCallEvent,
|
||||
@@ -20,7 +22,7 @@ if TYPE_CHECKING:
|
||||
_TOOL_RESULT_PREVIEW = 200
|
||||
|
||||
|
||||
async def render_events(events: AsyncIterator[AgentEvent]) -> None:
|
||||
async def render_events(events: AsyncIterator[AgentEvent]) -> None: # noqa: C901, PLR0912
|
||||
"""Print agent events to the terminal."""
|
||||
printed_text = False
|
||||
async for event in events:
|
||||
@@ -47,6 +49,10 @@ async def render_events(events: AsyncIterator[AgentEvent]) -> None:
|
||||
else content[:_TOOL_RESULT_PREVIEW] + "…"
|
||||
)
|
||||
click.secho(f"[tool result] {preview}", fg="magenta")
|
||||
elif isinstance(event, ErrorEvent):
|
||||
click.secho(f"\n[error] {event.message}", fg="bright_red")
|
||||
elif isinstance(event, CancelledEvent):
|
||||
click.secho("\n[cancelled]", fg="yellow")
|
||||
elif isinstance(event, MaxRoundsEvent):
|
||||
if event.continued:
|
||||
click.secho(
|
||||
@@ -60,5 +66,5 @@ async def render_events(events: AsyncIterator[AgentEvent]) -> None:
|
||||
_ = event
|
||||
if printed_text:
|
||||
click.echo()
|
||||
# Blank line before the next readline prompt so log and input are not jammed.
|
||||
click.echo()
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ class ReplState:
|
||||
|
||||
def __post_init__(self) -> None:
|
||||
# DeepSeek client uses a compatible but distinct param type; treat as ChatClient.
|
||||
self.client = cast("ChatClient", create_client(self.provider))
|
||||
self.client = cast("ChatClient", cast("object", create_client(self.provider)))
|
||||
self.agent = self._make_agent()
|
||||
|
||||
def _tool_registry(self) -> ToolRegistry | None:
|
||||
@@ -53,12 +53,13 @@ class ReplState:
|
||||
session_id=self.session_id,
|
||||
max_rounds=self.max_rounds,
|
||||
on_limit=prompt_continue_limit,
|
||||
stream=True,
|
||||
)
|
||||
|
||||
def rebuild_client(self) -> None:
|
||||
"""Recreate client and agent after provider/model/tools change."""
|
||||
messages = list(self.agent.messages)
|
||||
self.client = cast("ChatClient", create_client(self.provider))
|
||||
self.client = cast("ChatClient", cast("object", create_client(self.provider)))
|
||||
self.agent = self._make_agent()
|
||||
self.agent.messages = messages
|
||||
|
||||
|
||||
@@ -96,10 +96,10 @@ async def test_run_chat_loop_text_only() -> None:
|
||||
]
|
||||
)
|
||||
messages: list[AnyChatMessage] = [UserChatMessage(content="hi")]
|
||||
events = [e async for e in run_chat_loop(client, messages, model="m")]
|
||||
assert isinstance(events[0], AssistantMessageEvent)
|
||||
assert isinstance(events[1], TextDeltaEvent)
|
||||
assert events[1].content == "hello"
|
||||
events = [e async for e in run_chat_loop(client, messages, model="m", stream=False)]
|
||||
assert isinstance(events[0], TextDeltaEvent)
|
||||
assert events[0].content == "hello"
|
||||
assert isinstance(events[1], AssistantMessageEvent)
|
||||
assert len(messages) == 2 # noqa: PLR2004
|
||||
assert len(client.calls) == 1
|
||||
|
||||
|
||||
Reference in New Issue
Block a user