@ateam-ai-mobile/plugin-runtime 0.1.19 → 0.1.21

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/dist/index.d.mts CHANGED
@@ -1245,6 +1245,74 @@ interface VoiceAPI {
1245
1245
  transcript(): VoiceTranscriptEntry[];
1246
1246
  }
1247
1247
 
1248
+ type AiLiveCamera = 'front' | 'back';
1249
+ /** What the AI saw over time, as the live session's episode events. */
1250
+ interface AiLiveEpisode {
1251
+ /** episode.started / .interrupted / .recovered / .ongoing / .ended */
1252
+ type: string;
1253
+ /** The task class id from the chosen setup, e.g. "drinking". */
1254
+ class: string;
1255
+ episodeId: string;
1256
+ /** When (ms since the epoch, the session's clock). */
1257
+ at: number;
1258
+ [key: string]: unknown;
1259
+ }
1260
+ type AiLiveState =
1261
+ /** Nothing running for this screen. */
1262
+ 'idle'
1263
+ /** Asking for the live session, opening the camera and the connection. */
1264
+ | 'starting'
1265
+ /** Pictures are going to the AI ("Sending to AI" is on screen). */
1266
+ | 'sending'
1267
+ /** Stopped by stop() or by the screen closing. */
1268
+ | 'stopped'
1269
+ /** It could not start or it broke; `lastError` says why in plain words. */
1270
+ | 'error';
1271
+ interface AiLiveSnapshot {
1272
+ state: AiLiveState;
1273
+ camera: AiLiveCamera | null;
1274
+ /** Pictures sent since start. */
1275
+ sent: number;
1276
+ /** Picture slots that sent nothing (no fresh camera frame, or the connection was busy). */
1277
+ skipped: number;
1278
+ lastEpisode: AiLiveEpisode | null;
1279
+ lastError: string | null;
1280
+ }
1281
+ interface AiLiveStartOptions {
1282
+ /** Which camera: 'back' (default) or 'front', the selfie camera. */
1283
+ camera?: AiLiveCamera;
1284
+ }
1285
+ interface AiLiveAPI {
1286
+ /** Start sending this phone's camera to the chosen AI. Refuses by name when either
1287
+ * side has not said yes, or when another screen is sending already. */
1288
+ start(opts?: AiLiveStartOptions): Promise<AiLiveSnapshot>;
1289
+ /** Stop sending. Closing the screen does the same. */
1290
+ stop(): Promise<void>;
1291
+ getSnapshot(): AiLiveSnapshot;
1292
+ /** Called with every episode event the AI makes while this screen sends. */
1293
+ onEpisode(cb: (ev: AiLiveEpisode) => void): Subscription;
1294
+ /** Called whenever the snapshot changes. */
1295
+ subscribe(cb: (snap: AiLiveSnapshot) => void): Subscription;
1296
+ }
1297
+ /** What the host supplies (setAiLiveProvider). `owner` is the screen's holder id,
1298
+ * captured by the gate — a plugin never supplies its own. */
1299
+ interface AiLiveProvider {
1300
+ start(opts: AiLiveStartOptions, owner: string, ctx: {
1301
+ visual: DeviceState['visual'];
1302
+ }): Promise<AiLiveSnapshot>;
1303
+ stop(owner: string): Promise<void>;
1304
+ getSnapshot(owner: string): AiLiveSnapshot;
1305
+ onEpisode(cb: (ev: AiLiveEpisode) => void, owner: string): Subscription;
1306
+ subscribe(cb: (snap: AiLiveSnapshot) => void, owner: string): Subscription;
1307
+ /** The screen is gone: drop its callbacks and its last snapshot (after stop). */
1308
+ forget(owner: string): void;
1309
+ /** Whether ANY screen is sending right now — what the platform's indicator shows. */
1310
+ isSending(): boolean;
1311
+ /** Any change of isSending(). */
1312
+ subscribeSending(cb: () => void): Subscription;
1313
+ }
1314
+ declare const AI_LIVE_IDLE: AiLiveSnapshot;
1315
+
1248
1316
  /**
1249
1317
  * @adas/plugin-sdk — Type definitions
1250
1318
  *
@@ -1821,6 +1889,11 @@ interface NativeCapabilities$1 {
1821
1889
  nfc?: boolean;
1822
1890
  /** Real biometric auth (Face ID / Touch ID / fingerprint). */
1823
1891
  biometricsV2?: boolean;
1892
+ /** The developer's half of "camera pictures may go to an AI service off the
1893
+ * phone". Declaring it grants nothing by itself: the person on the phone must
1894
+ * also allow it in the host's settings. Both are checked together by
1895
+ * `mayPicturesLeavePhone()`. Not declared = pictures never leave. */
1896
+ picturesToAi?: boolean;
1824
1897
  }
