Repository navigation
feat(ai-components): move AIConversation to its own entry point - #3960
Merged
Merged
Conversation
AIConversation's list uses @legendapp/list/keyboard, which requires react-native-keyboard-controller with no guard. Since ai-components is a single entry and Metro bundles everything it reaches, every app importing from it would need keyboard-controller, even ones only using markdown or the composer. AIConversation now lives in ai-components/conversation, which needs keyboard-controller. The rest of ai-components loads it through one guarded require: with it, ComposerView rides the keyboard; without it, the composer stays put and the "+" button closes the keyboard with RN's Keyboard. The controller and its state stay in ai-components. The entry isolation check keeps ai-components and a2ui away from the conversation and @legendapp/list/keyboard, and only lets internal/keyboard.tsx load keyboard-controller.
Contributor
SDK Size
|
isekovanic
added a commit
that referenced
this pull request
Nov 10, 2026
Ticket: https://linear.app/stream/issue/RN-485 Stacked on #3960, for the `ai-components/conversation` entry. `examples/ExpoCrewAssistant`, a demo of a restaurant team member's assistant on the AI components and the Vision-Agents router. Its agent and backend are `crew_assistant` in GetStream/Vision-Agents#1884. - **Flows:** the home screen has one per use case: clock in (fit-check checklist), call out sick, the handbook with sources, equipment problems (from a photo, a scanned-code link or a message) with a repair ticket, back from time off, onboarding with a menu quiz and check-ins, interview practice, and clock out with a reflection form or a voice memo. - **Speaking first:** for a clock-in, clock-out, return from time off or a new hire, the backend has the agent open the conversation. - **Tools on the phone:** they call the restaurant's systems in the backend. Calls that ask first show above the composer with the AI components' approval card. The team lead view shows what they wrote. - **Voice memos:** on the chat SDK's own recorder (`AudioRecorderManager`, `AudioRecordingInProgress`) and player (`AudioAttachment`). - **Cal.com:** connected from the chat when booking a check-in. Tested on an Android emulator against a local router: every flow end to end, photo troubleshooting, the scan link and the team lead view. Not tested: voice mode, iOS, the Cal.com sign-in itself, and a transcribed memo, since the router's speech-to-text key has no credit.
4 of 6 tasks
isekovanic
added a commit
that referenced
this pull request
Nov 12, 2026
Ticket: https://linear.app/stream/issue/RN-485 ## 🎯 Goal Bring the AI agent work we shipped on `v9-release` to V10: the same components, APIs and sample apps, adapted to stream-chat 10 and the V10 i18n. The long-press Copy/Edit menu on the person's own messages isn't here. It isn't on v9 either, and it comes later as a V10 feature. ## 🛠 Implementation details The branch is one commit per v9 PR, in merge order, then the V10-only changes, so it can be reviewed commit by commit. **Ported from v9** - #3920 parse agent reply steps from message attachments - #3921 AI translations through the chat SDK, sample on the agents router - #3924 agent reply steps: reasoning, tool calls, approvals - #3926 native `AIAgent` module for the install id and tool-call sign-in - #3928 message views, reply actions and icon overrides - #3929 `AIConversation` on LegendList - #3931 chat options, suggestions and attachment preview fixes - #3933 client tool runner - #3934 polish of agent conversations - #3936 generated UI with an A2UI renderer - #3944 follow-up polish of agent conversations - #3958 A2UI list-row secrets and malformed messages - #3957 conversation state with `AIConversationController` - #3960 `AIConversation` in its own entry point - #3963 the crew assistant demo app - #3974 alignment with the other SDKs - #3975 StrictMode-safe controller lifecycle and `custom.uiAction` docs - #3976 crew drawer layout - #3978 the samples on `@stream-io/stream-agents` 0.4.2, in place of calypso and their own chat layer Where `develop` had already changed the same lines (comment cleanups, the i18n move, a11y docs), `develop`'s version wins. **What's different on V10** - **Fields under `custom`.** stream-chat 10 keeps `mime_type`, `file_size`, `ai_generated`, `generating`, `ai_ui` and the step fields under `custom`. `parseMessageParts` and `fromStreamMessage` lift them with a small `withCustomFields` helper, as the React SDK does. - **Translation keys.** The 55 AI and A2UI strings use catalog keys with their English inline, named after React's (`aiComponents.replyActions.copy.accessibilityLabel`, `a2ui.modal.close.label`, …), and `keys.ts` is regenerated. `useAITranslation` returns core's typed `t`. - **Entry isolation.** The AI entry points may reach V10's translation context. `@legendapp/list` and `react-native-keyboard-controller` are AI-only packages. - **LegendList stays at 3.7.1**, the version v9 resolves. 3.7.2 keeps fewer rows mounted after a jump, so the reused-rows test now only compares rows that stay mounted. It passes on both versions. - **Sample data layer.** Both samples use stream-agents' `AgentChat`, whose stream-chat 10 reader reads `channel.messagePaginator`, activates the channel so the client reloads it after a reconnect, and loads older pages with `toTail()`. The samples read the reply fields from `custom`, and the crew sample uploads voice memos with `uploadChannelFile`. - **Sample dependencies.** Both samples depend on `@stream-io/state-store` and `use-sync-external-store`, and pin `@stream-io/state-store` to one copy in `tsconfig` paths. They stay on stream-chat `^10.0.1`: stream-agents asks for `^10.0.2`, but only when it builds its own client, and the samples hand it theirs. ## 🎨 UI Changes None compared with v9. The screenshots are in the v9 PRs above. ## 🧪 Testing `yarn lint`, `yarn typecheck`, `test:typecheck`, the unit tests and `yarn build` pass, and both samples typecheck. On an Android emulator and an iOS simulator: - **ChatGPT sample:** reasoning, the device time tool, the generated Lisbon plan, the drawer, reopening a conversation from history, and starters on a new one. - **Crew sample:** - all eight flows, including the approval cards, the checklist and form actions, and the agent-first ones; - the equipment deep link, photo troubleshooting and the team lead view; - voice memos, recorded on the simulator with `say` and answered; - the clock-out form on iOS. - **Reconnect:** the network was dropped mid-reply on both samples. The client recovered the active channel, and the full reply appeared. - **Older messages:** with the page size briefly set to 3, older pages loaded until there were none left. After the move to stream-agents, both samples were checked again on both platforms: replies, the device time tool, the agent-first Clock in flow, the drawer, reopening from history, handbook sources, and an approval card into A2UI. Reconnect, older pages and voice memos were tested on the samples' previous chat layer, not again since. Not tested here: voice mode (the simulator's speech recognition doesn't hear `say`), dictation, Cal.com sign-in, and charts or photos in the ChatGPT sample. ## ☑️ Checklist - [x] I have signed the [Stream CLA](https://docs.google.com/forms/d/e/1FAIpQLScFKsKkAJI7mhCr7K9rEIOpqIDThrWxuvxnwUq2XkHyG154vQ/viewform) (required) - [x] PR targets the `develop` branch - [x] Documentation is updated - [ ] New code is tested in main example apps, including all possible scenarios - [ ] SampleApp iOS and Android - [x] Expo iOS and Android
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Ticket: https://linear.app/stream/issue/RN-485
AIConversation's list uses@legendapp/list/keyboard, which requiresreact-native-keyboard-controllerwithout a guard.ai-componentsis one entry and Metro bundles everything it reaches, so any app importing from it would need keyboard-controller after upgrading, including apps on 9.12 that only use markdown,StreamingMessageVieworComposerView.AIConversationhas its own entry point:stream-chat-react-native/ai-components/conversation(stream-chat-expo/ai-components/conversation). It needs keyboard-controller with aKeyboardProviderabove it. Only the view and its props types moved;AIConversationController,useAIConversationState,AIMessageandfromStreamMessagestay inai-components.ai-componentsloads it through one guardedrequire. With it,ComposerViewrides the keyboard and "+" waits for the keyboard to close before opening the sheet. Without it, the composer doesn't move and "+" closes the keyboard with RN'sKeyboard.ai-componentsanda2uifrom reaching the conversation or@legendapp/list/keyboard, and fails if any file other thaninternal/keyboard.tsximports keyboard-controller.AIConversationisn't released yet, so nothing breaks. The sample, the ai-components README and AGENTS.md use the new import.Tests cover the composer and sheet without keyboard-controller. Lint, typecheck, unit tests and build pass. Checked in ExpoChatGPTSample on an Android emulator: asking pins the question, the composer rides the keyboard, and the "+" sheet opens after the keyboard closes.