Tool call
One reach for a tool, from the ask to the answer, as a row. A run of them is joined by a line into a timeline, because four calls in one breath are one stretch of work, not four events.
A run of calls
Rows join up, counting the hidden gap markers between them. A done call's glyph says what it was about.
Assistant said
Let me look through the shelves.
Donelist_shelvesTook90ms
Asked
{}Answered
{
"shelves": [
"Backgrounds",
"Characters",
"Props"
]
}Donesearch_filesred lanternTook640ms
Asked
{
"query": "red lantern",
"shelf": "Props"
}Answered
{
"files": [
"props/lantern-red.glb",
"props/lantern-red-lit.glb"
]
}Doneread_fileprops/lantern-red.glbTook2s
Asked
{
"path": "props/lantern-red.glb"
}Answered
A 3D model: 2,140 triangles, one material, no animations.Assistant said
There are two red lanterns; the lit one has an emissive material.
<div class="mx-auto max-w-2xl">
<%= ai_chat id: "run_entries", follow: false do %>
<%= ai_chat_message role: :assistant do %><p>Let me look through the shelves.</p><% end %>
<%= ai_chat_tool_call name: "list_shelves", state: :done, icon: :folder do |tool| %>
<% tool.timing duration: 0.09 %>
<% tool.asked({}) %>
<% tool.answered({ shelves: [ "Backgrounds", "Characters", "Props" ] }) %>
<% end %>
<div data-ai-chat-timeline="gap" hidden></div>
<%= ai_chat_tool_call name: "search_files", state: :done, icon: :file, open: true do |tool| %>
<% tool.summary "red lantern" %>
<% tool.timing duration: 0.64 %>
<% tool.asked({ query: "red lantern", shelf: "Props" }) %>
<% tool.answered({ files: [ "props/lantern-red.glb", "props/lantern-red-lit.glb" ] }) %>
<% end %>
<div data-ai-chat-timeline="gap" hidden></div>
<%= ai_chat_tool_call name: "read_file", state: :done, icon: :file do |tool| %>
<% tool.summary "props/lantern-red.glb" %>
<% tool.timing duration: 2.4 %>
<% tool.asked({ path: "props/lantern-red.glb" }) %>
<% tool.answered "A 3D model: 2,140 triangles, one material, no animations." %>
<% end %>
<%= ai_chat_message role: :assistant do %><p>There are two red lanterns; the lit one has an emissive material.</p><% end %>
<% end %>
</div>Every state
Queued, running (with a live clock and progress), waiting on a person, done, and failed.
Queued
render_sceneRunning1m 12s Frame 12 of 40
render_scenenight marketRunning forWaiting on you
ask_personwhich lantern?Donedelete_filesPartly failed2 failedTook3s
Asked
{
"paths": [
"a.png",
"b.png",
"c.png"
]
}Answered
{
"deleted": 1,
"errors": [
{
"path": "b.png",
"error": "locked"
},
{
"path": "c.png",
"error": "missing"
}
]
}Failedfetch_pageexample.com/pricingTook30s
Answered
Timed out after 30 seconds<div class="mx-auto flex max-w-2xl flex-col gap-4">
<%= ai_chat_tool_call name: "render_scene", state: :queued, timeline: false %>
<%= ai_chat_tool_call name: "render_scene", state: :running, id: "states_render", timeline: false do |tool| %>
<% tool.summary "night market" %>
<% tool.timing started_at: @now - 72 %>
<% tool.progress "Frame 12 of 40" %>
<% end %>
<%= ai_chat_tool_call name: "ask_person", state: :waiting, timeline: false do |tool| %>
<% tool.summary "which lantern?" %>
<% end %>
<%= ai_chat_tool_call name: "delete_files", state: :done, icon: :folder, timeline: false do |tool| %>
<% tool.timing duration: 3.1 %>
<% tool.failures 2 %>
<% tool.asked({ paths: [ "a.png", "b.png", "c.png" ] }) %>
<% tool.answered({ deleted: 1, errors: [ { path: "b.png", error: "locked" }, { path: "c.png", error: "missing" } ] }) %>
<% end %>
<%= ai_chat_tool_call name: "fetch_page", state: :failed, timeline: false do |tool| %>
<% tool.summary "example.com/pricing" %>
<% tool.timing duration: 30 %>
<% tool.answered "Timed out after 30 seconds" %>
<% end %>
</div>What a call made
made keeps the output outside the fold, with the line running beside it.
Donegenerate_imagea red paper lanternTook14s
Asked
{
"prompt": "a red paper lantern, night market, soft glow"
}lantern.png
lantern.png
lantern.png
<div class="mx-auto max-w-2xl">
<%= ai_chat_tool_call name: "generate_image", state: :done, icon: :lightbulb do |tool| %>
<% tool.summary "a red paper lantern" %>
<% tool.timing duration: 14.2 %>
<% tool.asked({ prompt: "a red paper lantern, night market, soft glow" }) %>
<% tool.made do %>
<% %w[from-red-500 from-orange-400 from-rose-500].each do |from| %>
<div class="grid h-28 w-40 place-items-center rounded-lg bg-gradient-to-br <%= from %> to-neutral-900 text-xs text-white">lantern.png</div>
<% end %>
<% end %>
<% end %>
</div>