1825
1898
  interface PluginHooks$1 {
1826
1899
  onAppStart?: boolean;
@@ -1912,6 +1985,14 @@ interface PluginProps {
1912
1985
  * plugin gets a refusal (reads say so, actions throw) — never a fake `idle`.
1913
1986
  */
1914
1987
  voice: VoiceAPI;
1988
+ /**
1989
+ * The workspace's CHOSEN AI watching the phone camera, live — gated to plugins
1990
+ * that declared `capabilities: { picturesToAi: true }` AND used only when the
1991
+ * person on the phone allowed "Pictures to AI". The screen gets episodes
1992
+ * ("drinking" started), never pictures; "Sending to AI" is platform-owned.
1993
+ * REQUIRED like `voice`: an undeclared plugin gets a refusal, never a fake idle.
1994
+ */
1995
+ aiLive: AiLiveAPI;
1915
1996
  theme: ThemeTokens;
1916
1997
  context: PluginContext;
1917
1998
  /** Engine-supplied props from `sys.focusUiPlugin(pluginId, props)`.
@@ -2287,6 +2368,24 @@ declare function implementedVoice(): boolean;
2287
2368
  */
2288
2369
  declare function gateVoice(declared: boolean, pluginId: string): VoiceAPI;
2289
2370
 
2371
+ /** Host DI: the app supplies the live provider once at startup; null detaches it. */
2372
+ declare function setAiLiveProvider(provider: AiLiveProvider | null): void;
2373
+ /**
2374
+ * The `aiLive` a plugin receives. `capabilities` is its TRUSTED declaration
2375
+ * (pluginRuntime.ts); `holder` is the mounted screen it is bound to; `camera()` gives
2376
+ * the visual session the SDK's sender reads, held as aiLiveCameraHolder(holder). It
2377
+ * is built by resolvePluginRuntimeProps (the one place device gates are called) and
2378
+ * never reaches the plugin: the plugin gets episodes, the sender gets the camera.
2379
+ */
2380
+ declare function gateAiLive(capabilities: NativeCapabilities$1 | undefined, pluginId: string, holder: string, camera: () => DeviceState['visual']): AiLiveAPI;
2381
+ /** The screen closed: stop its live session and release its camera. */
2382
+ declare function releaseAiLive(holder: string): Promise<void>;
2383
+ /** For the platform's "Sending to AI" indicator: is any screen sending, and when that changes. */
2384
+ declare const aiLiveIndicator: {
2385
+ isSending: () => boolean;
2386
+ subscribe: (cb: () => void) => Subscription;
2387
+ };
2388
+
2290
2389
  /**
2291
2390
  * Host integration points — the DI seams that keep this package free of
2292
2391
  * Expo imports. The host app (or @ateam-ai-mobile/expo) plugs in concrete providers
@@ -2324,6 +2423,12 @@ declare function setCameraPreviewProvider(Component: ((props: CameraPreviewImplP
2324
2423
  /** Null when the host installed none — the SDK then renders a stated reason,
2325
2424
  * never a black rectangle that looks like a dark room. */
2326
2425
  declare function getCameraPreviewProvider(): ((props: CameraPreviewImplProps) => any) | null;
2426
+ /** Install the host's answer to "did the person on this phone allow camera
2427
+ * pictures to go to AI?". Pass null to remove it (consent then reads as no). */
2428
+ declare function setPicturesToAiConsentProvider(provider: (() => boolean) | null): void;
2429
+ /** The one check: true only when the plugin's trusted declaration includes
2430
+ * `picturesToAi` AND the person on the phone allowed it right now. */
2431
+ declare function mayPicturesLeavePhone(declared?: NativeCapabilities$1 | null): boolean;
2327
2432
  type PluginResolver = RegisteredPlugin | (() => Promise<RegisteredPlugin | null>);
2328
2433
  declare function registerNativePlugin(id: string, plugin: PluginResolver): void;
2329
2434
  declare function unregisterNativePlugin(id: string): void;
@@ -2352,6 +2457,8 @@ interface PluginRuntimeProps {
2352
2457
  native: PluginNative;
2353
2458
  deviceState: DeviceState;
2354
2459
  voice: VoiceAPI;
2460
+ /** The workspace's chosen AI watching the phone camera, live (`picturesToAi`). */
2461
+ aiLive: AiLiveAPI;
2355
2462
  }
2356
2463
  /** One declaration source — either the server manifest or the registry entry. */
2357
2464
  interface PluginDeclaration {
@@ -3347,4 +3454,4 @@ declare function isInlineSurface(m: SurfaceManifest): m is InlineSurfaceManifest
3347
3454
 
3348
3455
  declare function SurfaceDispatcher(): react_jsx_runtime.JSX.Element;
3349
3456
 
3350
- export { ActionButton, type ActivitySnapshot, AdaOrb, type AdaOrbState, Badge, type BiometricsAPI, type BiometricsAPIv2, type BluetoothAPI, type BluetoothDevice, type Bridge, type BundleCacheEntry, type BundleStorage, type CameraAPI, CameraPreview, type CameraPreviewProps, type CapabilitySnapshot, type CapabilityStatus, Card, type Confidence, type ConnectivityAPI, type ConnectivitySnapshot, type CookiesAPI, type DeviceBridgeDomain, type DeviceContextSnapshot, type DeviceState, type DeviceToolContext, type DeviceToolDefinition, type DeviceToolFailureReason, type DeviceToolFn, type DeviceToolOutcome, type DeviceToolSummary, type DeviceToolsAction, type DeviceToolsSessionDeps, EmptyState, type EnvironmentSnapshot, ErrorState, type FileSystemAPI, type Freshness, type HapticsAPI, type InlineSurfaceManifest, type InteractionSnapshot, ListItem, type LoadedBundleInfo, type LoadedBundleSource, LoadingState, type LocationAPI, type MapsAPI, type MapsAddress, type MapsCoordinate, type MapsPlace, type MapsRoute, type MapsRouteStep, MemoryBundleStorage, type MountSurfaceManifest, type NativeCapabilities$1 as NativeCapabilities, type NfcAPI, type NotificationsAPI, PLATFORM_VOICE_CALLER, type PluginManifest as PlatformPluginManifest, type PluginBridge, type PluginContext, type PluginGrants, type PluginHooks$1 as PluginHooks, type PluginManifest$1 as PluginManifest, type PluginNative, type PluginProps, type PluginRuntimeProps, type PluginRuntimeSource, PluginSDK, type PluginSummary, type PluginSurfaceMeta, type RegisteredPlugin, type RegisteredServicePlugin, type RegisteredToolsPlugin, type RegisteredUIPlugin, type RemotePlugin, type RenderMode, type ScannerAPI, SearchBar, type SessionSnapshot, type SharingAPI, type SpatialEvent, type SpatialIntent, type SpatialPoint, type SpatialSnapshot, type SpatialStateEvent, type StateEvent, type StateListener, type StateQuality, type StorageAPI, type Subscription, SurfaceCard, type SurfaceCardProps, SurfaceDispatcher, SurfaceDrawer, type SurfaceDrawerProps, SurfaceFullscreen, type SurfaceFullscreenProps, type SurfaceManifest, type SurfacePlacement, type SurfaceType, type SurfaceVisibility, TabBar, type ThemeTokens, type TrustedToolDeclaration, type VisionAPI, type VisionFrameQuality, type VisionLabel, type VisionObject, type VisionText, type VisualSnapshot, type VisualStartOptions, type VoiceAPI, type VoiceCaller, type VoiceDeviceToolCall, type VoiceDeviceToolReason, type VoiceEvent, type VoicePersona, type VoiceSessionProvider, type VoiceSnapshot, type VoiceStartOptions, type VoiceState, type VoiceSubscription, type VoiceTranscriptEntry, type WebViewCookie, __resetSessionSyncForTest, bundleManager, callDeviceTool, clearDeviceTools, createNativeBridge, deviceStateHolders, deviceState as deviceStateV2, deviceToolsActionForSession, ensureDeviceToolsLoaded, explainCapability, gateDeviceState, gatePluginNative, gateVoice, getCameraPreviewProvider, getHaptics, getNativeBundleHash, getNativeBundleUrl, getNativeComponentId, getPlugin, getPluginNative, handleServerDeviceToolCall, hasDeviceTool, implementedStateDomains, implementedVoice, isActionable, isDeviceToolCommand, isInlineSurface, isMountSurface, listDeviceTools, listPlugins, nativePluginRegistry, neverObserved, pluginBundleUrl, register, registerBundleModules, registerDeviceTools, registerNativePlugin, registerPlatformDeviceTools, registerService, registerTools, releaseDeviceStateHolds, rendersNative, resetDeviceToolLoader, resolvePluginGrants, resolvePluginRuntimeProps, resolvePluginUrl, setBundleStorage, setCameraPreviewProvider, setDeviceStateProvider, setDeviceToolContextProvider, setDeviceToolResultPoster, setHapticsProvider, setPluginNativeProvider, setPluginThemeColors, setVoiceProvider, supportsNative, supportsWebView, syncDeviceToolsForSession, unregisterDeviceTools, unregisterNativePlugin, useApi, useNativeBridge, usePlugin, usePluginRuntimeProps, usePluginTheme, useRemotePlugins, useSurfaceStore };
3457
+ export { AI_LIVE_IDLE, ActionButton, type ActivitySnapshot, AdaOrb, type AdaOrbState, type AiLiveAPI, type AiLiveCamera, type AiLiveEpisode, type AiLiveProvider, type AiLiveSnapshot, type AiLiveStartOptions, type AiLiveState, Badge, type BiometricsAPI, type BiometricsAPIv2, type BluetoothAPI, type BluetoothDevice, type Bridge, type BundleCacheEntry, type BundleStorage, type CameraAPI, CameraPreview, type CameraPreviewProps, type CapabilitySnapshot, type CapabilityStatus, Card, type Confidence, type ConnectivityAPI, type ConnectivitySnapshot, type CookiesAPI, type DeviceBridgeDomain, type DeviceContextSnapshot, type DeviceState, type DeviceToolContext, type DeviceToolDefinition, type DeviceToolFailureReason, type DeviceToolFn, type DeviceToolOutcome, type DeviceToolSummary, type DeviceToolsAction, type DeviceToolsSessionDeps, EmptyState, type EnvironmentSnapshot, ErrorState, type FileSystemAPI, type Freshness, type HapticsAPI, type InlineSurfaceManifest, type InteractionSnapshot, ListItem, type LoadedBundleInfo, type LoadedBundleSource, LoadingState, type LocationAPI, type MapsAPI, type MapsAddress, type MapsCoordinate, type MapsPlace, type MapsRoute, type MapsRouteStep, MemoryBundleStorage, type MountSurfaceManifest, type NativeCapabilities$1 as NativeCapabilities, type NfcAPI, type NotificationsAPI, PLATFORM_VOICE_CALLER, type PluginManifest as PlatformPluginManifest, type PluginBridge, type PluginContext, type PluginGrants, type PluginHooks$1 as PluginHooks, type PluginManifest$1 as PluginManifest, type PluginNative, type PluginProps, type PluginRuntimeProps, type PluginRuntimeSource, PluginSDK, type PluginSummary, type PluginSurfaceMeta, type RegisteredPlugin, type RegisteredServicePlugin, type RegisteredToolsPlugin, type RegisteredUIPlugin, type RemotePlugin, type RenderMode, type ScannerAPI, SearchBar, type SessionSnapshot, type SharingAPI, type SpatialEvent, type SpatialIntent, type SpatialPoint, type SpatialSnapshot, type SpatialStateEvent, type StateEvent, type StateListener, type StateQuality, type StorageAPI, type Subscription, SurfaceCard, type SurfaceCardProps, SurfaceDispatcher, SurfaceDrawer, type SurfaceDrawerProps, SurfaceFullscreen, type SurfaceFullscreenProps, type SurfaceManifest, type SurfacePlacement, type SurfaceType, type SurfaceVisibility, TabBar, type ThemeTokens, type TrustedToolDeclaration, type VisionAPI, type VisionFrameQuality, type VisionLabel, type VisionObject, type VisionText, type VisualSnapshot, type VisualStartOptions, type VoiceAPI, type VoiceCaller, type VoiceDeviceToolCall, type VoiceDeviceToolReason, type VoiceEvent, type VoicePersona, type VoiceSessionProvider, type VoiceSnapshot, type VoiceStartOptions, type VoiceState, type VoiceSubscription, type VoiceTranscriptEntry, type WebViewCookie, __resetSessionSyncForTest, aiLiveIndicator, bundleManager, callDeviceTool, clearDeviceTools, createNativeBridge, deviceStateHolders, deviceState as deviceStateV2, deviceToolsActionForSession, ensureDeviceToolsLoaded, explainCapability, gateAiLive, gateDeviceState, gatePluginNative, gateVoice, getCameraPreviewProvider, getHaptics, getNativeBundleHash, getNativeBundleUrl, getNativeComponentId, getPlugin, getPluginNative, handleServerDeviceToolCall, hasDeviceTool, implementedStateDomains, implementedVoice, isActionable, isDeviceToolCommand, isInlineSurface, isMountSurface, listDeviceTools, listPlugins, mayPicturesLeavePhone, nativePluginRegistry, neverObserved, pluginBundleUrl, register, registerBundleModules, registerDeviceTools, registerNativePlugin, registerPlatformDeviceTools, registerService, registerTools, releaseAiLive, releaseDeviceStateHolds, rendersNative, resetDeviceToolLoader, resolvePluginGrants, resolvePluginRuntimeProps, resolvePluginUrl, setAiLiveProvider, setBundleStorage, setCameraPreviewProvider, setDeviceStateProvider, setDeviceToolContextProvider, setDeviceToolResultPoster, setHapticsProvider, setPicturesToAiConsentProvider, setPluginNativeProvider, setPluginThemeColors, setVoiceProvider, supportsNative, supportsWebView, syncDeviceToolsForSession, unregisterDeviceTools, unregisterNativePlugin, useApi, useNativeBridge, usePlugin, usePluginRuntimeProps, usePluginTheme, useRemotePlugins, useSurfaceStore };
package/dist/index.d.ts CHANGED
@@ -1245,6 +1245,74 @@ interface VoiceAPI {
1245
1245
  transcript(): VoiceTranscriptEntry[];
1246
1246
  }
1247
1247
 
1248
+ type AiLiveCamera = 'front' | 'back';
1249
+ /** What the AI saw over time, as the live session's episode events. */
1250
+ interface AiLiveEpisode {
1251
+ /** episode.started / .interrupted / .recovered / .ongoing / .ended */
1252
+ type: string;
1253
+ /** The task class id from the chosen setup, e.g. "drinking". */
1254
+ class: string;
1255
+ episodeId: string;
1256
+ /** When (ms since the epoch, the session's clock). */
1257
+ at: number;
1258
+ [key: string]: unknown;
1259
+ }
1260
+ type AiLiveState =
1261
+ /** Nothing running for this screen. */
1262
+ 'idle'
1263
+ /** Asking for the live session, opening the camera and the connection. */
1264
+ | 'starting'
1265
+ /** Pictures are going to the AI ("Sending to AI" is on screen). */
1266
+ | 'sending'
1267
+ /** Stopped by stop() or by the screen closing. */
1268
+ | 'stopped'
1269
+ /** It could not start or it broke; `lastError` says why in plain words. */
1270
+ | 'error';
1271
+ interface AiLiveSnapshot {
1272
+ state: AiLiveState;
1273
+ camera: AiLiveCamera | null;
1274
+ /** Pictures sent since start. */
1275
+ sent: number;
1276
+ /** Picture slots that sent nothing (no fresh camera frame, or the connection was busy). */
1277
+ skipped: number;
1278
+ lastEpisode: AiLiveEpisode | null;
1279
+ lastError: string | null;
1280
+ }
1281
+ interface AiLiveStartOptions {
1282
+ /** Which camera: 'back' (default) or 'front', the selfie camera. */
1283
+ camera?: AiLiveCamera;
1284
+ }
1285
+ interface AiLiveAPI {
1286
+ /** Start sending this phone's camera to the chosen AI. Refuses by name when either
1287
+ * side has not said yes, or when another screen is sending already. */
1288
+ start(opts?: AiLiveStartOptions): Promise<AiLiveSnapshot>;
1289
+ /** Stop sending. Closing the screen does the same. */
1290
+ stop(): Promise<void>;
1291
+ getSnapshot(): AiLiveSnapshot;
1292
+ /** Called with every episode event the AI makes while this screen sends. */
1293
+ onEpisode(cb: (ev: AiLiveEpisode) => void): Subscription;
1294
+ /** Called whenever the snapshot changes. */
1295
+ subscribe(cb: (snap: AiLiveSnapshot) => void): Subscription;
1296
+ }
1297
+ /** What the host supplies (setAiLiveProvider). `owner` is the screen's holder id,
1298
+ * captured by the gate — a plugin never supplies its own. */
1299
+ interface AiLiveProvider {
1300
+ start(opts: AiLiveStartOptions, owner: string, ctx: {
1301
+ visual: DeviceState['visual'];
1302
+ }): Promise<AiLiveSnapshot>;
1303
+ stop(owner: string): Promise<void>;
1304
+ getSnapshot(owner: string): AiLiveSnapshot;
1305
+ onEpisode(cb: (ev: AiLiveEpisode) => void, owner: string): Subscription;
1306
+ subscribe(cb: (snap: AiLiveSnapshot) => void, owner: string): Subscription;
1307
+ /** The screen is gone: drop its callbacks and its last snapshot (after stop). */
1308
+ forget(owner: string): void;
1309
+ /** Whether ANY screen is sending right now — what the platform's indicator shows. */
1310
+ isSending(): boolean;
1311
+ /** Any change of isSending(). */
1312
+ subscribeSending(cb: () => void): Subscription;
1313
+ }
1314
+ declare const AI_LIVE_IDLE: AiLiveSnapshot;
1315
+
1248
1316
  /**
1249
1317
  * @adas/plugin-sdk — Type definitions
1250
1318
  *
@@ -1821,6 +1889,11 @@ interface NativeCapabilities$1 {
1821
1889
  nfc?: boolean;
1822
1890
  /** Real biometric auth (Face ID / Touch ID / fingerprint). */
1823
1891
  biometricsV2?: boolean;
1892
+ /** The developer's half of "camera pictures may go to an AI service off the
1893
+ * phone". Declaring it grants nothing by itself: the person on the phone must
1894
+ * also allow it in the host's settings. Both are checked together by
1895
+ * `mayPicturesLeavePhone()`. Not declared = pictures never leave. */
1896
+ picturesToAi?: boolean;
1824
1897
  }
1825
1898
  interface PluginHooks$1 {
1826
1899
  onAppStart?: boolean;
@@ -1912,6 +1985,14 @@ interface PluginProps {
1912
1985
  * plugin gets a refusal (reads say so, actions throw) — never a fake `idle`.
1913
1986
  */
1914
1987
  voice: VoiceAPI;
1988
+ /**
1989
+ * The workspace's CHOSEN AI watching the phone camera, live — gated to plugins
1990
+ * that declared `capabilities: { picturesToAi: true }` AND used only when the
1991
+ * person on the phone allowed "Pictures to AI". The screen gets episodes
1992
+ * ("drinking" started), never pictures; "Sending to AI" is platform-owned.
1993
+ * REQUIRED like `voice`: an undeclared plugin gets a refusal, never a fake idle.
1994
+ */
1995
+ aiLive: AiLiveAPI;
1915
1996
  theme: ThemeTokens;
1916
1997
  context: PluginContext;
1917
1998
  /** Engine-supplied props from `sys.focusUiPlugin(pluginId, props)`.
@@ -2287,6 +2368,24 @@ declare function implementedVoice(): boolean;
2287
2368
  */
2288
2369
  declare function gateVoice(declared: boolean, pluginId: string): VoiceAPI;
2289
2370
 
2371
+ /** Host DI: the app supplies the live provider once at startup; null detaches it. */
2372
+ declare function setAiLiveProvider(provider: AiLiveProvider | null): void;
2373
+ /**
2374
+ * The `aiLive` a plugin receives. `capabilities` is its TRUSTED declaration
2375
+ * (pluginRuntime.ts); `holder` is the mounted screen it is bound to; `camera()` gives
2376
+ * the visual session the SDK's sender reads, held as aiLiveCameraHolder(holder). It
2377
+ * is built by resolvePluginRuntimeProps (the one place device gates are called) and
2378
+ * never reaches the plugin: the plugin gets episodes, the sender gets the camera.
2379
+ */
2380
+ declare function gateAiLive(capabilities: NativeCapabilities$1 | undefined, pluginId: string, holder: string, camera: () => DeviceState['visual']): AiLiveAPI;
2381
+ /** The screen closed: stop its live session and release its camera. */
2382
+ declare function releaseAiLive(holder: string): Promise<void>;
2383
+ /** For the platform's "Sending to AI" indicator: is any screen sending, and when that changes. */
2384
+ declare const aiLiveIndicator: {
2385
+ isSending: () => boolean;
2386
+ subscribe: (cb: () => void) => Subscription;
2387
+ };
2388
+
2290
2389
  /**
2291
2390
  * Host integration points — the DI seams that keep this package free of
2292
2391
  * Expo imports. The host app (or @ateam-ai-mobile/expo) plugs in concrete providers
@@ -2324,6 +2423,12 @@ declare function setCameraPreviewProvider(Component: ((props: CameraPreviewImplP
2324
2423
  /** Null when the host installed none — the SDK then renders a stated reason,
2325
2424
  * never a black rectangle that looks like a dark room. */
2326
2425
  declare function getCameraPreviewProvider(): ((props: CameraPreviewImplProps) => any) | null;
2426
+ /** Install the host's answer to "did the person on this phone allow camera
2427
+ * pictures to go to AI?". Pass null to remove it (consent then reads as no). */
2428
+ declare function setPicturesToAiConsentProvider(provider: (() => boolean) | null): void;
2429
+ /** The one check: true only when the plugin's trusted declaration includes
2430
+ * `picturesToAi` AND the person on the phone allowed it right now. */
2431
+ declare function mayPicturesLeavePhone(declared?: NativeCapabilities$1 | null): boolean;
2327
2432
  type PluginResolver = RegisteredPlugin | (() => Promise<RegisteredPlugin | null>);
2328
2433
  declare function registerNativePlugin(id: string, plugin: PluginResolver): void;
2329
2434
  declare function unregisterNativePlugin(id: string): void;
@@ -2352,6 +2457,8 @@ interface PluginRuntimeProps {
2352
2457
  native: PluginNative;
2353
2458
  deviceState: DeviceState;
2354
2459
  voice: VoiceAPI;
2460
+ /** The workspace's chosen AI watching the phone camera, live (`picturesToAi`). */
2461
+ aiLive: AiLiveAPI;
2355
2462
  }
2356
2463
  /** One declaration source — either the server manifest or the registry entry. */
2357
2464
  interface PluginDeclaration {
@@ -3347,4 +3454,4 @@ declare function isInlineSurface(m: SurfaceManifest): m is InlineSurfaceManifest
3347
3454
 
3348
3455
  declare function SurfaceDispatcher(): react_jsx_runtime.JSX.Element;
3349
3456
 
3350
- export { ActionButton, type ActivitySnapshot, AdaOrb, type AdaOrbState, Badge, type BiometricsAPI, type BiometricsAPIv2, type BluetoothAPI, type BluetoothDevice, type Bridge, type BundleCacheEntry, type BundleStorage, type CameraAPI, CameraPreview, type CameraPreviewProps, type CapabilitySnapshot, type CapabilityStatus, Card, type Confidence, type ConnectivityAPI, type ConnectivitySnapshot, type CookiesAPI, type DeviceBridgeDomain, type DeviceContextSnapshot, type DeviceState, type DeviceToolContext, type DeviceToolDefinition, type DeviceToolFailureReason, type DeviceToolFn, type DeviceToolOutcome, type DeviceToolSummary, type DeviceToolsAction, type DeviceToolsSessionDeps, EmptyState, type EnvironmentSnapshot, ErrorState, type FileSystemAPI, type Freshness, type HapticsAPI, type InlineSurfaceManifest, type InteractionSnapshot, ListItem, type LoadedBundleInfo, type LoadedBundleSource, LoadingState, type LocationAPI, type MapsAPI, type MapsAddress, type MapsCoordinate, type MapsPlace, type MapsRoute, type MapsRouteStep, MemoryBundleStorage, type MountSurfaceManifest, type NativeCapabilities$1 as NativeCapabilities, type NfcAPI, type NotificationsAPI, PLATFORM_VOICE_CALLER, type PluginManifest as PlatformPluginManifest, type PluginBridge, type PluginContext, type PluginGrants, type PluginHooks$1 as PluginHooks, type PluginManifest$1 as PluginManifest, type PluginNative, type PluginProps, type PluginRuntimeProps, type PluginRuntimeSource, PluginSDK, type PluginSummary, type PluginSurfaceMeta, type RegisteredPlugin, type RegisteredServicePlugin, type RegisteredToolsPlugin, type RegisteredUIPlugin, type RemotePlugin, type RenderMode, type ScannerAPI, SearchBar, type SessionSnapshot, type SharingAPI, type SpatialEvent, type SpatialIntent, type SpatialPoint, type SpatialSnapshot, type SpatialStateEvent, type StateEvent, type StateListener, type StateQuality, type StorageAPI, type Subscription, SurfaceCard, type SurfaceCardProps, SurfaceDispatcher, SurfaceDrawer, type SurfaceDrawerProps, SurfaceFullscreen, type SurfaceFullscreenProps, type SurfaceManifest, type SurfacePlacement, type SurfaceType, type SurfaceVisibility, TabBar, type ThemeTokens, type TrustedToolDeclaration, type VisionAPI, type VisionFrameQuality, type VisionLabel, type VisionObject, type VisionText, type VisualSnapshot, type VisualStartOptions, type VoiceAPI, type VoiceCaller, type VoiceDeviceToolCall, type VoiceDeviceToolReason, type VoiceEvent, type VoicePersona, type VoiceSessionProvider, type VoiceSnapshot, type VoiceStartOptions, type VoiceState, type VoiceSubscription, type VoiceTranscriptEntry, type WebViewCookie, __resetSessionSyncForTest, bundleManager, callDeviceTool, clearDeviceTools, createNativeBridge, deviceStateHolders, deviceState as deviceStateV2, deviceToolsActionForSession, ensureDeviceToolsLoaded, explainCapability, gateDeviceState, gatePluginNative, gateVoice, getCameraPreviewProvider, getHaptics, getNativeBundleHash, getNativeBundleUrl, getNativeComponentId, getPlugin, getPluginNative, handleServerDeviceToolCall, hasDeviceTool, implementedStateDomains, implementedVoice, isActionable, isDeviceToolCommand, isInlineSurface, isMountSurface, listDeviceTools, listPlugins, nativePluginRegistry, neverObserved, pluginBundleUrl, register, registerBundleModules, registerDeviceTools, registerNativePlugin, registerPlatformDeviceTools, registerService, registerTools, releaseDeviceStateHolds, rendersNative, resetDeviceToolLoader, resolvePluginGrants, resolvePluginRuntimeProps, resolvePluginUrl, setBundleStorage, setCameraPreviewProvider, setDeviceStateProvider, setDeviceToolContextProvider, setDeviceToolResultPoster, setHapticsProvider, setPluginNativeProvider, setPluginThemeColors, setVoiceProvider, supportsNative, supportsWebView, syncDeviceToolsForSession, unregisterDeviceTools, unregisterNativePlugin, useApi, useNativeBridge, usePlugin, usePluginRuntimeProps, usePluginTheme, useRemotePlugins, useSurfaceStore };
3457
+ export { AI_LIVE_IDLE, ActionButton, type ActivitySnapshot, AdaOrb, type AdaOrbState, type AiLiveAPI, type AiLiveCamera, type AiLiveEpisode, type AiLiveProvider, type AiLiveSnapshot, type AiLiveStartOptions, type AiLiveState, Badge, type BiometricsAPI, type BiometricsAPIv2, type BluetoothAPI, type BluetoothDevice, type Bridge, type BundleCacheEntry, type BundleStorage, type CameraAPI, CameraPreview, type CameraPreviewProps, type CapabilitySnapshot, type CapabilityStatus, Card, type Confidence, type ConnectivityAPI, type ConnectivitySnapshot, type CookiesAPI, type DeviceBridgeDomain, type DeviceContextSnapshot, type DeviceState, type DeviceToolContext, type DeviceToolDefinition, type DeviceToolFailureReason, type DeviceToolFn, type DeviceToolOutcome, type DeviceToolSummary, type DeviceToolsAction, type DeviceToolsSessionDeps, EmptyState, type EnvironmentSnapshot, ErrorState, type FileSystemAPI, type Freshness, type HapticsAPI, type InlineSurfaceManifest, type InteractionSnapshot, ListItem, type LoadedBundleInfo, type LoadedBundleSource, LoadingState, type LocationAPI, type MapsAPI, type MapsAddress, type MapsCoordinate, type MapsPlace, type MapsRoute, type MapsRouteStep, MemoryBundleStorage, type MountSurfaceManifest, type NativeCapabilities$1 as NativeCapabilities, type NfcAPI, type NotificationsAPI, PLATFORM_VOICE_CALLER, type PluginManifest as PlatformPluginManifest, type PluginBridge, type PluginContext, type PluginGrants, type PluginHooks$1 as PluginHooks, type PluginManifest$1 as PluginManifest, type PluginNative, type PluginProps, type PluginRuntimeProps, type PluginRuntimeSource, PluginSDK, type PluginSummary, type PluginSurfaceMeta, type RegisteredPlugin, type RegisteredServicePlugin, type RegisteredToolsPlugin, type RegisteredUIPlugin, type RemotePlugin, type RenderMode, type ScannerAPI, SearchBar, type SessionSnapshot, type SharingAPI, type SpatialEvent, type SpatialIntent, type SpatialPoint, type SpatialSnapshot, type SpatialStateEvent, type StateEvent, type StateListener, type StateQuality, type StorageAPI, type Subscription, SurfaceCard, type SurfaceCardProps, SurfaceDispatcher, SurfaceDrawer, type SurfaceDrawerProps, SurfaceFullscreen, type SurfaceFullscreenProps, type SurfaceManifest, type SurfacePlacement, type SurfaceType, type SurfaceVisibility, TabBar, type ThemeTokens, type TrustedToolDeclaration, type VisionAPI, type VisionFrameQuality, type VisionLabel, type VisionObject, type VisionText, type VisualSnapshot, type VisualStartOptions, type VoiceAPI, type VoiceCaller, type VoiceDeviceToolCall, type VoiceDeviceToolReason, type VoiceEvent, type VoicePersona, type VoiceSessionProvider, type VoiceSnapshot, type VoiceStartOptions, type VoiceState, type VoiceSubscription, type VoiceTranscriptEntry, type WebViewCookie, __resetSessionSyncForTest, aiLiveIndicator, bundleManager, callDeviceTool, clearDeviceTools, createNativeBridge, deviceStateHolders, deviceState as deviceStateV2, deviceToolsActionForSession, ensureDeviceToolsLoaded, explainCapability, gateAiLive, gateDeviceState, gatePluginNative, gateVoice, getCameraPreviewProvider, getHaptics, getNativeBundleHash, getNativeBundleUrl, getNativeComponentId, getPlugin, getPluginNative, handleServerDeviceToolCall, hasDeviceTool, implementedStateDomains, implementedVoice, isActionable, isDeviceToolCommand, isInlineSurface, isMountSurface, listDeviceTools, listPlugins, mayPicturesLeavePhone, nativePluginRegistry, neverObserved, pluginBundleUrl, register, registerBundleModules, registerDeviceTools, registerNativePlugin, registerPlatformDeviceTools, registerService, registerTools, releaseAiLive, releaseDeviceStateHolds, rendersNative, resetDeviceToolLoader, resolvePluginGrants, resolvePluginRuntimeProps, resolvePluginUrl, setAiLiveProvider, setBundleStorage, setCameraPreviewProvider, setDeviceStateProvider, setDeviceToolContextProvider, setDeviceToolResultPoster, setHapticsProvider, setPicturesToAiConsentProvider, setPluginNativeProvider, setPluginThemeColors, setVoiceProvider, supportsNative, supportsWebView, syncDeviceToolsForSession, unregisterDeviceTools, unregisterNativePlugin, useApi, useNativeBridge, usePlugin, usePluginRuntimeProps, usePluginTheme, useRemotePlugins, useSurfaceStore };
package/dist/index.js CHANGED
@@ -75,6 +75,22 @@ var init_voice = __esm({
75
75
  }
76
76
  });
77
77
 
78
+ // src/sdk/aiLive.ts
79
+ var AI_LIVE_IDLE;
80
+ var init_aiLive = __esm({
81
+ "src/sdk/aiLive.ts"() {
82
+ "use strict";
83
+ AI_LIVE_IDLE = Object.freeze({
84
+ state: "idle",
85
+ camera: null,
86
+ sent: 0,
87
+ skipped: 0,
88
+ lastEpisode: null,
89
+ lastError: null
90
+ });
91
+ }
92
+ });
93
+
78
94
  // src/sdk/device-state.ts
79
95
  var device_state_exports = {};
80
96
  __export(device_state_exports, {
@@ -477,6 +493,18 @@ function setCameraPreviewProvider(Component) {
477
493
  function getCameraPreviewProvider() {
478
494
  return _cameraPreview;
479
495
  }
496
+ function setPicturesToAiConsentProvider(provider) {
497
+ _picturesToAiConsent = provider;
498
+ }
499
+ function mayPicturesLeavePhone(declared) {
500
+ if (declared?.picturesToAi !== true) return false;
501
+ if (!_picturesToAiConsent) return false;
502
+ try {
503
+ return _picturesToAiConsent() === true;
504
+ } catch {
505
+ return false;
506
+ }
507
+ }
480
508
  function registerNativePlugin(id, plugin) {
481
509
  _nativeRegistry.set(id, plugin);
482
510
  }
@@ -498,7 +526,7 @@ function registerBundleModules(modules) {
498
526
  function resolveBundleModule(name) {
499
527
  return _bundleModules.get(name);
500
528
  }
501
- var _haptics, noopNative, _pluginNative, _cameraPreview, _nativeRegistry, nativePluginRegistry, _bundleModules;
529
+ var _haptics, noopNative, _pluginNative, _cameraPreview, _picturesToAiConsent, _nativeRegistry, nativePluginRegistry, _bundleModules;
502
530
  var init_host = __esm({
503
531
  "src/host.ts"() {
504
532
  "use strict";
@@ -528,6 +556,7 @@ var init_host = __esm({
528
556
  };
529
557
  _pluginNative = noopNative;
530
558
  _cameraPreview = null;
559
+ _picturesToAiConsent = null;
531
560
  _nativeRegistry = /* @__PURE__ */ new Map();
532
561
  nativePluginRegistry = {
533
562
  has(id) {
@@ -705,6 +734,7 @@ var init_useApi = __esm({
705
734
  // src/sdk/index.ts
706
735
  var sdk_exports = {};
707
736
  __export(sdk_exports, {
737
+ AI_LIVE_IDLE: () => AI_LIVE_IDLE,
708
738
  ActionButton: () => ActionButton,
709
739
  ActivityIndicator: () => import_react_native.ActivityIndicator,
710
740
  Animated: () => import_react_native.Animated,
@@ -749,6 +779,7 @@ var init_sdk = __esm({
749
779
  init_registration();
750
780
  init_registration();
751
781
  init_voice();
782
+ init_aiLive();
752
783
  init_device_state();
753
784
  init_primitives();
754
785
  init_components();
@@ -1064,6 +1095,93 @@ var init_voiceHost = __esm({
1064
1095
  }
1065
1096
  });
1066
1097
 
1098
+ // src/aiLiveHost.ts
1099
+ function setAiLiveProvider(provider) {
1100
+ _provider3 = provider || null;
1101
+ }
1102
+ function denial2(why) {
1103
+ return Object.assign(new Error(`aiLive: ${why}`), { code: "RESTRICTED" });
1104
+ }
1105
+ function deniedAiLive(why) {
1106
+ const fail = () => {
1107
+ throw denial2(why);
1108
+ };
1109
+ return {
1110
+ async start() {
1111
+ return fail();
1112
+ },
1113
+ async stop() {
1114
+ },
1115
+ getSnapshot() {
1116
+ return { state: "error", camera: null, sent: 0, skipped: 0, lastEpisode: null, lastError: why };
1117
+ },
1118
+ onEpisode() {
1119
+ return fail();
1120
+ },
1121
+ subscribe() {
1122
+ return fail();
1123
+ }
1124
+ };
1125
+ }
1126
+ function gateAiLive(capabilities, pluginId, holder, camera) {
1127
+ if (capabilities?.picturesToAi !== true) {
1128
+ return deniedAiLive("not declared in this plugin's capabilities. Add `capabilities: { picturesToAi: true }` to send camera pictures to the workspace's chosen AI.");
1129
+ }
1130
+ if (!pluginId || !holder) return deniedAiLive("no plugin identity \u2014 it fails closed without a screen to bind the session to.");
1131
+ if (!_provider3) return deniedAiLive("no live AI in this build \u2014 the app has not called setAiLiveProvider.");
1132
+ const provider = _provider3;
1133
+ return {
1134
+ async start(opts) {
1135
+ if (!mayPicturesLeavePhone(capabilities)) {
1136
+ throw denial2(`the person on this phone has not allowed camera pictures to go to AI. They can turn on "Pictures to AI" in the app's settings (What Ada can access).`);
1137
+ }
1138
+ try {
1139
+ return await provider.start(opts || {}, holder, { visual: camera() });
1140
+ } catch (e) {
1141
+ await releaseDeviceStateHolds(aiLiveCameraHolder(holder));
1142
+ throw e;
1143
+ }
1144
+ },
1145
+ async stop() {
1146
+ try {
1147
+ await provider.stop(holder);
1148
+ } finally {
1149
+ await releaseDeviceStateHolds(aiLiveCameraHolder(holder));
1150
+ }
1151
+ },
1152
+ getSnapshot: () => provider.getSnapshot(holder),
1153
+ onEpisode: (cb) => provider.onEpisode(cb, holder),
1154
+ subscribe: (cb) => provider.subscribe(cb, holder)
1155
+ };
1156
+ }
1157
+ async function releaseAiLive(holder) {
1158
+ try {
1159
+ await _provider3?.stop(holder);
1160
+ } catch {
1161
+ }
1162
+ try {
1163
+ _provider3?.forget(holder);
1164
+ } catch {
1165
+ }
1166
+ await releaseDeviceStateHolds(aiLiveCameraHolder(holder));
1167
+ }
1168
+ var _provider3, aiLiveCameraHolder, NOTHING, aiLiveIndicator;
1169
+ var init_aiLiveHost = __esm({
1170
+ "src/aiLiveHost.ts"() {
1171
+ "use strict";
1172
+ init_host();
1173
+ init_deviceStateHost();
1174
+ _provider3 = null;
1175
+ aiLiveCameraHolder = (holder) => `${holder}#aiLive`;
1176
+ NOTHING = { unsubscribe() {
1177
+ } };
1178
+ aiLiveIndicator = {
1179
+ isSending: () => !!_provider3?.isSending(),
1180
+ subscribe: (cb) => _provider3?.subscribeSending(cb) ?? NOTHING
1181
+ };
1182
+ }
1183
+ });
1184
+
1067
1185
  // src/pluginRuntime.ts
1068
1186
  function mergeCaps(decl) {
1069
1187
  if (!decl) return void 0;
@@ -1079,7 +1197,8 @@ function resolvePluginRuntimeProps(src, holder = src.pluginId) {
1079
1197
  const native = gatePluginNative(getPluginNative(), capabilities, src.pluginId);
1080
1198
  const deviceState = gateDeviceState(stateDomains, holder);
1081
1199
  const voice = gateVoice(!!capabilities?.voice, src.pluginId);
1082
- return { device: native, native, deviceState, voice };
1200
+ const aiLive = gateAiLive(capabilities, src.pluginId, holder, () => gateDeviceState(["visual"], aiLiveCameraHolder(holder)).visual);
1201
+ return { device: native, native, deviceState, voice, aiLive };
1083
1202
  }
1084
1203
  var init_pluginRuntime = __esm({
1085
1204
  "src/pluginRuntime.ts"() {
@@ -1087,6 +1206,7 @@ var init_pluginRuntime = __esm({
1087
1206
  init_host();
1088
1207
  init_deviceStateHost();
1089
1208
  init_voiceHost();
1209
+ init_aiLiveHost();
1090
1210
  }
1091
1211
  });
1092
1212
 
@@ -3326,6 +3446,7 @@ var init_loader = __esm({
3326
3446
  // src/index.ts
3327
3447
  var index_exports = {};
3328
3448
  __export(index_exports, {
3449
+ AI_LIVE_IDLE: () => AI_LIVE_IDLE,
3329
3450
  ActionButton: () => ActionButton,
3330
3451
  ActivityIndicator: () => import_react_native.ActivityIndicator,
3331
3452
  AdaOrb: () => AdaOrb,
@@ -3361,6 +3482,7 @@ __export(index_exports, {
3361
3482
  TouchableOpacity: () => import_react_native.TouchableOpacity,
3362
3483
  View: () => import_react_native.View,
3363
3484
  __resetSessionSyncForTest: () => __resetSessionSyncForTest,
3485
+ aiLiveIndicator: () => aiLiveIndicator,
3364
3486
  bundleManager: () => bundleManager,
3365
3487
  callDeviceTool: () => callDeviceTool,
3366
3488
  clearDeviceTools: () => clearDeviceTools,
@@ -3370,6 +3492,7 @@ __export(index_exports, {
3370
3492
  deviceToolsActionForSession: () => deviceToolsActionForSession,
3371
3493
  ensureDeviceToolsLoaded: () => ensureDeviceToolsLoaded,
3372
3494
  explainCapability: () => explainCapability,
3495
+ gateAiLive: () => gateAiLive,
3373
3496
  gateDeviceState: () => gateDeviceState,
3374
3497
  gatePluginNative: () => gatePluginNative,
3375
3498
  gateVoice: () => gateVoice,
@@ -3390,6 +3513,7 @@ __export(index_exports, {
3390
3513
  isMountSurface: () => isMountSurface,
3391
3514
  listDeviceTools: () => listDeviceTools,
3392
3515
  listPlugins: () => listPlugins,
3516
+ mayPicturesLeavePhone: () => mayPicturesLeavePhone,
3393
3517
  nativePluginRegistry: () => nativePluginRegistry,
3394
3518
  neverObserved: () => neverObserved,
3395
3519
  pluginBundleUrl: () => pluginBundleUrl,
@@ -3400,18 +3524,21 @@ __export(index_exports, {
3400
3524
  registerPlatformDeviceTools: () => registerPlatformDeviceTools,
3401
3525
  registerService: () => registerService,
3402
3526
  registerTools: () => registerTools,
3527
+ releaseAiLive: () => releaseAiLive,
3403
3528
  releaseDeviceStateHolds: () => releaseDeviceStateHolds,
3404
3529
  rendersNative: () => rendersNative,
3405
3530
  resetDeviceToolLoader: () => resetDeviceToolLoader,
3406
3531
  resolvePluginGrants: () => resolvePluginGrants,
3407
3532
  resolvePluginRuntimeProps: () => resolvePluginRuntimeProps,
3408
3533
  resolvePluginUrl: () => resolvePluginUrl,
3534
+ setAiLiveProvider: () => setAiLiveProvider,
3409
3535
  setBundleStorage: () => setBundleStorage,
3410
3536
  setCameraPreviewProvider: () => setCameraPreviewProvider,
3411
3537
  setDeviceStateProvider: () => setDeviceStateProvider,
3412
3538
  setDeviceToolContextProvider: () => setDeviceToolContextProvider,
3413
3539
  setDeviceToolResultPoster: () => setDeviceToolResultPoster,
3414
3540
  setHapticsProvider: () => setHapticsProvider,
3541
+ setPicturesToAiConsentProvider: () => setPicturesToAiConsentProvider,
3415
3542
  setPluginNativeProvider: () => setPluginNativeProvider,
3416
3543
  setPluginThemeColors: () => setPluginThemeColors,
3417
3544
  setVoiceProvider: () => setVoiceProvider,
@@ -3434,6 +3561,7 @@ init_device_state();
3434
3561
  init_device_state();
3435
3562
  init_deviceStateHost();
3436
3563
  init_voiceHost();
3564
+ init_aiLiveHost();
3437
3565
  init_host();
3438
3566
  init_pluginRuntime();
3439
3567
  init_registry();
@@ -3661,6 +3789,7 @@ function usePlugin(pluginId, manifest) {
3661
3789
  var import_react12 = require("react");
3662
3790
  init_pluginRuntime();
3663
3791
  init_deviceStateHost();
3792
+ init_aiLiveHost();
3664
3793
  var mounts = 0;
3665
3794
  function usePluginRuntimeProps(src, deps) {
3666
3795
  const holderRef = (0, import_react12.useRef)(null);
@@ -3673,6 +3802,9 @@ function usePluginRuntimeProps(src, deps) {
3673
3802
  (0, import_react12.useEffect)(() => () => {
3674
3803
  void releaseDeviceStateHolds(holder);
3675
3804
  }, [holder]);
3805
+ (0, import_react12.useEffect)(() => () => {
3806
+ void releaseAiLive(holder);
3807
+ }, [holder]);
3676
3808
  const grantedKey = granted.join(",");
3677
3809
  (0, import_react12.useEffect)(() => {
3678
3810
  void releaseDeviceStateHolds(holder, granted);
@@ -3761,6 +3893,7 @@ init_store();
3761
3893
  init_SurfaceDispatcher();
3762
3894
  // Annotate the CommonJS export names for ESM import in node:
3763
3895
  0 && (module.exports = {
3896
+ AI_LIVE_IDLE,
3764
3897
  ActionButton,
3765
3898
  ActivityIndicator,
3766
3899
  AdaOrb,
@@ -3796,6 +3929,7 @@ init_SurfaceDispatcher();
3796
3929
  TouchableOpacity,
3797
3930
  View,
3798
3931
  __resetSessionSyncForTest,
3932
+ aiLiveIndicator,
3799
3933
  bundleManager,
3800
3934
  callDeviceTool,
3801
3935
  clearDeviceTools,
@@ -3805,6 +3939,7 @@ init_SurfaceDispatcher();
3805
3939
  deviceToolsActionForSession,
3806
3940
  ensureDeviceToolsLoaded,
3807
3941
  explainCapability,
3942
+ gateAiLive,
3808
3943
  gateDeviceState,
3809
3944
  gatePluginNative,
3810
3945
  gateVoice,
@@ -3825,6 +3960,7 @@ init_SurfaceDispatcher();
3825
3960
  isMountSurface,
3826
3961
  listDeviceTools,
3827
3962
  listPlugins,
3963
+ mayPicturesLeavePhone,
3828
3964
  nativePluginRegistry,
3829
3965
  neverObserved,
3830
3966
  pluginBundleUrl,
@@ -3835,18 +3971,21 @@ init_SurfaceDispatcher();
3835
3971
  registerPlatformDeviceTools,
3836
3972
  registerService,
3837
3973
  registerTools,
3974
+ releaseAiLive,
3838
3975
  releaseDeviceStateHolds,
3839
3976
  rendersNative,
3840
3977
  resetDeviceToolLoader,
3841
3978
  resolvePluginGrants,
3842
3979
  resolvePluginRuntimeProps,
3843
3980
  resolvePluginUrl,
3981
+ setAiLiveProvider,
3844
3982
  setBundleStorage,
3845
3983
  setCameraPreviewProvider,
3846
3984
  setDeviceStateProvider,
3847
3985
  setDeviceToolContextProvider,
3848
3986
  setDeviceToolResultPoster,
3849
3987
  setHapticsProvider,
3988
+ setPicturesToAiConsentProvider,
3850
3989
  setPluginNativeProvider,
3851
3990
  setPluginThemeColors,
3852
3991
  setVoiceProvider,