Skip to content

Commit 3f087cd

Browse files
gadenbuiecpsievert
andauthored
Tool calling UI (#52)
* draft * draft * fixup draft * fix typo * fix stylesheet id * more drafting * fix: chat_ui() expects a string message content to be a string * If tool has a title, use only that for result header * for overlong tool calls, only show tool name * feat: Support `@extra$display` in tool results * `display` can be markdown or HTML * `display` can be a list with `html`, `markdown` or `text` used in that order * `display_tool_request` hides the tool request if FALSE * Remove ... argument * Move JS/CSS files to proper location * Minor refactoring of tool_result_display() * Attach JS/CSS files to the main htmlDependency() * A bit more minor refactoring * `air format` (GitHub Actions) * chore: more minor refactoring * claude: ShinyToolRequest component * claude: ShinyToolResult component * chore: more chat tools work * chore: make js-build * chore: don't expand tool result by default * refactor: Pull out `tool_result_display()` * chore: use `request_id` instead of `id` * feat: provide request call, formatted from R/Python side * feat: Use light DOM instead of shadow DOM * chore: move chat tool styles to chat-tools.scss * feat: Use `.intent` from tool request args, not `intent` * feat: Use cards for tool results * chore: Limit tool result card max height * chore: build js and update R dist files * chore: kebab-case component attributes * chore: build and update assets * chore: small component and css updates * chore: build and update assets * fix: Ensure expandable cards are scoped to just the tool result card * chore: Remove `tool-request.js` from chat deps * chore: Use purrr-style map helpers * chore: revert formatting changes to preserve diff * chore(contents_shinychat): Provide generic to omit `... We might add `...` back in, but we don't need it right now * fix: remove overflow hidden * feat: Requests and results have same appearance Refactors ShinyToolRequest and ShinyToolResult to extend a base ShinyToolCard class * chore: update assets * feat: Preserve raw HTML in markdown stream output * refactor(chat_append_stream_impl): simplify with internal closure * chore: Use default syntax highlighting for request call in result * chore: use a spacer div to left-align intent and dropdown toggle indicator * feat: Support `icon` in `tool@annotations` * fix: Ensure streaming dot appears inline when possible or on a new line when necessary * chore: build and update assets * refactor: Simplify card header markup * chore: rebuild and update assets * chore: Soften tool title name weight * chore: Ensure consistent spacing between <p> and tool request/results * chore: build and update assets * chore: don't need to use `on_tool_result` to hide tool request * tests: fix snapshot tests * fix: Use tool result as seen by the LLM by default * feat: Better collapse indicator * chore: build and update assets * chore: rework collapse indicator as single div element * chore: Return bare html results as direct child of card * chore: Wrap tool arguments in div with header * chore: build and update assets * tests: Add test app for tool UI basics * chore: re-implement toggle icon using svg For consistent widths, otherwise divs look differently by browser and font-size * fix: Handle missing tool definitions gracefully * fix: `icon_deps` needs to be defined even if tool is missing * fix: fill in tool defs in ContentToolResults * feat: set client UI piecewise * chore: Remove card init script * chore: move display up * revert formatting change * chore: remove bslib data attributes * chore: build and update assets * chore: Require ellmer >= v0.3.0 * Revert "tests: fix snapshot tests" This reverts commit cc011ff. * refactor: rename `msg_turn` var for clarity * chore: simplify settings props when NULL is okay * chore: Tool results must have an associated request * refactor: clean up `tool_result_display()` * chore: suggestions from code review * refactor: Use a generator to set client UI * fix(findInnermostStreamingElement): rename and fixup helper function * chore: build and update assets * refactor(findInnermostStreamingElement): Make it faster * chore: build and update assets * fix: typo in `tool_result_display` * feat: Allow tool result to set display details, too * fix: default `showRequest` to `false` so attribute presence makes it true * draft: htmlwidget support still doesn't work, dependencies are not included correctly * chore: Add demo app with tool call for creating a map * chore: build and update assets * chore: wrap widgets in `tagList()` This **should be enough** but it still doesn't work * fix: unbreak `client_set_ui()` * fix: Need to explicitly pull out `value` html deps * feat: Use `@extra$display` to hold `title` and `icon` * fix: Assume HTML if no `result@extra$display` type is specified * feat: Add option/envvar to control tool display; require `@extra$display` be a list * chore: reverse order (opt then envvar) * chore: Limit recursion depth when finding streaming element * fix: Don't append streaming dot when assistant message is empty or last child is tool request * chore: build and update assets * fix(typo): return `display` after validation * refactor: `ensure_content_display()` * tests: Add tests for `contents_shinychat()` * tests: Add missing helpers file * chore: imports {cli}, suggests {withr} * fix: Add Shiny message handles when Shiny is available * chore: tool card body has overflow auto * chore: attach chat deps to `contents_shinychat()` request/results * chore: build and update assets * chore: Address code review comments * chore!: Use `.tool_intent` instead of `.intent` * fix(pkgdown): Update url and add missing function * docs: Add `contents_shinychat` to pkgdown index * docs: tool call UI article * chore: Add demo tool UI test apps * chore: remove debugging code * fix: Mention `chat_app()` and modules, also `stream="content"` * chore: change vignette title * chore: remove `tools` icon * chore: build and update assets * chore!: Change attributes for `tool-name` and `tool-title` `title` is a reserved attribute in HTML and lit elements, so we need to avoid using it. I considered also changing `tool-icon` (and maybe also `tool-intent`), but decided that the minimal change to have tool name and title is enough. If we only change `tool-title`, though, then it's odd that `name` is not `tool-name` as well. * chore: build and update assets * fix: Send a `shiny-tool-request-hide` custom message on result This is required when the tool result display is completely customized by the user, i.e they don't use our `<shiny-tool-result>` component. Without the custom message, we can't hide the tool result. Interestingly we need to remember the message because the tool request and result are being re-rendered frequently while the LLM is streaming output. For now, we store a set of seen tool request IDs and we short-circuit tool request rendering if we've already seen that ID. In the future, if we start new markdown-stream components when we have a switch in content type, we won't need to remember between renders. * chore: build and update assets * feat: Make it easier to extend tool request/result cards via custom `contents_shinychat()` * We now store the data used to create the tool request/result cards but avoid rendering them to tags until required. * This lets someone use `super(content, ContentToolRequest)` to get our default data structure that the can modify before it's rendered to tags. * This let users move some computation from tool result time to tool request time, which can improve perceived performance and reduce storage requirements. I also updated the `contents_shinychat()` docs to explain how to work with this new feature. * fix: as.tags() signature * chore!: Back to `.intent` instead of `.tool_intent` It's just simpler and more consistent * docs: Add NEWS item * chore: remove pkgload debug code Co-authored-by: Carson Sievert <cpsievert1@gmail.com> --------- Co-authored-by: Carson <cpsievert1@gmail.com> Co-authored-by: cpsievert <cpsievert@users.noreply.github.com>
1 parent 82a1f99 commit 3f087cd

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+3322
-168
lines changed

js/dist/chat/chat.css

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)