Skip to content

feat!(pkg-r): add chat_server(), deprecate chat_mod_server() and chat_mod_ui() - #264

Merged
cpsievert merged 9 commits into
mainfrom
feat/chat-server
Jun 29, 2026
Merged

feat!(pkg-r): add chat_server(), deprecate chat_mod_server() and chat_mod_ui()#264
cpsievert merged 9 commits into
mainfrom
feat/chat-server

Conversation

@cpsievert

@cpsievert cpsievert commented Jun 25, 2026

Copy link
Copy Markdown
Collaborator

Summary

chat_server() replaces chat_mod_server() as the primary way to wire up server-side chat logic.

The original module-based API (chat_mod_ui() / chat_mod_server()) was more structure than the use case needs. The goal of this API is simple: you hand us an ellmer client and we hook up all the server logic most people want — streaming, cancellation, bookmarking, etc. A full moduleServer() scope isn't required to deliver that. Furthermore, since part of the ID namespace is private/implicit, downstream logic that depends on the chat's ID (e.g., slash command JS events) need workarounds to work in the way users might expect. This change also better aligns the R package with the Python API where no modules are needed to get the "batteries included" experience.

chat_server() does the same job but runs directly in the caller's session scope. If you're already inside a moduleServer(), you pass that session in — no extra nesting, no doubled namespaces.

What changed

  • chat_server(id, client, ..., session) — new exported function with the same logic as chat_mod_server(), but runs in the provided session scope rather than creating its own. Takes an explicit session parameter (defaults to getDefaultReactiveDomain()).
  • chat_mod_server() — soft-deprecated (0.5.0). Now a thin wrapper around chat_server().
  • chat_mod_ui() — soft-deprecated (0.5.0). Replace with chat_ui(NS(id, "chat"), ...) in your module UI.

Migration

The simplest case — no module needed at all:

# Before (forced you into a module)
ui <- fluidPage(chat_mod_ui("chat"))
server <- function(input, output, session) {
  chat_mod_server("chat", client)
}

# After
ui <- fluidPage(chat_ui("chat"))
server <- function(input, output, session) {
  chat_server("chat", client)
}

If you're embedding chat inside an existing module, pass that module's session explicitly:

ui <- function(id) {
  ns <- NS(id)
  chat_ui(ns("chat"))
}
server <- function(id, client) {
  shiny::moduleServer(id, function(input, output, session) {
    chat_server("chat", client, session = session)
  })
}

Existing code using chat_mod_server() continues to work with a deprecation notice.

…existing modules

Soft-deprecates chat_mod_server() and chat_mod_ui().
@cpsievert
cpsievert marked this pull request as draft June 25, 2026 01:29
@cpsievert cpsievert changed the title feat(pkg-r): add chat_server() as a server fragment feat!(pkg-r): add chat_server(), deprecate chat_mod_server() and chat_mod_ui() Jun 25, 2026
@cpsievert
cpsievert marked this pull request as ready for review June 25, 2026 14:21
@cpsievert
cpsievert requested a review from gadenbuie June 25, 2026 14:21
Comment thread pkg-r/R/chat_app.R
Comment thread pkg-r/R/chat_app.R Outdated
…s in chat_server()

chat_server() + chat_ui() now replace chat_mod_server() + chat_mod_ui() throughout
docs, examples, vignettes, and test apps.

To preserve the same batteries-included behavior, enable_cancel and allow_attachments
in chat_ui() now default to NULL (defer to server) rather than FALSE. chat_server()
sends update_cancel and update_upload actions at init, automatically enabling both
features — matching Python's tri-state pattern. Explicit TRUE/FALSE in chat_ui()
still wins; FALSE now emits the attribute as "false" so the server cannot override
an explicit opt-out.

This comment was marked as resolved.

@cpsievert
cpsievert requested a review from gadenbuie June 26, 2026 00:00

@gadenbuie gadenbuie left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, thanks!

`?chat_mod_ui` now has a standalone deprecated page (with lifecycle badge
and migration guidance) rather than appearing on `?chat_app`.
@cpsievert cpsievert changed the title feat!(pkg-r): add chat_server(), deprecate chat_mod_server() and chat_mod_ui() feat!(pkg-r): add chat_server(), deprecate chat_mod_server() and chat_mod_ui() Jun 29, 2026
@cpsievert
cpsievert merged commit f0f1473 into main Jun 29, 2026
11 of 12 checks passed
@cpsievert
cpsievert deleted the feat/chat-server branch June 29, 2026 14:43
simonpcouch pushed a commit to posit-dev/commons that referenced this pull request Jul 21, 2026
…er() (#38)

shinychat deprecated chat_mod_ui()/chat_mod_server() in favor of
chat_ui()/chat_server(), which run in the caller's own session scope instead
of a private module scope (posit-dev/shinychat#264). commons_ui()/
commons_server() replace commons_mod_ui()/commons_mod_server() to match.

Since chat_server() now handles history persistence automatically,
commons_server() no longer takes bookmark_on_input/bookmark_on_response.

Fixes a bug introduced by dropping the module wrapper: the provenance-pill
messages targeted a hardcoded "chat" id (previously correct only because
session$ns() was scoped to the module id), so pills silently failed to
attach for any chat id other than "chat". They now resolve the id the same
way shinychat's own chat_server() internals do, via session$ns(id).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants