React Native SDK — Release Notes
@revrag-ai/embed-react-native · release history, newest first. Install the latest with npm install @revrag-ai/embed-react-native@^1.3.0; confirm the current version on npm. Never install 1.1.0 — see 1.1.1.
1.3.0: upgrading from 1.2.x
Upgrade
npm install @revrag-ai/embed-react-native@^1.3.0
cd ios && pod install && cd ..No code changes needed. The public API, the peer dependencies (same verified stacks) and the native code are unchanged from 1.2.0. Restart Metro with --reset-cache and rebuild.
The agent's taps now appear in click analytics. They arrive as the same ANALYTICS_DATA events as a person's, with data.source: "agent". If your dashboards or Embed.on(ANALYTICS_DATA) listeners count clicks, filter on data.source — see The agent's taps are reported, tagged.
Changed
The agent's taps are reported, tagged
1.2.0 dropped every tap the agent made during a call. They are now sent like a person's, and data.source tells them apart:
| Who tapped | 1.2.0 | 1.3.0 |
|---|---|---|
| A person | sent, source: "user" | sent, source: "user" |
| The agent, during a call | not sent | sent, source: "agent" |
| The SDK widget's own buttons | not sent | not sent |
This matches the web SDK's data.source. A person tapping the same control right after the agent is sent too — the 300 ms repeat filter now applies per source.
Fixed
The agent no longer acts on the screen behind a modal
With a React Native <Modal> open, the agent could still tap, type into or move a slider on the screen behind it — pressing a control the user couldn't see or reach. The screen behind an open modal is now reported to the agent as not visible, and actions aimed at it are refused; the agent works on the modal itself.
Menus, popovers and toasts don't block the screen behind them, and neither does an overlay parked off-screen. When two modals are open, the one shown last is on top. A sheet that isn't an RN <Modal> counts as part of the screen unless its container sets accessibilityViewIsModal. See Modals and overlays.
Highlights draw on top of an open modal
A highlight on a modal's content was drawn underneath the modal, so the user never saw it. It now draws on top, in the same window as the widget.
1.2.0: upgrading from 1.1.x
Upgrade
npm install @revrag-ai/embed-react-native@^1.2.0
cd ios && pod install && cd ..No code changes needed. Nothing was removed or changed in the public API, the peer dependencies are the same as 1.1.1 (same verified stacks), and no native code changed. Restart Metro with --reset-cache and rebuild.
Click analytics event names and payload change in this release. If your dashboards, funnels or Embed.on(ANALYTICS_DATA) listeners use the SDK's *_pressed events, read Taps on your app are named by what they do before you ship.
Changed
Taps on your app are named by what they do
While the button is visible, the SDK reports taps on Pressable and the Touchable family as ANALYTICS_DATA events. It now follows the Android and web SDKs' naming:
| Touchable's role | 1.1 | 1.2.0 |
|---|---|---|
button, imagebutton, tab | <name>_pressed | <name>_pressed, type: button_click |
checkbox, switch, togglebutton | <name>_pressed | <name>_toggled, type: checkbox_toggle |
radio | <name>_pressed | <name>_selected, type: radio_select |
combobox | <name>_pressed | <name>_opened, type: button_click |
link, or no role | <name>_pressed | <name>_pressed, type: element_click |
The <name> comes from your own id, name or testID first, used as written — an existing submit_pressed stays submit_pressed. Without one, the SDK uses the accessibility label, the visible text or an icon name, cleaned up to at most four words with digits and currency words left out:
| 1.1 | 1.2.0 |
|---|---|
pressable-7_pressed (no id, "Apply Now" text) | apply_now_pressed |
touchableopacity-3_pressed (icon-only back button) | arrow_back_pressed |
dark_mode_pressed (a switch with id="dark_mode") | dark_mode_toggled |
data is now flat: element_id, type, kind, role, checked (the state after the tap), source, click_sequence, component, and legacy_event_name when the name changed, so dashboards can map old names to new. The 1.1 nested metadata: { timestamp, type, component, clickSequence } is gone — move listeners to data.
No longer reported: the SDK widget's own buttons, the agent's own taps, and a second identical event within 300 ms. Text with an email, UPI id or masked number never becomes a name.
See Automatic click / press tracking for the full rules, including how to declare a toggle's state.
The widget follows more of your dashboard
| Dashboard setting | 1.1 | 1.2.0 |
|---|---|---|
Collapsed state (isCollapsed: false) | ignored | the card starts open |
| Left / top padding | fixed spacing | used; a top-anchored button can be dragged down |
| Collapse time, when not set | the card stays open | the card folds after 15 s (paused while captions are on) |
Gradient fill (fillType: "gradient") | left → right | diagonal, as on Android; one gradient color alone themes the card |
| Corner radius | rounded the button and the card | rounds the open card only (default 20); the button stays a pill |
Panel close delay (viewCloseDelay) | not used | how long the calculation panel stays open |
Check the widget on a device after upgrading — the same dashboard settings can look different.
Agent status and captions
- The status line follows Android: "Listening", "Speaking", "Thinking", and a muted state when the user has muted themselves (a muted user used to see "Listening…").
- Captions show the whole sentence; a long answer scrolls instead of ending in "…".
- The captions (CC) badge uses the card's text color, so it stays visible on light cards.
Less text in UI snapshots
UI snapshots no longer carry each element's combined descendant text (subtree_text), so less of each screen's text leaves the device. What is captured, and the redaction rules, are unchanged.
Fixed
A touch on your app stops the agent
Touching your app while the agent was tapping, scrolling or highlighting did nothing — it kept acting over the user. Now what it was doing is cancelled and the highlight disappears. Touches on the SDK widget and the agent's own taps never count.
The agent no longer presses disabled controls
A disabled button kept its onPress, and the agent called it directly, bypassing your guard on a "Pay" or "Submit" button. Disabled touchables and read-only TextInputs are now refused, and targeting the label inside a disabled button no longer taps the card around it.
Resuming the agent keeps a user's mute
resumeAgent() unmuted a user who had muted themselves before the pause. It now unmutes only if the pause muted.
Other fixes
- Events report the correct
sdk_version(1.1.1 reported"1.1.0"). - React Native
rolevalues such asimg,option,listitemandsearchboxare understood by the agent.
1.1.1
Fixes a crash in 1.1.0: every screen that rendered a FlatList or SectionList failed with "Cannot read property 'Consumer' of undefined". Do not install 1.1.0 — go to 1.2.0.
- Patched components keep their statics (
ScrollView.Context,TextInput.State). - The SDK installs its component wrappers when the package loads, not when
EmbedProvidermounts. On 1.1.0, lists and inputs already on screen were remounted once (scroll reset, keyboard dropped). - Jest: a snapshot containing a
<Modal>gains one wrapperViewonce the SDK is imported — update those snapshots.
1.1.0
The Action Intelligence release — the agent can now see and act on your screens — plus a stricter, more predictable integration contract. Upgrading from 1.0.35 requires a few code changes; work through the upgrade steps below.
Breaking changes
| Change | What to do |
|---|---|
appVersion is required in useInitialize | Move it out of EmbedProvider into useInitialize({ apiKey, appVersion }). The provider prop is now an override only. |
navigationRef is required for the widget to appear | Pass the same ref to EmbedProvider and NavigationContainer. Without it the button never shows and startCall() fails. |
Do not call LiveKit's registerGlobals() yourself | Remove it from index.js — useInitialize calls it; a second call duplicates native event listeners. |
| iOS module renamed | import livekit_react_native and LivekitReactNative.setup() (lowercase "k") in AppDelegate.swift — the old import LiveKitReactNative no longer resolves. |
| Android permissions now merged by the SDK | Remove manually added RECORD_AUDIO / MODIFY_AUDIO_SETTINGS — the SDK's manifest merges them (plus BLUETOOTH_CONNECT). Voice-only apps may strip camera with tools:node="remove". |
| ProGuard package changed | Replace -keep class com.revrag.embed.** with -keep class com.revragai.embedreactnative.** { *; }. WebRTC/LiveKit/Lottie ship their own consumer rules — drop those manual keeps. |
| Supported React Native narrowed to 0.76 – 0.86 | Hermes required. RN ≥ 0.82 needs the New-Architecture stack: Reanimated 4.5.2 + react-native-worklets + Gesture Handler 3.x, with react-native-worklets/plugin as the last Babel plugin. See the Dependency & Compatibility Guide. |
New
- Action Intelligence / UI capture — the agent reads the on-screen element tree (
stableIdtargeting viatestID) and can tap, type, select, scroll, and highlight, with action verification. Sensitive-field controls:secureTextEntry(never captured, agent refuses to touch) andnativeID="embed-redact-…"(value masked). - Widget visibility system —
showOnAllScreens,includeScreens,excludeScreens,endCallWhenHiddenByVisibility,embedButtonContinuity,embedButtonDelayMs, and groupedembedButtonVisibilityConfig(per-group delay/inset/continuity). - Agent lifecycle events — one
embedOnAgentsubscription for all events (AGENT_VISIBLE,AGENT_TAP_TO_OPEN/_CLOSE,POPUP_MESSAGE_VISIBLE,AGENT_CONVERSATION_STARTED/_ENDED,GEN_TOOL_TRIGGERED,MICROPHONE_PERMISSION_ALLOWED/_DENIED).AGENT_CONNECTED/AGENT_DISCONNECTEDare deprecated aliases. - Automatic click/press tracking — taps on
Pressableand the Touchable family emitANALYTICS_DATAevents named from the element'sid/nameprop (<id>_pressed). - Manual controls —
startCall/endCall/isCallActive,pauseAgent/resumeAgent,expandWidget/collapseWidget,EmbedLogout,checkPermissions/openAppSettings, andsetScreenMatching(alias/ancestor/structure screen matching). - Screenshot consent props —
sessionScreenshotEnabled/passiveScreenshotEnabled(both defaultfalse, double consent with a backend flag).
Fixed / clarified
startCall()returnsfalseonly when the widget is hidden or unmounted. A missingUSER_DATAno longer rejects — the token request aborts while the promise resolvestrue, so observeAGENT_CONVERSATION_STARTEDfor the real outcome.USER_DATAis persisted only after the backend accepts it — re-send it if it was first sent offline.SCREEN_STATEevents are analytics tags only; they do not drive widget visibility or UI capture.excludeScreensis consulted only inshowOnAllScreensmode; inincludeScreensmode the allow-list alone decides.
Upgrade steps: 1.0.35 → 1.1.0
npm install @revrag-ai/embed-react-native@^1.2.0(never 1.1.0), then re-pin peers per the Dependency & Compatibility Guide and runpod install.- Move
appVersionintouseInitialize; remove it fromEmbedProvider. - Ensure
navigationRefis passed to bothEmbedProviderandNavigationContainer. - Delete any
registerGlobals()call fromindex.js. - Update
AppDelegate.swifttoimport livekit_react_native/LivekitReactNative.setup(). - Remove manually declared Android audio permissions and update the ProGuard keep rule.
- Rebuild fully (
gradlew clean,pod install) and re-test a call on a real device.
1.0.35 and earlier
The pre–Action Intelligence line: floating voice-agent button (LiveKit), route tracking via EmbedProvider, and the four Embed.Event keys (USER_DATA, SCREEN_STATE, CUSTOM_EVENT, ANALYTICS_DATA). Supported React Native 0.70+. No UI capture, no agent actions, no visibility groups. If you are still on this line, upgrade via the steps above — 1.0.x is not maintained.
Support
- Docs: https://docs.revrag.ai
- Email: contact@revrag.ai
- Dashboard: app.revrag.ai