Permission
An agent asking to be allowed something, with the answer under the reasoning rather than in a dialog that arrived without it. The ask comes first, in the tool's own name; the reasoning is its case.
Asking
Allow is the prominent, consequential choice; a second, wider grant is offered only when there's something to widen. Focus goes to the card, never to Allow.
read_chat chat_id: 4812
Read the conversation where the lantern brief was agreed.
The brief here refers to decisions made there, and I can't see them.
- “Go with the lit version” — 3 Sept
- “Keep it under 3k triangles” — 4 Sept
<div class="mx-auto max-w-xl">
<%= ai_chat_permission tool: "read_chat", state: :waiting, url: "#" do |ask| %>
<% ask.argument "chat_id", 4812 %>
<% ask.summary { tag.p("Read the conversation where the lantern brief was agreed.") } %>
<% ask.reason { tag.p("The brief here refers to decisions made there, and I can't see them.") } %>
<% ask.example "“Go with the lit version” — 3 Sept" %>
<% ask.example "“Keep it under 3k triangles” — 4 Sept" %>
<% ask.allow confirm: "Let this chat read conversation 4812?" %>
<% ask.allow "Allow for any chat", params: { widened: true }, confirm: "Let this chat read any conversation?" %>
<% ask.refuse %>
<% end %>
</div>Answered
Granted, refused, and a request answered in the chat with nothing granted.
delete_files paths: drafts/*
Remove the three superseded drafts.
Allowed.
send_email to: grace.okafor@example.com
Refused.
read_chat chat_id: 4812
Answered in the chat — nothing was granted.
<div class="mx-auto flex max-w-xl flex-col gap-4">
<%= ai_chat_permission tool: "delete_files", state: :granted do |ask| %>
<% ask.argument "paths", "drafts/*" %>
<% ask.summary { tag.p("Remove the three superseded drafts.") } %>
<% end %>
<%= ai_chat_permission tool: "send_email", state: :refused do |ask| %>
<% ask.argument "to", "grace.okafor@example.com" %>
<% end %>
<%= ai_chat_permission tool: "read_chat", state: :lapsed do |ask| %>
<% ask.argument "chat_id", 4812 %>
<% end %>
</div>