文件历史

23 次代码提交

作者 SHA1 备注 提交日期
Simon Willison 556c1eaa14 Dedupe tool descriptions in logs, better argument display, closes #1515 2026-07-05 10:00:06 -07:00
Simon Willison 92a9ca7cbf Async tool calls to missing tools now produce error results (#1483)
The async execute_tool_calls() silently dropped calls to tools that
were not in tools= (or had no implementation): output and exception
were assigned but no ToolResult was ever appended, so the next
provider call carried an assistant tool_call with no matching result
- which OpenAI and Anthropic reject. The sync executor already
returned an 'Error: tool ... does not exist' result.

The async path now mirrors the sync one: before_call fires (and can
CancelToolCall) even though the tool is unavailable, and an error
ToolResult is appended in call order. Also removes the now-unreachable
tool-is-None branch from the inline sync-implementation path.

This matters more since chain resume landed: a pending call whose
tool is no longer registered would otherwise never resolve.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-06-09 15:17:37 -07:00
Simon Willison 73bb0221b2 Guaranteed tool call IDs (#1481)
* Guarantee every tool call has a unique tool_call_id

add_tool_call() now synthesizes a unique tc_-prefixed id (monotonic
ULID) whenever the provider did not supply one. Previously consumers
correlating tool calls with results - or keying external state on a
specific invocation - had to invent fallback matching schemes for
id-less providers, and test models like llm-echo exercised different
code paths than production providers.

Provider-supplied ids are preserved untouched, and responses
rehydrated from the logs database keep their stored ids (synthesis
only happens at add_tool_call time). Existing tests that asserted
tool_call_id None now normalize or mask the synthesized ids.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-09 14:04:26 -07:00
Simon Willison b865ede0f1 Tool implementations can receive the ToolCall via llm_tool_call param (#1480)
* Tool implementations can receive the ToolCall via llm_tool_call parameter

Tool functions (sync or async, including Toolbox methods) that declare
a parameter named llm_tool_call are now passed the llm.ToolCall object
for the current invocation. The parameter is reserved: it is excluded
from the input schema exposed to the model and is only injected when
declared explicitly - a **kwargs catch-all does not receive it.

This lets tool implementations key external state against the unique
tool_call_id, e.g. for human-in-the-loop approval flows that need to
resume a specific tool call after the answer arrives.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Ran Black

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-06-09 13:51:39 -07:00
Simon Willison c8889e0a76 Ran black 2026-03-17 11:25:12 -07:00
Simon Willison 5204a11f33 Allow -o option when calling tools, closes #1233 2025-08-11 13:44:26 -07:00
Simon Willison 08094082f2 Toolbox.add_tool(), prepare() and prepare_async() methods
Closes #1111
2025-08-11 13:19:31 -07:00
Simon Willison 3a96d52895 Better handling of before_call cancellation, closes #1148 2025-06-01 18:36:55 -07:00
Simon Willison d96ae4ed8d Fix --async logging to database, closes #1150 2025-06-01 17:38:26 -07:00
Simon Willison 30e0c4abe8 ToolResult.exception for tool errors, now logged to DB
Closes #1104
2025-06-01 17:01:40 -07:00
Simon Willison ed64fc3362 chain_limit/before_call/after_call for conversations
* chain_limit/before_call/after_call for conversations, closes #1088
* Docs for before_call/after_call including for model.conversation
2025-06-01 12:00:29 -07:00
Simon Willison b5d1c5ee90 Tools can now return attachments
Closes #1014

- llm.ToolOutput(output='...', attachments=[...]) for tools to return attachments
- New table: `tool_results_attachments`
- Table is populated when tools return attachments
- llm --tools-debug shows attachments returned by tools
- llm logs shows attachments returned by tools
2025-06-01 10:08:36 -07:00
Simon Willison 6bab712cdd Fix for module 'builtins' has no attribute 'instance_id, closes #1107 2025-05-27 13:13:28 -07:00
Simon Willison 9e25055765 Turn incorrect tool names into errors, closes #1104 2025-05-27 09:29:05 -07:00
Simon Willison 2bc6d7679c New default tool, llm_time, closes #1103 2025-05-26 23:00:18 -07:00
Simon Willison 9bbb37fae0 New default llm_version tool, closes #1096
Refs https://github.com/simonw/llm/issues/1095#issuecomment-2910574597
2025-05-26 13:30:47 -07:00
Simon Willison e23e13e6c7 Test for async toolbox, docs for toolboxes in general
Closes #1090, refs #997
2025-05-26 10:23:03 -07:00
Simon Willison 3cbc37a470 Log tool plugin to database
Refs https://github.com/simonw/llm/issues/1020#issuecomment-2905968166
2025-05-23 15:59:43 -07:00
Simon Willison 3e3492898c Conversations using tools in Python API
Refs #1033
2025-05-21 23:05:16 -07:00
Simon Willison 3cb875fa3d Async tool support (#1063)
* Sync models can now call async tools, refs #987
* Test for async tool functions in sync context, refs #987
* Test for asyncio tools, plus test that they run in parallel
* Docs for async tool usage
2025-05-21 21:42:19 -07:00
Simon Willison 88b806ae1a Got multi-tool OpenAI chat working, in no-stream mode too
Refs #1017, #1019
2025-05-13 17:19:30 -07:00
Simon Willison a50de8b57a ChainResponse.log_to_db() method and test, refs #1017, #1003 2025-05-13 17:19:30 -07:00
Simon Willison 5162cabbe1 First test for tools, plus vcr+syrupy, refs #1017 2025-05-13 17:19:30 -07:00