@graineai/inapp-react-native 0.26.0 → 0.26.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/INTEGRATION.md CHANGED
@@ -819,11 +819,18 @@ fourth. The guarantees, so you do not have to think about them:
819
819
  applies only to the SDK's own text socket, never to a host's channel.
820
820
  - **Ordered.** Every context frame carries a monotonic `seq`; the runtime keeps
821
821
  the newest and drops anything that arrives late. The last screen always wins.
822
- - **Cleanup-safe.** A screen's unmount clears the screen only if it is still
823
- the one being described (`client.clearScreen(id)`), so a navigation library
824
- unmounting the old screen after the new one mounted cannot erase it.
822
+ - **Cleanup-safe.** The description is re-sent whenever its state changes and
823
+ withdrawn only on unmount — never on a change (0.26.2; earlier versions sent
824
+ a screen-less frame before every navigation). The withdrawal clears the
825
+ screen only if it is still the one being described (`client.clearScreen(id)`),
826
+ so a navigation library unmounting the old screen after the new one mounted
827
+ cannot erase it.
825
828
  - **Reconnect-safe.** The newest context is replayed whenever the media or the
826
829
  screen channel (re)connects.
830
+ - **Self-healing.** The newest screen is re-asserted every few seconds during
831
+ a call and when the app returns to the foreground, with its original
832
+ sequence number — so a frame lost in flight is repaired within seconds, not
833
+ at the next screen change; one that arrived is simply ignored.
827
834
  - **Applied every turn.** The runtime puts the last-reported screen on the
828
835
  prompt at every generation, so nothing that rewrites the prompt mid-call — a
829
836
  language switch, a summary — can make the agent forget where the customer is.
@@ -916,7 +923,7 @@ told to ignore).
916
923
 
917
924
  | Prop | Type | Notes |
918
925
  |---|---|---|
919
- | `publishableKey` | `string` | Required unless you pass `client`. |
926
+ | `publishableKey` | `string` | Required unless you pass `client`. Selects the agent — one key per agent; there is no `agentId` prop. |
920
927
  | `baseUrl` | `string` | Defaults to Graine's host. |
921
928
  | `client` | `GraineInAppClient` | Use **your** instance instead of building one. Pass this if your app has a module-level client. |
922
929
  | `navigationRef` | `ref` | The same ref you give `NavigationContainer`. Makes the agent screen-aware with no per-screen code. |
@@ -346,8 +346,12 @@ export function useGraineScreen(context) {
346
346
  const serialised = JSON.stringify(context ?? null);
347
347
  useEffect(() => {
348
348
  client.setScreen(context);
349
- return () => client.clearScreen(context?.screen);
350
349
  }, [client, serialised]);
350
+ const reported = useRef(context?.screen);
351
+ reported.current = context?.screen;
352
+ useEffect(() => () => {
353
+ client.clearScreen(reported.current);
354
+ }, [client]);
351
355
  }
352
356
  export function useGraineField(name, field) {
353
357
  const client = useGraineClient();
@@ -192,6 +192,7 @@ export function GraineVoiceLauncher({ webView: WebView, autoStart = false, trans
192
192
  clearTimeout(pending);
193
193
  pending = null;
194
194
  }
195
+ pushContext();
195
196
  return;
196
197
  }
197
198
  if (next === "background" && wasActive && !pending) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@graineai/inapp-react-native",
3
- "version": "0.26.0",
3
+ "version": "0.26.2",
4
4
  "type": "module",
5
5
  "description": "Graine in-app agent for React Native — an agent that sees the screen your customer is on and can act on it.",
6
6
  "license": "MIT",