Skip to content

Commit f1d4594

Browse files
committed
chore: deprecate 'over-reaching' Chat features
1 parent 24b02cf commit f1d4594

File tree

2 files changed

+73
-95
lines changed

2 files changed

+73
-95
lines changed

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
5151

5252
* `ui.panel_well()` is deprecated in favor of `ui.card()`. (#2038)
5353

54+
* Numerous `ui.Chat()` features have been deprecated in preparation for future removal to simplify the API (#2050)
55+
* The `messages` parameter in the `Chat()` constructor is deprecated. Pass initial messages to the `.ui(messages=...)` method instead.
56+
* The `tokenizer` parameter in the `Chat()` constructor is deprecated. Token counting and message trimming features will eventually be removed.
57+
* The `format`, `token_limits`, `transform_user`, and `transform_assistant` parameters in the `.messages()` method are deprecated. Provider-specific formatting and message transformation features will eventually be removed.
58+
* The `.transform_user_input()` and `.transform_assistant_response()` methods are deprecated. Message transformation features will eventually be removed.
59+
* The `transform` parameter in the `.user_input()` method is deprecated. User input transformation features will eventually be removed.
60+
5461

5562
## [1.4.0] - 2025-04-08
5663

shiny/ui/_chat.py

Lines changed: 66 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -157,21 +157,7 @@ async def handle_user_input(user_input: str):
157157
A unique identifier for the chat session. In Shiny Core, make sure this id
158158
matches a corresponding :func:`~shiny.ui.chat_ui` call in the UI.
159159
messages
160-
A sequence of messages to display in the chat. A given message can be one of the
161-
following:
162-
163-
* A string, which is interpreted as markdown and rendered to HTML on the client.
164-
* To prevent interpreting as markdown, mark the string as
165-
:class:`~shiny.ui.HTML`.
166-
* A UI element (specifically, a :class:`~shiny.ui.TagChild`).
167-
* This includes :class:`~shiny.ui.TagList`, which take UI elements
168-
(including strings) as children. In this case, strings are still
169-
interpreted as markdown as long as they're not inside HTML.
170-
* A dictionary with `content` and `role` keys. The `content` key can contain a
171-
content as described above, and the `role` key can be "assistant" or "user".
172-
173-
**NOTE:** content may include specially formatted **input suggestion** links
174-
(see `.append_message()` for more information).
160+
Deprecated. Use `.ui(messages=...)` instead.
175161
on_error
176162
How to handle errors that occur in response to user input. When `"unhandled"`,
177163
the app will stop running when an error occurs. Otherwise, a notification
@@ -183,11 +169,8 @@ async def handle_user_input(user_input: str):
183169
* `"sanitize"`: Sanitize the error message before displaying it to the user.
184170
* `"unhandled"`: Do not display any error message to the user.
185171
tokenizer
186-
The tokenizer to use for calculating token counts, which is required to impose
187-
`token_limits` in `.messages()`. If not provided, a default generic tokenizer
188-
is attempted to be loaded from the tokenizers library. A specific tokenizer
189-
may also be provided by following the `TokenEncoding` (tiktoken or tozenizers)
190-
protocol (e.g., `tiktoken.encoding_for_model("gpt-4o")`).
172+
Deprecated. Token counting and message trimming features will be removed in a
173+
future version.
191174
"""
192175

193176
def __init__(
@@ -201,6 +184,18 @@ def __init__(
201184
if not isinstance(id, str):
202185
raise TypeError("`id` must be a string.")
203186

187+
if messages:
188+
warn_deprecated(
189+
"The `messages` parameter in Chat() is deprecated. "
190+
"Use `.ui(messages=...)` instead for starting messages."
191+
)
192+
193+
if tokenizer is not None:
194+
warn_deprecated(
195+
"The `tokenizer` parameter in Chat() is deprecated. "
196+
"Token counting and message trimming features will be removed in a future version."
197+
)
198+
204199
self.id = resolve_id(id)
205200
self.user_input_id = ResolvedId(f"{self.id}_user_input")
206201
self._transform_user: TransformUserInputAsync | None = None
@@ -459,48 +454,22 @@ def messages(
459454
"""
460455
Reactively read chat messages
461456
462-
Obtain chat messages within a reactive context. The default behavior is
463-
intended for passing messages along to a model for response generation where
464-
you typically want to:
465-
466-
1. Cap the number of tokens sent in a single request (i.e., `token_limits`).
467-
2. Apply user input transformations (i.e., `transform_user`), if any.
468-
3. Not apply assistant response transformations (i.e., `transform_assistant`)
469-
since these are predominantly for display purposes (i.e., the model shouldn't
470-
concern itself with how the responses are displayed).
457+
Obtain chat messages within a reactive context.
471458
472459
Parameters
473460
----------
474461
format
475-
The message format to return. The default value of `MISSING` means
476-
chat messages are returned as :class:`ChatMessage` objects (a dictionary
477-
with `content` and `role` keys). Other supported formats include:
478-
479-
* `"anthropic"`: Anthropic message format.
480-
* `"google"`: Google message (aka content) format.
481-
* `"langchain"`: LangChain message format.
482-
* `"openai"`: OpenAI message format.
483-
* `"ollama"`: Ollama message format.
462+
Deprecated. Provider-specific message formatting will be removed in a future
463+
version.
484464
token_limits
485-
Limit the conversation history based on token limits. If specified, only
486-
the most recent messages that fit within the token limits are returned. This
487-
is useful for avoiding "exceeded token limit" errors when sending messages
488-
to the relevant model, while still providing the most recent context available.
489-
A specified value must be a tuple of two integers. The first integer is the
490-
maximum number of tokens that can be sent to the model in a single request.
491-
The second integer is the amount of tokens to reserve for the model's response.
492-
Note that token counts based on the `tokenizer` provided to the `Chat`
493-
constructor.
465+
Deprecated. Token counting and message trimming features will be removed in
466+
a future version.
494467
transform_user
495-
Whether to return user input messages with transformation applied. This only
496-
matters if a `transform_user_input` was provided to the chat constructor.
497-
The default value of `"all"` means all user input messages are transformed.
498-
The value of `"last"` means only the last user input message is transformed.
499-
The value of `"none"` means no user input messages are transformed.
468+
Deprecated. Message transformation features will be removed in a future
469+
version.
500470
transform_assistant
501-
Whether to return assistant messages with transformation applied. This only
502-
matters if an `transform_assistant_response` was provided to the chat
503-
constructor.
471+
Deprecated. Message transformation features will be removed in a future
472+
version.
504473
505474
Note
506475
----
@@ -514,6 +483,30 @@ def messages(
514483
A tuple of chat messages.
515484
"""
516485

486+
if not isinstance(format, MISSING_TYPE):
487+
warn_deprecated(
488+
"The `format` parameter in messages() is deprecated. "
489+
"Provider-specific message formatting will be removed in a future version."
490+
)
491+
492+
if token_limits is not None:
493+
warn_deprecated(
494+
"The `token_limits` parameter in messages() is deprecated. "
495+
"Token counting and message trimming features will be removed in a future version."
496+
)
497+
498+
if transform_user != "all":
499+
warn_deprecated(
500+
"The `transform_user` parameter in messages() is deprecated. "
501+
"Message transformation features will be removed in a future version."
502+
)
503+
504+
if transform_assistant:
505+
warn_deprecated(
506+
"The `transform_assistant` parameter in messages() is deprecated. "
507+
"Message transformation features will be removed in a future version."
508+
)
509+
517510
messages = self._messages()
518511

519512
# Anthropic requires a user message first and no system messages
@@ -982,25 +975,14 @@ def transform_user_input(
982975
self, fn: TransformUserInput | TransformUserInputAsync | None = None
983976
) -> None | Callable[[TransformUserInput | TransformUserInputAsync], None]:
984977
"""
985-
Transform user input.
986-
987-
Use this method as a decorator on a function (`fn`) that transforms user input
988-
before storing it in the chat messages returned by `.messages()`. This is
989-
useful for implementing RAG workflows, like taking a URL and scraping it for
990-
text before sending it to the model.
991-
992-
Parameters
993-
----------
994-
fn
995-
A function to transform user input before storing it in the chat
996-
`.messages()`. If `fn` returns `None`, the user input is effectively
997-
ignored, and `.on_user_submit()` callbacks are suspended until more input is
998-
submitted. This behavior is often useful to catch and handle errors that
999-
occur during transformation. In this case, the transform function should
1000-
append an error message to the chat (via `.append_message()`) to inform the
1001-
user of the error.
978+
Deprecated. User input transformation features will be removed in a future version.
1002979
"""
1003980

981+
warn_deprecated(
982+
"The transform_user_input() method is deprecated. "
983+
"User input transformation features will be removed in a future version."
984+
)
985+
1004986
def _set_transform(fn: TransformUserInput | TransformUserInputAsync):
1005987
self._transform_user = _utils.wrap_async(fn)
1006988

@@ -1024,31 +1006,14 @@ def transform_assistant_response(
10241006
fn: TransformAssistantResponseFunction | None = None,
10251007
) -> None | Callable[[TransformAssistantResponseFunction], None]:
10261008
"""
1027-
Transform assistant responses.
1028-
1029-
Use this method as a decorator on a function (`fn`) that transforms assistant
1030-
responses before displaying them in the chat. This is useful for post-processing
1031-
model responses before displaying them to the user.
1032-
1033-
Parameters
1034-
----------
1035-
fn
1036-
A function that takes a string and returns either a string,
1037-
:class:`shiny.ui.HTML`, or `None`. If `fn` returns a string, it gets
1038-
interpreted and parsed as a markdown on the client (and the resulting HTML
1039-
is then sanitized). If `fn` returns :class:`shiny.ui.HTML`, it will be
1040-
displayed as-is. If `fn` returns `None`, the response is effectively ignored.
1041-
1042-
Note
1043-
----
1044-
When doing an `.append_message_stream()`, `fn` gets called on every chunk of the
1045-
response (thus, it should be performant), and can optionally access more
1046-
information (i.e., arguments) about the stream. The 1st argument (required)
1047-
contains the accumulated content, the 2nd argument (optional) contains the
1048-
current chunk, and the 3rd argument (optional) is a boolean indicating whether
1049-
this chunk is the last one in the stream.
1009+
Deprecated. Assistant response transformation features will be removed in a future version.
10501010
"""
10511011

1012+
warn_deprecated(
1013+
"The transform_assistant_response() method is deprecated. "
1014+
"Assistant response transformation features will be removed in a future version."
1015+
)
1016+
10521017
def _set_transform(
10531018
fn: TransformAssistantResponseFunction,
10541019
):
@@ -1255,6 +1220,12 @@ def user_input(self, transform: bool = False) -> str | None:
12551220
2. Maintaining message state separately from `.messages()`.
12561221
12571222
"""
1223+
if transform:
1224+
warn_deprecated(
1225+
"The `transform` parameter in user_input() is deprecated. "
1226+
"User input transformation features will be removed in a future version."
1227+
)
1228+
12581229
msg = self._latest_user_input()
12591230
if msg is None:
12601231
return None

0 commit comments

Comments
 (0)