Skip to content

Commit 8af30ae

Browse files
committed
feat: remove option for showing tool calls + prettier tool call output
1 parent 01ecc4c commit 8af30ae

File tree

3 files changed

+27
-22
lines changed

3 files changed

+27
-22
lines changed

pydantic_ai_slim/pydantic_ai/_cli.py

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,6 @@ async def run_chat(
229229
config_dir: Path | None = None,
230230
deps: AgentDepsT = None,
231231
message_history: list[ModelMessage] | None = None,
232-
show_tool_calls: bool = False,
233232
) -> int:
234233
prompt_history_path = (config_dir or PYDANTIC_AI_HOME) / PROMPT_HISTORY_FILENAME
235234
prompt_history_path.parent.mkdir(parents=True, exist_ok=True)
@@ -256,7 +255,7 @@ async def run_chat(
256255
return exit_value
257256
else:
258257
try:
259-
messages = await ask_agent(agent, text, stream, console, code_theme, deps, messages, show_tool_calls)
258+
messages = await ask_agent(agent, text, stream, console, code_theme, deps, messages)
260259
except CancelledError: # pragma: no cover
261260
console.print('[dim]Interrupted[/dim]')
262261
except Exception as e: # pragma: no cover
@@ -274,9 +273,12 @@ async def ask_agent(
274273
code_theme: str,
275274
deps: AgentDepsT = None,
276275
messages: list[ModelMessage] | None = None,
277-
show_tool_calls: bool = False,
278276
) -> list[ModelMessage]:
279-
status = Status('[dim]Working on it…[/dim]', console=console)
277+
MODEL_CALL_STATUS_MSG = '[dim]Calling model…[/dim]'
278+
TOOL_EXECUTION_STATUS_MSG = '[dim]Executing tools…[/dim]'
279+
MAX_TOOL_CALL_RESULT_LEN = 100
280+
MAX_TOOL_CALL_ID_LEN = 5
281+
status = Status(MODEL_CALL_STATUS_MSG, console=console)
280282

281283
if not stream:
282284
with status:
@@ -287,26 +289,40 @@ async def ask_agent(
287289

288290
with status, ExitStack() as stack:
289291
async with agent.iter(prompt, message_history=messages, deps=deps) as agent_run:
290-
live = Live('', refresh_per_second=15, console=console, vertical_overflow='ellipsis')
292+
final_output_live = None
291293
async for node in agent_run:
292294
if Agent.is_model_request_node(node):
295+
status.update(MODEL_CALL_STATUS_MSG)
293296
async with node.stream(agent_run.ctx) as handle_stream:
294297
status.stop() # stopping multiple times is idempotent
295-
stack.enter_context(live) # entering multiple times is idempotent
296298

297299
async for content in handle_stream.stream_output(debounce_by=None):
298-
live.update(Markdown(str(content), code_theme=code_theme))
299-
elif show_tool_calls and Agent.is_call_tools_node(node):
300+
if final_output_live is None:
301+
final_output_live = Live(
302+
'', refresh_per_second=15, console=console, vertical_overflow='ellipsis'
303+
)
304+
stack.enter_context(final_output_live) # entering multiple times is idempotent
305+
final_output_live.update(Markdown(str(content), code_theme=code_theme))
306+
elif Agent.is_call_tools_node(node):
307+
status.update(TOOL_EXECUTION_STATUS_MSG)
300308
async with node.stream(agent_run.ctx) as handle_stream:
301309
async for event in handle_stream:
302310
if isinstance(event, FunctionToolCallEvent):
311+
status.stop() # stopping multiple times is idempotent
303312
console.print(
304-
Markdown(f'[Tool] {event.part.tool_name!r} called with args={event.part.args}')
313+
Markdown(
314+
f'[Tool] {event.part.tool_name!r}[{event.part.tool_call_id[-5:]}] called with args={event.part.args}'
315+
)
305316
)
317+
status.start()
306318
elif isinstance(event, FunctionToolResultEvent):
319+
status.stop() # stopping multiple times is idempotent
307320
console.print(
308-
Markdown(f'[Tool] {event.result.tool_name!r} returned => {event.result.content}')
321+
Markdown(
322+
f'[Tool] {event.result.tool_name!r}[{event.result.tool_call_id[-MAX_TOOL_CALL_ID_LEN:]}] returned => {event.result.content if len(event.result.content) < MAX_TOOL_CALL_RESULT_LEN else str(event.result.content[:MAX_TOOL_CALL_RESULT_LEN]) + "..."}'
323+
)
309324
)
325+
status.start()
310326

311327
assert agent_run.result is not None
312328
return agent_run.result.all_messages()

pydantic_ai_slim/pydantic_ai/agent/abstract.py

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1113,15 +1113,13 @@ async def to_cli(
11131113
deps: AgentDepsT = None,
11141114
prog_name: str = 'pydantic-ai',
11151115
message_history: list[_messages.ModelMessage] | None = None,
1116-
show_tool_calls: bool = False,
11171116
) -> None:
11181117
"""Run the agent in a CLI chat interface.
11191118
11201119
Args:
11211120
deps: The dependencies to pass to the agent.
11221121
prog_name: The name of the program to use for the CLI. Defaults to 'pydantic-ai'.
11231122
message_history: History of the conversation so far.
1124-
show_tool_calls: Whether to show tool calls in the CLI.
11251123
11261124
Example:
11271125
```python {title="agent_to_cli.py" test="skip"}
@@ -1145,23 +1143,20 @@ async def main():
11451143
code_theme='monokai',
11461144
prog_name=prog_name,
11471145
message_history=message_history,
1148-
show_tool_calls=show_tool_calls,
11491146
)
11501147

11511148
def to_cli_sync(
11521149
self: Self,
11531150
deps: AgentDepsT = None,
11541151
prog_name: str = 'pydantic-ai',
11551152
message_history: list[_messages.ModelMessage] | None = None,
1156-
show_tool_calls: bool = False,
11571153
) -> None:
11581154
"""Run the agent in a CLI chat interface with the non-async interface.
11591155
11601156
Args:
11611157
deps: The dependencies to pass to the agent.
11621158
prog_name: The name of the program to use for the CLI. Defaults to 'pydantic-ai'.
11631159
message_history: History of the conversation so far.
1164-
show_tool_calls: Whether to show tool calls in the CLI.
11651160
11661161
```python {title="agent_to_cli_sync.py" test="skip"}
11671162
from pydantic_ai import Agent
@@ -1172,7 +1167,5 @@ def to_cli_sync(
11721167
```
11731168
"""
11741169
return get_event_loop().run_until_complete(
1175-
self.to_cli(
1176-
deps=deps, prog_name=prog_name, message_history=message_history, show_tool_calls=show_tool_calls
1177-
)
1170+
self.to_cli(deps=deps, prog_name=prog_name, message_history=message_history)
11781171
)

tests/test_cli.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,6 @@ def test_agent_to_cli_sync(mocker: MockerFixture, env: TestEnv):
293293
prog_name='pydantic-ai',
294294
deps=None,
295295
message_history=None,
296-
show_tool_calls=False,
297296
)
298297

299298

@@ -310,7 +309,6 @@ async def test_agent_to_cli_async(mocker: MockerFixture, env: TestEnv):
310309
prog_name='pydantic-ai',
311310
deps=None,
312311
message_history=None,
313-
show_tool_calls=False,
314312
)
315313

316314

@@ -331,7 +329,6 @@ async def test_agent_to_cli_with_message_history(mocker: MockerFixture, env: Tes
331329
prog_name='pydantic-ai',
332330
deps=None,
333331
message_history=test_messages,
334-
show_tool_calls=False,
335332
)
336333

337334

@@ -351,5 +348,4 @@ def test_agent_to_cli_sync_with_message_history(mocker: MockerFixture, env: Test
351348
prog_name='pydantic-ai',
352349
deps=None,
353350
message_history=test_messages,
354-
show_tool_calls=False,
355351
)

0 commit comments

Comments
 (0)