Skip to content

Commit 14087fd

Browse files
committed
feat: optionally show tool calls in CLI
1 parent 8ab8bd0 commit 14087fd

File tree

2 files changed

+19
-3
lines changed

2 files changed

+19
-3
lines changed

pydantic_ai_slim/pydantic_ai/_cli.py

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
from ._run_context import AgentDepsT
1919
from .agent import AbstractAgent, Agent
2020
from .exceptions import UserError
21-
from .messages import ModelMessage, ModelResponse
21+
from .messages import FunctionToolCallEvent, FunctionToolResultEvent, ModelMessage, ModelResponse
2222
from .models import KnownModelName, infer_model
2323
from .output import OutputDataT
2424

@@ -229,6 +229,7 @@ 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,
232233
) -> int:
233234
prompt_history_path = (config_dir or PYDANTIC_AI_HOME) / PROMPT_HISTORY_FILENAME
234235
prompt_history_path.parent.mkdir(parents=True, exist_ok=True)
@@ -255,7 +256,7 @@ async def run_chat(
255256
return exit_value
256257
else:
257258
try:
258-
messages = await ask_agent(agent, text, stream, console, code_theme, deps, messages)
259+
messages = await ask_agent(agent, text, stream, console, code_theme, deps, messages, show_tool_calls)
259260
except CancelledError: # pragma: no cover
260261
console.print('[dim]Interrupted[/dim]')
261262
except Exception as e: # pragma: no cover
@@ -273,6 +274,7 @@ async def ask_agent(
273274
code_theme: str,
274275
deps: AgentDepsT = None,
275276
messages: list[ModelMessage] | None = None,
277+
show_tool_calls: bool = False,
276278
) -> list[ModelMessage]:
277279
status = Status('[dim]Working on it…[/dim]', console=console)
278280

@@ -294,6 +296,17 @@ async def ask_agent(
294296

295297
async for content in handle_stream.stream_output(debounce_by=None):
296298
live.update(Markdown(str(content), code_theme=code_theme))
299+
elif show_tool_calls and Agent.is_call_tools_node(node):
300+
async with node.stream(agent_run.ctx) as handle_stream:
301+
async for event in handle_stream:
302+
if isinstance(event, FunctionToolCallEvent):
303+
console.print(
304+
Markdown(f'[Tool] {event.part.tool_name!r} called with args={event.part.args}')
305+
)
306+
elif isinstance(event, FunctionToolResultEvent):
307+
console.print(
308+
Markdown(f'[Tool] {event.result.tool_name!r} returned => {event.result.content}')
309+
)
297310

298311
assert agent_run.result is not None
299312
return agent_run.result.all_messages()

pydantic_ai_slim/pydantic_ai/agent/abstract.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1113,6 +1113,7 @@ 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,
11161117
) -> None:
11171118
"""Run the agent in a CLI chat interface.
11181119
@@ -1143,13 +1144,15 @@ async def main():
11431144
code_theme='monokai',
11441145
prog_name=prog_name,
11451146
message_history=message_history,
1147+
show_tool_calls=show_tool_calls,
11461148
)
11471149

11481150
def to_cli_sync(
11491151
self: Self,
11501152
deps: AgentDepsT = None,
11511153
prog_name: str = 'pydantic-ai',
11521154
message_history: list[_messages.ModelMessage] | None = None,
1155+
show_tool_calls: bool = False,
11531156
) -> None:
11541157
"""Run the agent in a CLI chat interface with the non-async interface.
11551158
@@ -1167,5 +1170,5 @@ def to_cli_sync(
11671170
```
11681171
"""
11691172
return get_event_loop().run_until_complete(
1170-
self.to_cli(deps=deps, prog_name=prog_name, message_history=message_history)
1173+
self.to_cli(deps=deps, prog_name=prog_name, message_history=message_history, show_tool_calls=show_tool_calls)
11711174
)

0 commit comments

Comments
 (0)