Loops AI Docs

Architecture

How the native container, the typed bridge, and native session ownership work.

The SDK is a native container around the Loops web runtime loaded in mode=sdk. The web owns the conversation UI; native owns the session, routing, and analytics. Understanding this helps you reason about callbacks and security.

The container

LoopsAIChatFragment
  └─ WebView  → chat.loopsai.com/<agentId>?mode=sdk&platform=android…
        ↕ loopsAIBridge (typed message bridge)

LoopsAIChatFragment is the single host; the Activity, Compose, and convenience entry points all wrap it.

The bridge

Native and web talk over a typed message envelope:

{ "protocolVersion": 1, "type": "nativeAction", "name": "productQuoteChanged",
  "requestId": "req_123", "payload": { /* … */ } }
  • Web → native actions drive the host callbacks (ready, message, responding, product quote, conversation active, analytics passthrough, open URL, close).
  • Native → web actions are the methods you call (context updates, search, try-on, size). See Flow modes.
  • Unknown action names are ignored, and the legacy flat { action } shape is rejected. protocolVersion lets a shipped binary evolve without breaking older app versions.

The transport prefers WebViewCompat.addWebMessageListener (which enforces the origin allowlist) and falls back to addJavascriptInterface only when needed.

Native session ownership

The system WebView can wipe partitioned storage, which would lose the anonymous session. The SDK fixes this natively:

  • It bootstraps the session against the runtime and persists the anon session in app-private SharedPreferences (com.loopsai.chat.session).
  • It re-injects the session (_lsuid / _lscid) on every WebView load, and applies persistSession updates the runtime emits.
  • Bootstrap retries transient failures (transport errors and 5xx only) with exponential backoff.

The result: the session survives app relaunch with no extra work on your side. The anon id is pseudonymous — not a credential — so it lives in app-private storage, not EncryptedSharedPreferences.

Security

  • Origin allowlist — only chat.loopsai.com and your custom environment host can drive the bridge; navigation to other origins opens in the system browser instead.
  • Foreign links open in the system browser, never inside the WebView.
  • Camera capture is granted to the WebView only for allowlisted origins, and only when the host app holds the matching permission.
  • WebView debugging is enabled only in debug builds.

Authenticated (non-anonymous) sessions via a token provider are on the roadmap; v1 is anonymous-session based. Today the bridge accepts a token-refresh request but it is a no-op until the auth provider ships.

Host callbacks reference

CallbackFires when
onReadyThe runtime is live; safe to push context.
onRespondingThe assistant starts/stops responding.
onProductQuoteChangedThe active product quote changes (null = cleared).
onAnalyticsEventA canonical analytics event crossed the bridge.
onConversationActiveA conversation becomes active.
onMessageEventA message / new-chat / overlay event.
onCloseRequestedThe runtime asked to close (default: finish/pop).
onOpenUrlRequestedA foreign link should open externally.
onErrorA load / bridge / session error occurred.

On this page