kaipingyang

ShinyAssistantUI — AI skill for Claude Code

AI community

A Shiny htmlwidget that wraps @assistant-ui/react — giving Shiny apps a full-featured AI chat UI with streaming output, slash command menu, file attac.

How to install ShinyAssistantUI

This entry records only its repository, not the path inside it, so there is no exact command to give. Open kaipingyang/shinyAssistantUI and copy the folder into ~/.claude/skills/, or the file into ~/.claude/agents/.

What ShinyAssistantUI does

A Shiny htmlwidget that wraps @assistant-ui/react — giving Shiny apps a full-featured AI chat UI with streaming output, slash command menu, file attac.

Alternatives in AI

  • Botmux — Bridge Feishu/Lark to AI coding CLIs — Claude Code, Codex, Gemini, OpenCode… every DM, group or topic spawns i 1.2k ★
  • Proxypal — A desktop app that lets you use your AI subscriptions (Claude, ChatGPT, Gemini, GitHub Copilot) with any codin 1.2k ★
  • My Free Code — Open-source multi-provider AI gateway for Claude Code and other coding agents, with model routing, streaming 633 ★

README

shinyAssistantUI

A Shiny htmlwidget that wraps [`@assistant-ui/react`](https://github.com/assistant-ui/assistant-ui) — giving Shiny apps a full-featured AI chat UI with streaming output, slash command menu, file attachments, and tool call display.

Backend-agnostic: works with [ClaudeAgentSDK](https://github.com/kaipingyang/ClaudeAgentSDK), [ellmer](https://github.com/tidyverse/ellmer), or any R-based AI backend.

Installation

# GitHub (development)
remotes::install_github("kaipingyang/shinyAssistantUI")

Usage

library(shiny)
library(shinyAssistantUI)

ui <- assistantUIPage(
  assistantUIOutput("chat", height = "100%"),
  title = "AI Assistant"
)

server <- function(input, output, session) {
  assistantUIServer("chat", handler = function(message, on_chunk, on_done, on_error) {
    # Call any AI backend here
    # Stream tokens back with on_chunk(), finish with on_done()
    on_chunk("Hello! You said: ")
    on_chunk(message)
    on_done()
  })
}

shinyApp(ui, server)

With ClaudeAgentSDK

library(shiny)
library(shinyAssistantUI)
library(ClaudeAgentSDK)

ui <- assistantUIPage(
  assistantUIOutput("chat", height = "100%"),
  title = "Claude Assistant"
)

server <- function(input, output, session) {
  client <- ClaudeSDKClient$new(claude_agent_options())

  assistantUIServer("chat", handler = function(message, on_chunk, on_done, on_error) {
    client$connect()
    client$send(message)
    client$receive_response_async(
      on_message = function(msg) {
        if (inherits(msg, "AssistantMessage")) {
          for (block in msg$content) {
            if (inherits(block, "TextBlock")) on_chunk(block$text)
          }
        }
        if (inherits(msg, "ResultMessage")) on_done()
      }
    )
  })
}

shinyApp(ui, server)

With bslib

library(bslib)

page_sidebar(
  title = "My AI App",
  sidebar = sidebar(...),
  bslib::card(
    full_screen = TRUE,
    assistantUIOutput("chat", height = "100%")
  )
)

In RSt