llm icon indicating copy to clipboard operation
llm copied to clipboard

Tools returning attachments

Open simonw opened this issue 6 months ago • 4 comments

Refs:

  • #1014

TODO:

  • [x] Add ToolOutput mechanism for returning attachments
  • [x] Get that working in the .chain() mechanism
  • [x] Get it working in default OpenAI plugin
  • [ ] Log returned attachments to the database
  • [ ] Comprehensive tests across async/sync
  • [ ] Update documentation

simonw avatar Jun 01 '25 03:06 simonw

For the database, I'm going to do a many-to-many table between attachments and tool_results.

simonw avatar Jun 01 '25 03:06 simonw

I'm a bit nervous about async mode and attachments, since I don't think I've had to deal with that before - how should attachments async-resolve URLs?

simonw avatar Jun 01 '25 03:06 simonw

New table:

CREATE TABLE [tool_results_attachments] (
   [tool_result_id] INTEGER REFERENCES [tool_results]([id]),
   [attachment_id] TEXT REFERENCES [attachments]([id]),
   [order] INTEGER,
   PRIMARY KEY ([tool_result_id], [attachment_id])
);

simonw avatar Jun 01 '25 03:06 simonw

In digging through the code I have a nasty suspicion that attachments are not fully asyncio safe - I think sometimes when an async model is executing a prompt it may make a blocking call to attachment.base64_content() which calls attachment.content_bytes() which calls a blocking httpx.get(). Fixing this will be tricky because it will involve fixing a bunch of existing plugins.

simonw avatar Jun 01 '25 04:06 simonw

--td output now looks like this:

% llm -T fetch_image_from_url 'Tell me about https://static.simonwillison.net/static/2025/two-pelicans.jpg' --td

Tool call: fetch_image_from_url({'image_url': 'https://static.simonwillison.net/static/2025/two-pelicans.jpg'})
  Image fetched
  Attachments:
    <Attachment: 69caf7de384d865612b63cec6663a3cfff56a39197e68da6ffb105d78dce7f6f url="https://static.simonwillison.net/static/2025/two-pelicans.jpg">

simonw avatar Jun 01 '25 16:06 simonw