Skip to content

feat(client): add hiddenText to sendMessage - #92

Merged
yuma2024 merged 4 commits into
mainfrom
feat/send-message-hidden-text
Oct 28, 2026
Merged

yuma2024 merged 4 commits into
mainfrom
feat/send-message-hidden-text

Conversation

@yuma2024

@yuma2024 yuma2024 commented Oct 28, 2026 •

Copy link
Copy Markdown
Contributor

Why

An app sometimes collects context before the chat starts (e.g. a form) and wants the AI to use it for the whole conversation without showing it in the chat. The existing inputs don't cover this: useAI({ prompt }) state, even when read from chat metadata, goes into the system prompt for the current run only. It is not part of the chat history and is not tied to a message. forwardedProps don't reach the model's messages. transformed_file is also sent but not shown, but the server prefixes it with a file header and it needs originalFile. What's needed is text attached to a message that stays in the history.

Change

  • SendMessageOptions.hiddenText?: string. It is sent as a text part before the visible text and the attachments. No heading or separator is added. Whitespace-only hiddenText is ignored.
  • Saved on the user message as a new PersistedHiddenTextContent ({ type: 'hidden_text', text }) part, so later turns and reloads send it again (transformMessagesToClientFormat).
  • getDisplayTextFromContent only reads text parts, so the built-in bubble, chat title, chat list and save-as-command leave it out. Existing stored messages are read as before.
  • Without hiddenText, behavior is unchanged. Client only; no server or core change.
  • README: an example under Programmatic Chat Control, and a note that a custom Message slot should skip hidden_text parts.

API: additive. PersistedContentPart gains hidden_text, so a consumer with an exhaustive switch over it needs one more case (same as when transformed_file and attachment_ref were added). sendFn in UseMessageQueueOptions gains a 4th optional parameter rather than an options object, since that type is exported.

Tests

bun run test: client 580, server 370, workflows 27 pass. New tests: wire order and stored order (hidden → visible → attachments), chat title, the rendered user bubble, and that the text reaches the AI on a later turn after a reload. The bubble test fails if getDisplayTextFromContent picks up every part that has text; the reload test fails with the messageConversion.ts change reverted.

Not covered

  • A long hiddenText is stored in localStorage like any other message text, so when storage is full the save can fail silently (same as long messages today). The AI then gets it only while the chat stays open, not after a reload, a reconnect or a chat switch.

🤖 Generated with Claude Code

yuma2024 and others added 4 commits October 28, 2026 13:17
sendMessage(text, { hiddenText }) sends hiddenText to the AI as a text
part before the visible text. It is saved with the message as a
'hidden_text' part, so later turns and reloads still send it, and
getDisplayTextFromContent leaves it out of the bubble, title and chat list.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Skip whitespace-only hiddenText, like the visible message.
- Build the visible text part once and reuse it.
- README: the built-in UI hides it; custom message slots and
  ChatRepository implementations need to handle hidden_text parts.
- Test the user bubble by rendering it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ents

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ntent

getTextFromContent is only called on assistant and tool messages, so
hidden_text never reaches it. getDisplayTextFromContent already reads
only text parts.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@yuma2024
yuma2024 marked this pull request as ready for review October 28, 2026 08:15
@yuma2024 yuma2024 changed the title [WIP] feat(client): add hiddenText to sendMessage feat(client): add hiddenText to sendMessage Oct 28, 2026
@yuma2024
yuma2024 merged commit 893fb2e into main Oct 28, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants