@ateam-ai-mobile/plugin-runtime 0.1.7 → 0.1.8

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
@@ -20,7 +20,8 @@ export { ActivityIndicator, Animated, FlatList, Image, Modal, Platform, Pressabl
20
20
  * VERB names: takePhoto, getCurrent, scanBarcode,
21
21
  * readOnce, authenticate, pickImage.
22
22
  * Returns a BARE value. THROWS when it cannot.
23
- * Declared in the manifest as `native: { camera: true }`.
23
+ * Declared in the manifest as `capabilities: { camera: true }`
24
+ * (the legacy `native: {}` field is still honoured).
24
25
  * Lives in '@adas/plugin-sdk'.
25
26
  *
26
27
  * props.deviceState.* SEMANTIC. "What is true right now, and how well do
@@ -117,17 +118,19 @@ type RestrictionState = 'none' | 'backgroundRestricted' | 'systemRestricted' | '
117
118
  * never raw sensor streams." If you find yourself wanting an event per frame
118
119
  * or per GPS fix, you are in the wrong layer.
119
120
  */
120
- interface StateEvent<TName extends string = string> {
121
+ interface StateEvent<TName extends string = string, TPayload = unknown> {
121
122
  domain: DeviceBridgeDomain;
122
123
  name: TName;
123
124
  /** Epoch ms. */
124
125
  timestamp: number;
125
126
  /**
126
127
  * OPEN: per-event payload schemas are not specified anywhere in the three
127
- * design docs. Typed `unknown` rather than `any` so a consumer is forced to
128
- * narrow it rather than read a field that may not exist.
128
+ * design docs. Defaults to `unknown` rather than `any` so a consumer is forced
129
+ * to narrow it rather than read a field that may not exist. A domain that
130
+ * decides its schemas (spatial — see `SpatialStateEvent`) passes `TPayload`,
131
+ * which is the freeze's own second parameter, dropped here until one did.
129
132
  */
130
- payload?: unknown;
133
+ payload?: TPayload;
131
134
  }
132
135
  interface Subscription {
133
136
  unsubscribe(): void;
@@ -141,9 +144,17 @@ type StateListener<TName extends string = string> = (event: StateEvent<TName>) =
141
144
  * connectivity, capability, interaction and environment only. Rather than mint
142
145
  * names those docs deliberately did not mint, their events are typed against
143
146
  * the naming RULE. A wrong-shaped name is a compile error; the specific
144
- * vocabulary stays open, as the docs left it.
147
+ * vocabulary stays open, as the docs left it — except where a DECISION closes
148
+ * it (spatial, see `SpatialEvent`), and that list is checked against the rule
149
+ * through `AssertConforming`.
145
150
  */
146
151
  type ConformingEventName = `${string}Changed` | `${string}Started` | `${string}Stopped` | `${string}Available` | `${string}Unavailable` | `${string}StateStale`;
152
+ /**
153
+ * A closed list of names, checked against the naming rule at compile time.
154
+ * Wrap a decided vocabulary in this and a name like `turnCompleted` stops
155
+ * compiling instead of reaching a plugin.
156
+ */
157
+ type AssertConforming<T extends ConformingEventName> = T;
147
158
  /** FROZEN (API_FREEZE §12). */
148
159
  type DeviceBridgeErrorCode = 'UNSUPPORTED' | 'PERMISSION_DENIED' | 'RESTRICTED' | 'BUSY' | 'TEMPORARILY_UNAVAILABLE' | 'STALE' | 'TIMEOUT' | 'CANCELLED' | 'INTERNAL';
149
160
  /**
@@ -272,12 +283,89 @@ interface SpatialSnapshot {
272
283
  };
273
284
  quality: StateQuality;
274
285
  }
286
+ /**
287
+ * DECISION (not frozen) — the spatial event vocabulary. Six names, all ending
288
+ * in a suffix the naming rule allows, which `AssertConforming` enforces.
289
+ *
290
+ * Drawn from the architecture doc's spatial candidates (meaningful movement,
291
+ * meaningful turn, location quality degraded/recovered, state became stale)
292
+ * and named after the SNAPSHOT fields they report, so an event and a read use
293
+ * one vocabulary: `lastMeaningfulTurnChanged` is `changes.lastMeaningfulTurnDeg`
294
+ * changing. The names an earlier note floated (`turnCompleted`, `arrived`,
295
+ * `headingLost`) are rejected — the first two fail the rule, and "arrived" is a
296
+ * destination, which the vocabulary's Governance puts above Device Bridge.
297
+ */
298
+ type SpatialEvent = AssertConforming<'movementStarted' | 'movementStopped' | 'lastMeaningfulTurnChanged' | 'positionConfidenceChanged' | 'positionChanged' | 'spatialStateStale'>;
299
+ /** A spatial event: the frozen envelope, with its payload always present. */
300
+ type SpatialEventOf<TName extends SpatialEvent, TPayload> = StateEvent<TName, TPayload> & {
301
+ domain: 'spatial';
302
+ payload: TPayload;
303
+ };
304
+ /**
305
+ * DECISION — what each spatial event carries. Only the facts of the
306
+ * transition, in the snapshot's own field names; everything else is one
307
+ * `getSnapshot()` away, which keeps two shapes of the same fact from drifting.
308
+ *
309
+ * `timestamp` on the envelope is when the transition was RECOGNISED. Where a
310
+ * hold delays that on purpose, `since` carries the true onset.
311
+ */
312
+ type SpatialStateEvent =
313
+ /** `movement.state` became `moving` and held (navigation: 3 s). */
314
+ SpatialEventOf<'movementStarted', {
315
+ previous: 'stationary' | 'unknown';
316
+ speedMps: number | null;
317
+ bearingDeg: number | null;
318
+ since: number;
319
+ }>
320
+ /** `moving` → `stationary`, held (navigation: 5 s). Never fired on moving →
321
+ * `unknown`: losing the speed is not evidence of stopping. */
322
+ | SpatialEventOf<'movementStopped', {
323
+ previous: 'moving';
324
+ since: number;
325
+ }>
326
+ /** A new completed turn. Signed: positive = clockwise = right. */
327
+ | SpatialEventOf<'lastMeaningfulTurnChanged', {
328
+ lastMeaningfulTurnDeg: number;
329
+ timestamp: number;
330
+ }>
331
+ /** The GPS fix band (high ≤10 m, medium ≤50 m, else low) changed and held.
332
+ * The fix alone — a compass calibration change is not a position event. */
333
+ | SpatialEventOf<'positionConfidenceChanged', {
334
+ level: ConfidenceLevel;
335
+ previous: ConfidenceLevel;
336
+ accuracyM: number | null;
337
+ direction: 'dropped' | 'recovered';
338
+ }>
339
+ /** Moved at least max(profile floor, 2 × accuracyM) from the last reported
340
+ * position, so GPS jitter never fires it. The session's first fix fires
341
+ * with `previous: null`. */
342
+ | SpatialEventOf<'positionChanged', {
343
+ position: SpatialPoint;
344
+ previous: SpatialPoint | null;
345
+ distanceM: number | null;
346
+ }>
347
+ /** `quality.freshness.state` became `stale`. Once; re-armed by a fresh read. */
348
+ | SpatialEventOf<'spatialStateStale', {
349
+ observedAt: number | null;
350
+ ageMs: number | null;
351
+ }>;
275
352
  interface SpatialDomain {
276
353
  getSnapshot(): Promise<SpatialSnapshot>;
277
354
  start(options: StartOptions<SpatialIntent>): Promise<StateSession>;
278
355
  stop(sessionId?: string): Promise<void>;
279
- /** OPEN: no frozen spatial event vocabulary; rule-conforming names only. */
280
- subscribe(listener: StateListener<ConformingEventName>): Subscription;
356
+ /**
357
+ * DECISION: the six `SpatialEvent`s, typed per name — narrow on `e.name` and
358
+ * `e.payload` is that event's shape.
359
+ *
360
+ * Events flow only while a spatial session is open; subscribing opens no
361
+ * sensor. They are derived from the same snapshot `getSnapshot()` returns: a
362
+ * listener that re-reads inside the callback sees the snapshot its event came
363
+ * from. A state change must hold, on at least two fixes, before it fires.
364
+ *
365
+ * From a device tool's `ctx.deviceState` this refuses (RESTRICTED): a call
366
+ * has no lifetime to own the listener.
367
+ */
368
+ subscribe(listener: (event: SpatialStateEvent) => void): Subscription;
281
369
  }
282
370
  /** FROZEN (API_FREEZE §4) + VOCABULARY §"Visual Intents". Nine values. */
283
371
  type VisualIntent = 'navigation' | 'document' | 'ocr' | 'shopping' | 'inspection' | 'accessibility' | 'stream' | 'highQuality' | 'lowPower';
@@ -841,6 +929,7 @@ interface DeviceToolContextV2Extension {
841
929
  type deviceState_ActivityDomain = ActivityDomain;
842
930
  type deviceState_ActivityIntent = ActivityIntent;
843
931
  type deviceState_ActivitySnapshot = ActivitySnapshot;
932
+ type deviceState_AssertConforming<T extends ConformingEventName> = AssertConforming<T>;
844
933
  type deviceState_AvailabilityState = AvailabilityState;
845
934
  type deviceState_CapabilityDomain = CapabilityDomain;
846
935
  type deviceState_CapabilityEvent = CapabilityEvent;
@@ -877,12 +966,14 @@ type deviceState_MediaHandle = MediaHandle;
877
966
  type deviceState_PluginPropsV2Extension = PluginPropsV2Extension;
878
967
  type deviceState_RestrictionState = RestrictionState;
879
968
  type deviceState_SpatialDomain = SpatialDomain;
969
+ type deviceState_SpatialEvent = SpatialEvent;
880
970
  type deviceState_SpatialIntent = SpatialIntent;
881
971
  type deviceState_SpatialPoint = SpatialPoint;
882
972
  type deviceState_SpatialSnapshot = SpatialSnapshot;
973
+ type deviceState_SpatialStateEvent = SpatialStateEvent;
883
974
  type deviceState_StartOptions<TIntent extends string> = StartOptions<TIntent>;
884
975
  type deviceState_StateDomainDeclaration = StateDomainDeclaration;
885
- type deviceState_StateEvent<TName extends string = string> = StateEvent<TName>;
976
+ type deviceState_StateEvent<TName extends string = string, TPayload = unknown> = StateEvent<TName, TPayload>;
886
977
  type deviceState_StateListener<TName extends string = string> = StateListener<TName>;
887
978
  type deviceState_StateQuality = StateQuality;
888
979
  type deviceState_StateSession = StateSession;
@@ -900,7 +991,7 @@ declare const deviceState_explainCapability: typeof explainCapability;
900
991
  declare const deviceState_isActionable: typeof isActionable;
901
992
  declare const deviceState_neverObserved: typeof neverObserved;
902
993
  declare namespace deviceState {
903
- export { type deviceState_ActivityDomain as ActivityDomain, type deviceState_ActivityIntent as ActivityIntent, type deviceState_ActivitySnapshot as ActivitySnapshot, type deviceState_AvailabilityState as AvailabilityState, type deviceState_CapabilityDomain as CapabilityDomain, type deviceState_CapabilityEvent as CapabilityEvent, type deviceState_CapabilitySnapshot as CapabilitySnapshot, type deviceState_CapabilityStatus as CapabilityStatus, type deviceState_Confidence as Confidence, type deviceState_ConfidenceLevel as ConfidenceLevel, type deviceState_ConformingEventName as ConformingEventName, type deviceState_ConnectivityDomain as ConnectivityDomain, type deviceState_ConnectivityEvent as ConnectivityEvent, type deviceState_ConnectivityIntent as ConnectivityIntent, type deviceState_ConnectivitySnapshot as ConnectivitySnapshot, type deviceState_DeviceBridgeDomain as DeviceBridgeDomain, deviceState_DeviceBridgeError as DeviceBridgeError, type deviceState_DeviceBridgeErrorCode as DeviceBridgeErrorCode, type deviceState_DeviceBridgeV2 as DeviceBridgeV2, type deviceState_DeviceContextDomain as DeviceContextDomain, type deviceState_DeviceContextSnapshot as DeviceContextSnapshot, type deviceState_DevicePlacement as DevicePlacement, type deviceState_DeviceState as DeviceState, type deviceState_DeviceToolContextV2Extension as DeviceToolContextV2Extension, type deviceState_EnvironmentDomain as EnvironmentDomain, type deviceState_EnvironmentEvent as EnvironmentEvent, type deviceState_EnvironmentIntent as EnvironmentIntent, type deviceState_EnvironmentSnapshot as EnvironmentSnapshot, type deviceState_Freshness as Freshness, type deviceState_FreshnessState as FreshnessState, type deviceState_HumanActivity as HumanActivity, type deviceState_InteractionDomain as InteractionDomain, type deviceState_InteractionEvent as InteractionEvent, type deviceState_InteractionSnapshot as InteractionSnapshot, type deviceState_MediaHandle as MediaHandle, type PermissionState$1 as PermissionState, type deviceState_PluginPropsV2Extension as PluginPropsV2Extension, type deviceState_RestrictionState as RestrictionState, type deviceState_SpatialDomain as SpatialDomain, type deviceState_SpatialIntent as SpatialIntent, type deviceState_SpatialPoint as SpatialPoint, type deviceState_SpatialSnapshot as SpatialSnapshot, type deviceState_StartOptions as StartOptions, type deviceState_StateDomainDeclaration as StateDomainDeclaration, type deviceState_StateEvent as StateEvent, type deviceState_StateListener as StateListener, type deviceState_StateQuality as StateQuality, type deviceState_StateSession as StateSession, type deviceState_StatefulDomain as StatefulDomain, type deviceState_Subscription as Subscription, type deviceState_SupportState as SupportState, type deviceState_VisualCaptureOptions as VisualCaptureOptions, type deviceState_VisualCaptureResult as VisualCaptureResult, type deviceState_VisualDomain as VisualDomain, type deviceState_VisualFrameQuality as VisualFrameQuality, type deviceState_VisualFrameRef as VisualFrameRef, type deviceState_VisualIntent as VisualIntent, type deviceState_VisualSnapshot as VisualSnapshot, deviceState_explainCapability as explainCapability, deviceState_isActionable as isActionable, deviceState_neverObserved as neverObserved };
994
+ export { type deviceState_ActivityDomain as ActivityDomain, type deviceState_ActivityIntent as ActivityIntent, type deviceState_ActivitySnapshot as ActivitySnapshot, type deviceState_AssertConforming as AssertConforming, type deviceState_AvailabilityState as AvailabilityState, type deviceState_CapabilityDomain as CapabilityDomain, type deviceState_CapabilityEvent as CapabilityEvent, type deviceState_CapabilitySnapshot as CapabilitySnapshot, type deviceState_CapabilityStatus as CapabilityStatus, type deviceState_Confidence as Confidence, type deviceState_ConfidenceLevel as ConfidenceLevel, type deviceState_ConformingEventName as ConformingEventName, type deviceState_ConnectivityDomain as ConnectivityDomain, type deviceState_ConnectivityEvent as ConnectivityEvent, type deviceState_ConnectivityIntent as ConnectivityIntent, type deviceState_ConnectivitySnapshot as ConnectivitySnapshot, type deviceState_DeviceBridgeDomain as DeviceBridgeDomain, deviceState_DeviceBridgeError as DeviceBridgeError, type deviceState_DeviceBridgeErrorCode as DeviceBridgeErrorCode, type deviceState_DeviceBridgeV2 as DeviceBridgeV2, type deviceState_DeviceContextDomain as DeviceContextDomain, type deviceState_DeviceContextSnapshot as DeviceContextSnapshot, type deviceState_DevicePlacement as DevicePlacement, type deviceState_DeviceState as DeviceState, type deviceState_DeviceToolContextV2Extension as DeviceToolContextV2Extension, type deviceState_EnvironmentDomain as EnvironmentDomain, type deviceState_EnvironmentEvent as EnvironmentEvent, type deviceState_EnvironmentIntent as EnvironmentIntent, type deviceState_EnvironmentSnapshot as EnvironmentSnapshot, type deviceState_Freshness as Freshness, type deviceState_FreshnessState as FreshnessState, type deviceState_HumanActivity as HumanActivity, type deviceState_InteractionDomain as InteractionDomain, type deviceState_InteractionEvent as InteractionEvent, type deviceState_InteractionSnapshot as InteractionSnapshot, type deviceState_MediaHandle as MediaHandle, type PermissionState$1 as PermissionState, type deviceState_PluginPropsV2Extension as PluginPropsV2Extension, type deviceState_RestrictionState as RestrictionState, type deviceState_SpatialDomain as SpatialDomain, type deviceState_SpatialEvent as SpatialEvent, type deviceState_SpatialIntent as SpatialIntent, type deviceState_SpatialPoint as SpatialPoint, type deviceState_SpatialSnapshot as SpatialSnapshot, type deviceState_SpatialStateEvent as SpatialStateEvent, type deviceState_StartOptions as StartOptions, type deviceState_StateDomainDeclaration as StateDomainDeclaration, type deviceState_StateEvent as StateEvent, type deviceState_StateListener as StateListener, type deviceState_StateQuality as StateQuality, type deviceState_StateSession as StateSession, type deviceState_StatefulDomain as StatefulDomain, type deviceState_Subscription as Subscription, type deviceState_SupportState as SupportState, type deviceState_VisualCaptureOptions as VisualCaptureOptions, type deviceState_VisualCaptureResult as VisualCaptureResult, type deviceState_VisualDomain as VisualDomain, type deviceState_VisualFrameQuality as VisualFrameQuality, type deviceState_VisualFrameRef as VisualFrameRef, type deviceState_VisualIntent as VisualIntent, type deviceState_VisualSnapshot as VisualSnapshot, deviceState_explainCapability as explainCapability, deviceState_isActionable as isActionable, deviceState_neverObserved as neverObserved };
904
995
  }
905
996
 
906
997
  /**
@@ -954,11 +1045,51 @@ interface VoiceSnapshot {
954
1045
  /** The last error, if `state === 'error'`; also carries a refusal reason when
955
1046
  * this surface was handed to a plugin that did not declare `voice`. */
956
1047
  lastError: string | null;
1048
+ /** The most recent LOCAL device-tool call the model made through the session
1049
+ * (name + epoch ms), or null if none yet. Diagnostic: proves whether the
1050
+ * model's call_device_tool actually reached the phone vs was never made. */
1051
+ lastDeviceTool: {
1052
+ name: string;
1053
+ at: number;
1054
+ } | null;
1055
+ /** The sessionId the Core allowset is bound to. Diagnostic: authorization
1056
+ * requires it to equal `sessionId`; a mismatch is why tools refuse. */
1057
+ authorizedSessionId: string | null;
957
1058
  }
958
1059
  interface VoiceStartOptions {
959
1060
  /** Hand the mic to a specific skill on connect (voice /session → takeMic),
960
1061
  * exactly as `sys.focusUiPlugin("platform:voice", { skillSlug })` does. */
961
1062
  skillSlug?: string;
1063
+ /**
1064
+ * A PER-CALL persona override, same shape as the authored
1065
+ * `solution.voice.persona` ({ name, style }). Declared on the voice
1066
+ * session-create call (POST /session `persona`); the server sanitizes it
1067
+ * (name/style only, length-capped) and layers it OVER the solution's authored
1068
+ * persona for THIS call only — prompt-layer, so it can never touch caller
1069
+ * verification or tool allow-lists. Set once at session start and constant
1070
+ * for the call, so it adds no per-turn prompt pushes.
1071
+ *
1072
+ * Use it when a plugin needs its own voice persona without owning a skill
1073
+ * (e.g. a guide HUD). A solution-wide persona belongs in solution.voice.
1074
+ */
1075
+ persona?: VoicePersona;
1076
+ /**
1077
+ * `'none'` = a CLEAN call: the voice gets none of the workspace's skills — no
1078
+ * skill manifest, no skill tools, no platform welcome line, no mid-call
1079
+ * skill-state prompt refresh — only the voice basics, this call's persona and
1080
+ * the CALLING plugin's own device tools (other solutions' tools registered on
1081
+ * the same phone are neither offered nor run). For a plugin that owns its conversation (e.g.
1082
+ * a guide HUD). Reduce-only: it can remove what the voice gets, never add.
1083
+ * Absent = the workspace's skills, as today. Not combinable with `skillSlug`.
1084
+ */
1085
+ skills?: 'none';
1086
+ }
1087
+ /** The authored persona shape (solution.voice.persona). */
1088
+ interface VoicePersona {
1089
+ /** The name the voice uses for itself ("You are <name> …"). */
1090
+ name?: string;
1091
+ /** Free-text style/behaviour guidance rendered under the identity line. */
1092
+ style?: string;
962
1093
  }
963
1094
  /**
964
1095
  * What changed. Coarse on purpose: `state` covers connect/mute/session/partials,
@@ -1411,6 +1542,108 @@ interface VisionAPI {
1411
1542
  /** Measure whether a frame is usable. Feeds VisualFrameRef.quality. */
1412
1543
  assessQuality(frameId: string): Promise<VisionFrameQuality>;
1413
1544
  }
1545
+ /** The same `{ latitude, longitude }` `location.getCurrent` returns, so a fix
1546
+ * passes straight in. */
1547
+ interface MapsCoordinate {
1548
+ latitude: number;
1549
+ longitude: number;
1550
+ }
1551
+ /** A postal address, field by field. `null` = the map data has no value — never
1552
+ * an empty string, which would read as a street with no name. */
1553
+ interface MapsAddress {
1554
+ /** The placemark's own name — a building, or often number + street. */
1555
+ name: string | null;
1556
+ street: string | null;
1557
+ streetNumber: string | null;
1558
+ /** Neighbourhood / sub-locality. */
1559
+ district: string | null;
1560
+ city: string | null;
1561
+ /** State / province / administrative area. */
1562
+ region: string | null;
1563
+ postalCode: string | null;
1564
+ country: string | null;
1565
+ /** ISO 3166-1 alpha-2, e.g. "GB". */
1566
+ isoCountryCode: string | null;
1567
+ }
1568
+ interface MapsPlace {
1569
+ /** What the map calls it ("Boots", "10 Downing St"). Null when unnamed. */
1570
+ name: string | null;
1571
+ coordinate: MapsCoordinate;
1572
+ address: MapsAddress;
1573
+ /** Apple's point-of-interest category as a vocabulary term ("Pharmacy",
1574
+ * "Cafe", "PublicTransport") — NOT free text. Null for a plain address, or
1575
+ * when the service gives none. */
1576
+ category: string | null;
1577
+ /** Straight-line metres from `opts.near`, when you passed one — NOT walking
1578
+ * distance (ask `route` for that). Null without `near`. */
1579
+ distanceM: number | null;
1580
+ }
1581
+ interface MapsRouteStep {
1582
+ /** Apple's instruction ("Turn right onto Baker St"). The FIRST step is usually
1583
+ * an origin step with an empty instruction — kept, not dropped, so step
1584
+ * indexes line up with Apple's. */
1585
+ instructions: string;
1586
+ distanceM: number;
1587
+ /** An advisory Apple attaches to this step. Null when there is none. */
1588
+ notice: string | null;
1589
+ polyline: MapsCoordinate[];
1590
+ }
1591
+ interface MapsRoute {
1592
+ mode: 'walking';
1593
+ distanceM: number;
1594
+ /** Apple's estimate for the whole route. */
1595
+ expectedTravelTimeMs: number;
1596
+ steps: MapsRouteStep[];
1597
+ /** The whole route, start to end. */
1598
+ polyline: MapsCoordinate[];
1599
+ }
1600
+ interface MapsAPI {
1601
+ /** Can this build search and route? True when the AdaMaps module is in the
1602
+ * binary (iOS). False on Android and on an older build — `reverseGeocode`
1603
+ * does not need the module and may still work there. */
1604
+ isSupported(): Promise<boolean>;
1605
+ /**
1606
+ * Find places by free text — "pharmacy", "10 Downing Street".
1607
+ *
1608
+ * `near` centres the search on a coordinate YOU supply, within `radiusM`
1609
+ * (default 3000, above 0 and at most 100 000). On iOS 18+ results are
1610
+ * confined to that area; before 18 it is a strong hint and a farther result
1611
+ * can come back — each result's `distanceM` says how far. At most `limit`
1612
+ * results (default 8, from 1; more than 25 is capped at 25).
1613
+ *
1614
+ * Network, Apple's servers. `[]` = Apple looked and found nothing. iOS only:
1615
+ * throws UNAVAILABLE on Android or a build without AdaMaps.
1616
+ */
1617
+ search(query: string, opts?: {
1618
+ near?: MapsCoordinate;
1619
+ radiusM?: number;
1620
+ limit?: number;
1621
+ }): Promise<MapsPlace[]>;
1622
+ /**
1623
+ * What is at a coordinate — its address and name.
1624
+ *
1625
+ * iOS AND Android (the platform geocoder); needs no AdaMaps module. The
1626
+ * result's `coordinate` is the point you asked about, and its
1627
+ * `category` / `distanceM` are null. `null` = nothing there.
1628
+ *
1629
+ * Network, not on-device. iOS reports a rate limit and a lost connection as
1630
+ * the SAME error, so OFFLINE here can also mean "too many requests". Android's
1631
+ * geocoder refuses without location permission (UNAVAILABLE) — that is the
1632
+ * platform's rule, not a location read.
1633
+ */
1634
+ reverseGeocode(at: MapsCoordinate): Promise<MapsPlace | null>;
1635
+ /**
1636
+ * A walking route between two coordinates YOU supply.
1637
+ *
1638
+ * `null` = Apple found no route — never a fake 0 m route, which would read as
1639
+ * "you have arrived". Walking is the only mode; any other refuses by name.
1640
+ * Network, Apple's servers. iOS only: throws UNAVAILABLE on Android or a build
1641
+ * without AdaMaps.
1642
+ */
1643
+ route(from: MapsCoordinate, to: MapsCoordinate, opts?: {
1644
+ mode?: 'walking';
1645
+ }): Promise<MapsRoute | null>;
1646
+ }
1414
1647
  interface BluetoothAPI {
1415
1648
  /** Is BLE hardware present and permitted? */
1416
1649
  isSupported(): Promise<boolean>;
@@ -1481,6 +1714,9 @@ interface PluginNative {
1481
1714
  bluetooth: BluetoothAPI;
1482
1715
  /** SHAPE ONLY in this build — see VisionAPI. On-device image understanding. */
1483
1716
  vision: VisionAPI;
1717
+ /** Place search, reverse geocoding, walking routes — see MapsAPI. Sends
1718
+ * queries to Apple's map servers; NOT on-device. */
1719
+ maps: MapsAPI;
1484
1720
  }
1485
1721
  interface NativeCapabilities$1 {
1486
1722
  camera?: boolean;
@@ -1496,6 +1732,9 @@ interface NativeCapabilities$1 {
1496
1732
  /** On-device image understanding (OCR, labels, frame quality). Refuses by
1497
1733
  * name until the native module lands — see VisionAPI. */
1498
1734
  vision?: boolean;
1735
+ /** Place search, reverse geocoding, walking routes. Means "may send place
1736
+ * queries to Apple Maps" — network, not on-device. See MapsAPI. */
1737
+ maps?: boolean;
1499
1738
  /** The live voice SESSION (props.voice). A privacy surface — a declaring
1500
1739
  * plugin can read the conversation transcript — so it is gated like any
1501
1740
  * other capability, and coupled to the platform's unsuppressable mic
@@ -1649,8 +1888,9 @@ interface PluginManifest$1 {
1649
1888
  };
1650
1889
  capabilities?: Record<string, unknown>;
1651
1890
  /** L3 DeviceState domains this plugin reads (props.deviceState), as Core passes
1652
- * them through from the bundle's declaration. Absent → fall back to the loaded
1653
- * bundle's own `stateDomains`. Read via resolvePluginRuntimeProps. */
1891
+ * them through from the solution's declaration. Absent → NO domains (fail
1892
+ * closed): the loaded bundle's own `stateDomains` is never consulted when a
1893
+ * manifest exists. Read via resolvePluginRuntimeProps. */
1654
1894
  stateDomains?: DeviceBridgeDomain[];
1655
1895
  _source?: string;
1656
1896
  _connectorId?: string;
@@ -1688,6 +1928,9 @@ interface DeviceToolContext {
1688
1928
  * the same gating a UI plugin's `props.deviceState` gets. This is what lets an
1689
1929
  * EXTERNAL tool (e.g. Ada Guide's `guide.observe`) read `ctx.deviceState.visual`
1690
1930
  * over the public surface, with no SDK-internal access.
1931
+ *
1932
+ * `subscribe` refuses (RESTRICTED) on every domain: a call has no lifetime to
1933
+ * own a subscription, and the engines outlive it. Read instead.
1691
1934
  */
1692
1935
  deviceState: DeviceState;
1693
1936
  /** Cooperative cancellation: caller cancelled, or the session went away. */
@@ -1708,9 +1951,10 @@ interface RegisteredToolsPlugin {
1708
1951
  type: 'tools';
1709
1952
  capabilities?: NativeCapabilities$1;
1710
1953
  /**
1711
- * L3 DeviceState domains this plugin's tools may read via `ctx.deviceState`
1712
- * (e.g. `['visual']`). Undeclared domains answer "not declared". Same
1713
- * mechanism as a UI plugin's manifest `stateDomains`.
1954
+ * L3 DeviceState domains this plugin's tools read via `ctx.deviceState` (e.g.
1955
+ * `['visual']`). For a remote bundle this is the author's statement, not a
1956
+ * grant: the tools get the manifest's `stateDomains` (resolvePluginGrants),
1957
+ * and a domain declared here but not there is denied with a warning.
1714
1958
  */
1715
1959
  stateDomains?: DeviceBridgeDomain[];
1716
1960
  tools: DeviceToolDefinition[];
@@ -1748,7 +1992,8 @@ declare function register(id: string, config: {
1748
1992
  */
1749
1993
  declare function registerTools(id: string, config: {
1750
1994
  capabilities?: NativeCapabilities$1;
1751
- /** L3 DeviceState domains the tools may read via ctx.deviceState (e.g. ['visual']). */
1995
+ /** L3 DeviceState domains the tools read via ctx.deviceState (e.g. ['visual']).
1996
+ * For a remote bundle the MANIFEST grants them — see RegisteredToolsPlugin. */
1752
1997
  stateDomains?: DeviceBridgeDomain[];
1753
1998
  tools: DeviceToolDefinition[];
1754
1999
  }): RegisteredToolsPlugin;
@@ -2006,11 +2251,6 @@ interface PluginRuntimeProps {
2006
2251
  deviceState: DeviceState;
2007
2252
  voice: VoiceAPI;
2008
2253
  }
2009
- /**
2010
- * Where a plugin's declarations come from. TRUSTED source resolution lives here,
2011
- * not in each caller: the server `manifest` wins, the loaded bundle's own default
2012
- * export is the fallback.
2013
- */
2014
2254
  /** One declaration source — either the server manifest or the registry entry. */
2015
2255
  interface PluginDeclaration {
2016
2256
  capabilities?: NativeCapabilities$1 | Record<string, unknown>;
@@ -2033,9 +2273,17 @@ interface PluginRuntimeSource {
2033
2273
  */
2034
2274
  plugin?: PluginDeclaration | null;
2035
2275
  }
2276
+ /** What a plugin is GRANTED — resolved from its one trusted source. The same
2277
+ * value gates its rendered surface and its device tools (the tool registry
2278
+ * receives it through bundleManager.load/loadTools). */
2279
+ interface PluginGrants {
2280
+ capabilities?: NativeCapabilities$1;
2281
+ stateDomains?: DeviceBridgeDomain[];
2282
+ }
2036
2283
  /**
2037
- * Turn a plugin's declarations into the gated { device, native, deviceState } it
2038
- * receives — the SINGLE place this happens, so every surface is identical.
2284
+ * Resolve a plugin's grants — the SINGLE place this happens, for every rendered
2285
+ * surface AND for the device tools its bundle registers, so a plugin gets
2286
+ * identical access through either.
2039
2287
  *
2040
2288
  * TRUST BOUNDARY. Exactly ONE source is authoritative: the server `manifest` for
2041
2289
  * a remote plugin, the registry `plugin` for a host-owned one. They are NEVER
@@ -2045,6 +2293,9 @@ interface PluginRuntimeSource {
2045
2293
  * not carry `stateDomains` for a remote plugin, the fix is Core passing it, not
2046
2294
  * trusting the bundle: Core already holds the solution's declaration.)
2047
2295
  */
2296
+ declare function resolvePluginGrants(src: PluginRuntimeSource): PluginGrants;
2297
+ /** Turn a plugin's grants into the gated { device, native, deviceState, voice } it
2298
+ * receives on every rendered surface. */
2048
2299
  declare function resolvePluginRuntimeProps(src: PluginRuntimeSource): PluginRuntimeProps;
2049
2300
 
2050
2301
  interface DeviceToolSummary {
@@ -2077,7 +2328,9 @@ declare function setDeviceToolContextProvider(fn: (pluginId: string, capabilitie
2077
2328
  declare function registerDeviceTools(pluginId: string, tools: DeviceToolDefinition[], capabilities?: NativeCapabilities$1, stateDomains?: DeviceBridgeDomain[]): string[];
2078
2329
  /** Drop every tool owned by a plugin (bundle eviction / plugin revoked). */
2079
2330
  declare function unregisterDeviceTools(pluginId: string): void;
2080
- declare function hasDeviceTool(name: string): boolean;
2331
+ /** Is `name` registered — and, given `pluginId`, registered BY that plugin?
2332
+ * (A clean voice call only lets its owner's own tools run.) */
2333
+ declare function hasDeviceTool(name: string, pluginId?: string): boolean;
2081
2334
  declare function listDeviceTools(): DeviceToolSummary[];
2082
2335
  /**
2083
2336
  * Invoke a device tool. Never throws — every failure comes back as a typed
@@ -2210,6 +2463,9 @@ declare class BundleManager {
2210
2463
  * of the previous tenant's tools.
2211
2464
  */
2212
2465
  private registeredToolPluginIds;
2466
+ /** bundleUrl → the trusted declaration last recorded on its disk-cache entry
2467
+ * this session, so a memory hit with unchanged grants skips the index I/O. */
2468
+ private recordedDeclarations;
2213
2469
  /**
2214
2470
  * Enforce the in-memory tenant boundary. Call at the top of every public load
2215
2471
  * path, BEFORE any cache read.
@@ -2237,9 +2493,11 @@ declare class BundleManager {
2237
2493
  * tenant switch (or wipe) happened while this load was in flight. Its results
2238
2494
  * belong to a tenant that is no longer current and must be discarded. */
2239
2495
  private isStale;
2240
- /** Flip an existing provenance record to source:'memory' — a later serve of an
2241
- * already-evaluated bundle came from the in-memory cache, not a fresh
2242
- * download/disk read. No-op if nothing was recorded yet. */
2496
+ /** Record a memory serve: the running bytes are the already-evaluated module,
2497
+ * and `expected` is refreshed from the manifest hash the caller JUST passed —
2498
+ * so after a redeploy the record reads hash !== expected (STALE) instead of
2499
+ * the old in-sync pair. The ONE place both memory paths (load()'s early return
2500
+ * and loadModule's) record reuse. No-op if nothing was recorded yet. */
2243
2501
  private markMemoryHit;
2244
2502
  /**
2245
2503
  * Load a plugin component. Returns the RegisteredUIPlugin object.
@@ -2249,16 +2507,26 @@ declare class BundleManager {
2249
2507
  * provided for any bundle the user has not previously verified — without
2250
2508
  * it, a tampered bundle is `eval`'d as JS with full RN runtime + every
2251
2509
  * native capability the manifest declares.
2510
+ *
2511
+ * `grants` is what the MANIFEST grants this plugin (resolvePluginGrants) — the
2512
+ * only authority its device tools are registered under. Omitted (e.g. a
2513
+ * prewarm from the slim plugin list) → the bundle is loaded but its tools are
2514
+ * NOT registered: without the manifest there is nothing trusted to gate them
2515
+ * on, and registering with nothing would downgrade a registration the
2516
+ * manifest-driven tool loader already made.
2252
2517
  */
2253
- load(pluginId: string, bundleUrl: string, version: string, expectedHash?: string): Promise<RegisteredUIPlugin>;
2518
+ load(pluginId: string, bundleUrl: string, version: string, expectedHash?: string, grants?: PluginGrants): Promise<RegisteredUIPlugin>;
2254
2519
  /**
2255
2520
  * Load a bundle for its `tools/` section only — no UI required.
2256
2521
  *
2257
2522
  * Same download, same integrity check, same evaluation as `load()`; the only
2258
2523
  * difference is that a bundle exporting tools and no `Component` is a success
2259
2524
  * here rather than "no component found". Returns the tool names registered.
2525
+ *
2526
+ * `grants` is REQUIRED: the tools are registered under `pluginId` with exactly
2527
+ * what the manifest grants (see load()), never what the bundle claims.
2260
2528
  */
2261
- loadTools(pluginId: string, bundleUrl: string, version: string, expectedHash?: string): Promise<string[]>;
2529
+ loadTools(pluginId: string, bundleUrl: string, version: string, expectedHash: string | undefined, grants: PluginGrants): Promise<string[]>;
2262
2530
  /**
2263
2531
  * Prewarm: load every plugin bundle in the background after app boot, so a
2264
2532
  * later open is instant (in-memory hit) instead of round-tripping the
@@ -2270,6 +2538,8 @@ declare class BundleManager {
2270
2538
  bundleUrl: string;
2271
2539
  version: string;
2272
2540
  bundleHash?: string;
2541
+ /** The manifest's grants, when the caller has the manifest (see load()). */
2542
+ grants?: PluginGrants;
2273
2543
  }>): Promise<void>;
2274
2544
  /**
2275
2545
  * Clear all caches (in-memory + storage).
@@ -2290,11 +2560,36 @@ declare class BundleManager {
2290
2560
  getLoadedBundles(): LoadedBundleInfo[];
2291
2561
  private loadModule;
2292
2562
  /**
2293
- * Pick up every `tools` section in an evaluated bundle and put it in the
2294
- * device tool registry. Runs for UI, hybrid and tools-only bundles alike: a
2295
- * plugin that ships both gets its tools registered without its UI mounting.
2563
+ * Register THIS plugin's device tools under the TRUSTED declaration, then
2564
+ * record that declaration on the disk-cache entry. Runs on every trusted load
2565
+ * — memory hit included — so the grants in force are always the latest the
2566
+ * manifest gave (a revoked grant stops applying on the next load, not the next
2567
+ * app start). Callers run it only after their stale check.
2568
+ */
2569
+ private commitTools;
2570
+ /**
2571
+ * Put the plugin's own `tools` section in the device tool registry — under the
2572
+ * pluginId and grants the MANIFEST resolved, never the bundle's own `id`,
2573
+ * `capabilities` or `stateDomains`. A bundle is code the manifest authorised
2574
+ * by hash; what it may touch is the manifest's to say, same as its rendered
2575
+ * surface (resolvePluginRuntimeProps). Its own `id` would also let it register
2576
+ * as another plugin — including the host's platform tools, which a same-id
2577
+ * re-registration replaces.
2578
+ *
2579
+ * Only this plugin's export (the same lookup the component uses) is
2580
+ * registered. Another export's tools in the same bundle belong to another
2581
+ * plugin and register when THAT plugin's manifest loads it.
2296
2582
  */
2297
2583
  private registerToolsFromModule;
2584
+ /**
2585
+ * Record the trusted declaration on this tenant's disk-cache entry for the
2586
+ * bytes RUNNING — the recovery path (tools/loader loadFromDiskCache) has no
2587
+ * manifest and re-registers with exactly this. Only onto an entry this tenant
2588
+ * owns whose hash is the running hash: the grant was issued for these bytes,
2589
+ * and those are the bytes recovery will evaluate. Best-effort — a lost write
2590
+ * leaves no `trusted`, which recovery treats as fail closed.
2591
+ */
2592
+ private recordTrustedDeclaration;
2298
2593
  /**
2299
2594
  * Download + integrity-verify a bundle. Refuses to return when:
2300
2595
  * - manifest hash and computed hash disagree
@@ -2304,11 +2599,15 @@ declare class BundleManager {
2304
2599
  */
2305
2600
  private download;
2306
2601
  private evaluate;
2602
+ /** Find a plugin component in a loaded module. */
2603
+ private getComponentFromMemory;
2307
2604
  /**
2308
- * Find a plugin component in a loaded module.
2309
- * Handles: default export, direct key match, multi-plugin .id match.
2605
+ * Find THIS plugin's export in a loaded module — the one lookup both the
2606
+ * component and the device tools use, so a plugin's UI and its tools always
2607
+ * come from the same export. `accept` says what the caller needs from it.
2608
+ * Handles: direct key match, PascalCase key, default export, multi-plugin .id match.
2310
2609
  */
2311
- private getComponentFromMemory;
2610
+ private findPluginExport;
2312
2611
  private describeModule;
2313
2612
  }
2314
2613
  /** Singleton — shared across all plugin renderers */
@@ -2321,6 +2620,7 @@ declare const bundleManager: BundleManager;
2321
2620
  * default is in-memory (bundles re-download per app session — correct,
2322
2621
  * just slower on cold start).
2323
2622
  */
2623
+
2324
2624
  interface BundleCacheEntry {
2325
2625
  localPath: string;
2326
2626
  version: string;
@@ -2342,6 +2642,23 @@ interface BundleCacheEntry {
2342
2642
  * untrusted. Never read a missing tenant as "mine".
2343
2643
  */
2344
2644
  tenant?: string;
2645
+ /**
2646
+ * The trusted declaration these bytes' device tools were last registered
2647
+ * under: the pluginId and grants resolved from the server manifest that named
2648
+ * this bundle (resolvePluginGrants). Recorded so the disk-cache recovery path —
2649
+ * which runs exactly when there is NO manifest — re-registers with the same
2650
+ * authority instead of the bundle's own claim.
2651
+ *
2652
+ * Absent → no trusted declaration is known for these bytes, so recovery skips
2653
+ * the entry (fail closed) and the catalog path registers it once the owning
2654
+ * connector answers again.
2655
+ */
2656
+ trusted?: TrustedToolDeclaration;
2657
+ }
2658
+ /** Who a bundle's device tools belong to and what they are granted — always
2659
+ * from the manifest, never from the bundle. */
2660
+ interface TrustedToolDeclaration extends PluginGrants {
2661
+ pluginId: string;
2345
2662
  }
2346
2663
  interface BundleStorage {
2347
2664
  loadIndex(): Promise<Record<string, BundleCacheEntry>>;
@@ -2572,6 +2889,9 @@ interface PluginManifestLike {
2572
2889
  name?: string;
2573
2890
  render?: any;
2574
2891
  _connectorId?: string;
2892
+ capabilities?: Record<string, unknown>;
2893
+ native?: NativeCapabilities$1;
2894
+ stateDomains?: DeviceBridgeDomain[];
2575
2895
  }
2576
2896
  interface UsePluginResult {
2577
2897
  plugin: RegisteredUIPlugin | null;
@@ -2890,4 +3210,4 @@ declare function isInlineSurface(m: SurfaceManifest): m is InlineSurfaceManifest
2890
3210
 
2891
3211
  declare function SurfaceDispatcher(): react_jsx_runtime.JSX.Element;
2892
3212
 
2893
- 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 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, MemoryBundleStorage, type MountSurfaceManifest, type NativeCapabilities$1 as NativeCapabilities, type NfcAPI, type NotificationsAPI, PLATFORM_VOICE_CALLER, type PluginManifest as PlatformPluginManifest, type PluginBridge, type PluginContext, 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 SpatialIntent, type SpatialPoint, type SpatialSnapshot, type StateQuality, type StorageAPI, SurfaceCard, type SurfaceCardProps, SurfaceDispatcher, SurfaceDrawer, type SurfaceDrawerProps, SurfaceFullscreen, type SurfaceFullscreenProps, type SurfaceManifest, type SurfacePlacement, type SurfaceType, type SurfaceVisibility, TabBar, type ThemeTokens, type VisionAPI, type VisionFrameQuality, type VisionLabel, type VisionObject, type VisionText, type VisualSnapshot, type VoiceAPI, type VoiceCaller, type VoiceEvent, type VoiceSessionProvider, type VoiceSnapshot, type VoiceStartOptions, type VoiceState, type VoiceSubscription, type VoiceTranscriptEntry, type WebViewCookie, __resetSessionSyncForTest, bundleManager, callDeviceTool, clearDeviceTools, createNativeBridge, 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, register, registerBundleModules, registerDeviceTools, registerNativePlugin, registerPlatformDeviceTools, registerService, registerTools, resetDeviceToolLoader, resolvePluginRuntimeProps, resolvePluginUrl, setBundleStorage, setCameraPreviewProvider, setDeviceStateProvider, setDeviceToolContextProvider, setDeviceToolResultPoster, setHapticsProvider, setPluginNativeProvider, setPluginThemeColors, setVoiceProvider, supportsNative, supportsWebView, syncDeviceToolsForSession, unregisterDeviceTools, unregisterNativePlugin, useApi, useNativeBridge, usePlugin, usePluginTheme, useRemotePlugins, useSurfaceStore };
3213
+ 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 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 VoiceAPI, type VoiceCaller, type VoiceEvent, type VoicePersona, type VoiceSessionProvider, type VoiceSnapshot, type VoiceStartOptions, type VoiceState, type VoiceSubscription, type VoiceTranscriptEntry, type WebViewCookie, __resetSessionSyncForTest, bundleManager, callDeviceTool, clearDeviceTools, createNativeBridge, 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, register, registerBundleModules, registerDeviceTools, registerNativePlugin, registerPlatformDeviceTools, registerService, registerTools, resetDeviceToolLoader, resolvePluginGrants, resolvePluginRuntimeProps, resolvePluginUrl, setBundleStorage, setCameraPreviewProvider, setDeviceStateProvider, setDeviceToolContextProvider, setDeviceToolResultPoster, setHapticsProvider, setPluginNativeProvider, setPluginThemeColors, setVoiceProvider, supportsNative, supportsWebView, syncDeviceToolsForSession, unregisterDeviceTools, unregisterNativePlugin, useApi, useNativeBridge, usePlugin, usePluginTheme, useRemotePlugins, useSurfaceStore };