Skip to content

feat(ai-components): bring the AI agent work to V10 - #3979

Open
isekovanic wants to merge 23 commits into
developfrom
feat/stream-agents-and-a2ui-integration
Open

isekovanic wants to merge 23 commits into
developfrom
feat/stream-agents-and-a2ui-integration

Conversation

@isekovanic

Copy link
Copy Markdown
Contributor

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

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 read messages straight from channel.messagePaginator, through a small useAgentMessages hook, and load older pages with toTail(). A followed channel is activated, as <Channel> does, so the client reloads it after a reconnect, and the samples have no recovery code of their own. The only event they still listen to is message.updated, which feeds calypso's LiveReasoning. 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.

🎨 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.

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

  • I have signed the Stream CLA (required)
  • PR targets the develop branch
  • Documentation is updated
  • New code is tested in main example apps, including all possible scenarios
    • SampleApp iOS and Android
    • Expo iOS and Android

…mple on the agents router

Ported from #3921 on v9-release. The AI components read the chat SDK's V10 translation
context, which the entry isolation check now allows.
Ported from #3929 on v9-release. stream-chat 10 keeps mime_type, file_size and the AI fields
under `custom`, so steps and messages read them through withCustomFields, as React does.
Ported from #3944 on v9-release. Pins @legendapp/list at 3.7.1, the version v9 resolves.
The AI and A2UI strings use V10's catalog keys with their English inline, named after the
React SDK's, and keys.ts is regenerated.
Both samples read messages from the channel's messagePaginator, and the AI fields from
`custom`. The crew sample uploads voice memos with uploadChannelFile.
LegendList 3.7.2 keeps fewer rows mounted after a jump, so the test now compares only the rows
that stay mounted and were reused for another reply.
AgentChat no longer copies the messages into a store of its own. It activates the channel, as
<Channel> does, so the client reloads it after a reconnect, and the samples' own recovery goes.
@Stream-SDK-Bot

Copy link
Copy Markdown
Contributor

SDK Size

title develop branch diff status
js_bundle_size 2027 KB 2033 KB +6261 B 🔴
ai_components_size 163 KB 344 KB +185900 B 🔴
a2ui_size n/a 103 KB n/a 🆕

@isekovanic
isekovanic requested a review from oliverlaz November 11, 2026 23:40

This branch has not been deployed

No deployments
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.

2 participants