@ateam-ai-mobile/ui 0.1.5 → 0.1.7
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 +325 -21
- package/dist/index.d.ts +325 -21
- package/dist/index.js +1127 -176
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1120 -177
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
- package/src/WorkspaceBanner.tsx +71 -0
- package/src/auth/HandoffScreen.tsx +94 -0
- package/src/auth/JoinScreen.tsx +145 -0
- package/src/auth/LoginScreen.tsx +181 -0
- package/src/auth/OpenJoinScreen.tsx +131 -0
- package/src/auth/handoffExchange.ts +49 -0
- package/src/auth/inviteJoin.ts +44 -0
- package/src/auth/login.ts +57 -0
- package/src/auth/openJoin.ts +56 -0
- package/src/chat/MessageBubble.tsx +3 -0
- package/src/index.ts +38 -1
- package/src/plugin/Plugin.tsx +14 -9
- package/src/providers.ts +44 -0
- package/src/voice/VoiceCallSheet.tsx +4 -32
- package/src/voice/VoiceMicIndicator.tsx +99 -0
- package/src/voice/VoiceSessionHost.tsx +77 -0
- package/src/voice/useVoiceCall.ts +40 -231
- package/src/voice/voiceSession.ts +628 -0
package/dist/index.d.mts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
-
import { Message, JobProgress, UIAction, AdasSession, TenantMembership } from '@ateam-ai-mobile/core';
|
|
3
|
-
import * as
|
|
4
|
-
import
|
|
5
|
-
import
|
|
2
|
+
import { Message, JobProgress, UIAction, AdasSession, TenantMembership, HandoffExchangeResult, ConsumerSignInResult, InvitePreview, ConsumerCapabilityConfig } from '@ateam-ai-mobile/core';
|
|
3
|
+
import * as React$1 from 'react';
|
|
4
|
+
import React__default, { ReactNode } from 'react';
|
|
5
|
+
import * as _ateam_ai_mobile_plugin_runtime from '@ateam-ai-mobile/plugin-runtime';
|
|
6
|
+
import { PluginSurfaceMeta, PlatformPluginManifest, VoiceState, VoiceTranscriptEntry, VoiceSessionProvider, VoiceStartOptions, VoiceCaller, VoiceSnapshot, VoiceEvent, VoiceSubscription } from '@ateam-ai-mobile/plugin-runtime';
|
|
6
7
|
import * as zustand from 'zustand';
|
|
7
8
|
|
|
8
9
|
interface AdasChatScreenProps {
|
|
@@ -70,7 +71,7 @@ interface PluginRendererProps {
|
|
|
70
71
|
/** Plugin manifest (from API) */
|
|
71
72
|
manifest: any;
|
|
72
73
|
/** Shared command buffer from parent — captures commands before plugin mounts */
|
|
73
|
-
commandBufferRef?:
|
|
74
|
+
commandBufferRef?: React__default.MutableRefObject<any[]>;
|
|
74
75
|
/** Engine-supplied props from sys.focusUiPlugin(id, props) — forwarded to
|
|
75
76
|
* the plugin Component as `PluginProps.props`. */
|
|
76
77
|
props?: any;
|
|
@@ -126,7 +127,7 @@ declare function EmbeddedPluginWebView({ pluginId, manifest, commandBufferRef }:
|
|
|
126
127
|
declare function usePluginBridge(pluginId: string, connectorId?: string, commandBufferRef?: React.MutableRefObject<any[]>, wsRef?: {
|
|
127
128
|
current: WebSocket | null;
|
|
128
129
|
}): {
|
|
129
|
-
webViewRef:
|
|
130
|
+
webViewRef: React$1.RefObject<any>;
|
|
130
131
|
sendInit: () => void;
|
|
131
132
|
handleMessage: (event: {
|
|
132
133
|
nativeEvent: {
|
|
@@ -174,6 +175,203 @@ interface LightboxState {
|
|
|
174
175
|
}
|
|
175
176
|
declare const useLightboxStore: zustand.UseBoundStore<zustand.StoreApi<LightboxState>>;
|
|
176
177
|
|
|
178
|
+
interface WorkspaceBannerProps {
|
|
179
|
+
/** Extra top inset (e.g. safe-area) so the banner clears the status bar. */
|
|
180
|
+
topInset?: number;
|
|
181
|
+
}
|
|
182
|
+
declare function WorkspaceBanner({ topInset }: WorkspaceBannerProps): react_jsx_runtime.JSX.Element | null;
|
|
183
|
+
|
|
184
|
+
interface HandoffScreenProps {
|
|
185
|
+
/** The one-time handoff code the host captured from the deep link (null = nothing pending). */
|
|
186
|
+
code: string | null;
|
|
187
|
+
/**
|
|
188
|
+
* Adopt the handed-off tenant. AWAITED before onSignedIn so the host's active
|
|
189
|
+
* tenant is set before the session reads it (the exchange result carries the
|
|
190
|
+
* tenant the code was bound to). No-op is fine when the result has no tenant.
|
|
191
|
+
*/
|
|
192
|
+
onAdoptTenant: (tenant: string) => void | Promise<void>;
|
|
193
|
+
/** Adopt the session JWT (host wires its authStore.login → core session + tenantConfirmed). */
|
|
194
|
+
onSignedIn: (jwt: string) => void | Promise<void>;
|
|
195
|
+
/** Clear the consumed single-use code so a relaunch never retries it. Called after success. */
|
|
196
|
+
onDone: () => void;
|
|
197
|
+
/** Back to sign in — the host toggles the pre-auth phase (not a router). */
|
|
198
|
+
onCancel: () => void;
|
|
199
|
+
}
|
|
200
|
+
declare function HandoffScreen({ code, onAdoptTenant, onSignedIn, onDone, onCancel }: HandoffScreenProps): react_jsx_runtime.JSX.Element;
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* Handoff exchange — the pure, testable half of HandoffScreen (R9B).
|
|
204
|
+
*
|
|
205
|
+
* Kept JSX-free in its own module (like R6's runLogoutTeardown) so the
|
|
206
|
+
* security-sensitive error mapper and the adopt-before-sign-in ORDERING can be
|
|
207
|
+
* node-tested directly, without rendering the RN component.
|
|
208
|
+
*/
|
|
209
|
+
|
|
210
|
+
interface HandoffExchangeDeps {
|
|
211
|
+
/** Trade the one-time code for a session JWT (host injects core.exchangeHandoff). */
|
|
212
|
+
exchange: (code: string) => Promise<HandoffExchangeResult>;
|
|
213
|
+
/** Adopt the handed-off tenant (host's single tenant writer). */
|
|
214
|
+
onAdoptTenant: (tenant: string) => void | Promise<void>;
|
|
215
|
+
/** Adopt the session JWT. */
|
|
216
|
+
onSignedIn: (jwt: string) => void | Promise<void>;
|
|
217
|
+
/** Clear the consumed single-use code. */
|
|
218
|
+
onDone: () => void;
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Run the handoff: exchange → (adopt tenant) → sign in → clear the code, in that
|
|
222
|
+
* exact order. The tenant adoption is AWAITED BEFORE onSignedIn so the host's
|
|
223
|
+
* active tenant is set before the session reads it — a cross-tenant handoff must
|
|
224
|
+
* never sign in under the wrong tenant. Throws on any failure (the caller maps it
|
|
225
|
+
* to a user-facing message); onSignedIn / onDone never run on the error path.
|
|
226
|
+
*/
|
|
227
|
+
declare function runHandoffExchange(code: string, deps: HandoffExchangeDeps): Promise<void>;
|
|
228
|
+
/**
|
|
229
|
+
* Map the server's rejection to plainer copy. SECURITY: the exchange endpoint
|
|
230
|
+
* deliberately does NOT tell an anonymous caller whether a code was unknown (404)
|
|
231
|
+
* vs used/expired (410) — distinguishing them would confirm a real code to a
|
|
232
|
+
* replay attacker. So both collapse to ONE message; never promise "expired" vs
|
|
233
|
+
* "already used". 429 is the one safe-to-distinguish case (a rate-limit hint
|
|
234
|
+
* leaks nothing about code validity).
|
|
235
|
+
*/
|
|
236
|
+
declare function handoffErrorMessage(msg?: string): string;
|
|
237
|
+
|
|
238
|
+
interface OpenJoinScreenProps {
|
|
239
|
+
/** Adopt the joined tenant (host's single ACTIVE_TENANT writer), awaited before sign-in. */
|
|
240
|
+
onAdoptTenant: (tenant: string) => void | Promise<void>;
|
|
241
|
+
/** Adopt the session JWT (host: authStore.login → core session + tenantConfirmed). */
|
|
242
|
+
onSignedIn: (jwt: string) => void | Promise<void>;
|
|
243
|
+
/** Back to sign in — the host toggles the pre-auth phase (not a router). */
|
|
244
|
+
onBack: () => void;
|
|
245
|
+
}
|
|
246
|
+
declare function OpenJoinScreen({ onAdoptTenant, onSignedIn, onBack }: OpenJoinScreenProps): react_jsx_runtime.JSX.Element;
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* Open self-signup — the pure, testable half of OpenJoinScreen (R9B).
|
|
250
|
+
*
|
|
251
|
+
* JSX-free so the join ORDERING (join → adopt tenant → sign in) and the error
|
|
252
|
+
* mapper are node-testable without rendering. The native id_token acquisition
|
|
253
|
+
* happens in the component via getOAuthProvider(); the acquired token is passed
|
|
254
|
+
* in here, so this module stays pure and provider-free.
|
|
255
|
+
*/
|
|
256
|
+
|
|
257
|
+
interface OpenJoinDeps {
|
|
258
|
+
/** Exchange { tenant, id_token } for a session JWT (host injects core.openJoinWith*). */
|
|
259
|
+
join: (slug: string, idToken: string) => Promise<ConsumerSignInResult>;
|
|
260
|
+
/** Adopt the joined tenant (host's single ACTIVE_TENANT writer). */
|
|
261
|
+
onAdoptTenant: (tenant: string) => void | Promise<void>;
|
|
262
|
+
/** Adopt the session JWT. */
|
|
263
|
+
onSignedIn: (jwt: string) => void | Promise<void>;
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* Complete an open self-signup with an already-acquired id_token.
|
|
267
|
+
*
|
|
268
|
+
* Returns false WITHOUT side effects when idToken is null — the caller acquired
|
|
269
|
+
* no token (the user cancelled the native sheet, or it returned none), which is
|
|
270
|
+
* a silent no-op, never an error. Otherwise: join → adopt the joined tenant →
|
|
271
|
+
* sign in, in that order (the tenant is adopted only AFTER the server confirms
|
|
272
|
+
* the join, and BEFORE sign-in so the session reads the right tenant). Throws on
|
|
273
|
+
* a join failure (the caller maps it to a message); sign-in never runs then.
|
|
274
|
+
*/
|
|
275
|
+
declare function completeOpenJoin(slug: string, idToken: string | null, deps: OpenJoinDeps): Promise<boolean>;
|
|
276
|
+
/**
|
|
277
|
+
* Map the server's open-join rejection to plainer copy. Unlike the handoff
|
|
278
|
+
* exchange, these ARE safe to distinguish — the caller already knows the tenant
|
|
279
|
+
* slug they typed, so "invite-only" / "no such team" leak nothing.
|
|
280
|
+
*/
|
|
281
|
+
declare function openJoinErrorMessage(msg?: string): string;
|
|
282
|
+
|
|
283
|
+
interface JoinScreenProps {
|
|
284
|
+
/** The invite code the host captured from the deep link. */
|
|
285
|
+
code: string | null;
|
|
286
|
+
/** Adopt the session JWT (host: authStore.login → core session + tenantConfirmed). */
|
|
287
|
+
onSignedIn: (jwt: string) => void | Promise<void>;
|
|
288
|
+
/** Clear the consumed single-use invite so a relaunch never retries it. */
|
|
289
|
+
onDone: () => void;
|
|
290
|
+
/** Dismiss on a bad invite — the host toggles the pre-auth phase (not a router). */
|
|
291
|
+
onCancel: () => void;
|
|
292
|
+
}
|
|
293
|
+
declare function JoinScreen({ code, onSignedIn, onDone, onCancel }: JoinScreenProps): react_jsx_runtime.JSX.Element;
|
|
294
|
+
|
|
295
|
+
/**
|
|
296
|
+
* Invite join — the pure, testable half of JoinScreen (R9B).
|
|
297
|
+
*
|
|
298
|
+
* JSX-free so the join ORDERING and the header derivation are node-testable
|
|
299
|
+
* without rendering. The native id_token acquisition happens in the component via
|
|
300
|
+
* getOAuthProvider(); the acquired token is passed in here.
|
|
301
|
+
*/
|
|
302
|
+
|
|
303
|
+
interface InviteJoinDeps {
|
|
304
|
+
/** Exchange { invite, id_token } for a tenant-scoped JWT (host injects core.joinWith*). */
|
|
305
|
+
join: (code: string, idToken: string) => Promise<ConsumerSignInResult>;
|
|
306
|
+
/** Clear the consumed single-use invite (host store). */
|
|
307
|
+
onDone: () => void;
|
|
308
|
+
/** Adopt the session JWT. */
|
|
309
|
+
onSignedIn: (jwt: string) => void | Promise<void>;
|
|
310
|
+
}
|
|
311
|
+
/**
|
|
312
|
+
* Complete an invite join with an already-acquired id_token.
|
|
313
|
+
*
|
|
314
|
+
* Returns false WITHOUT side effects when idToken is null (user cancelled the
|
|
315
|
+
* native sheet). Otherwise: join → clear the consumed invite → sign in, in that
|
|
316
|
+
* order (matching the app: the invite is cleared before sign-in so a relaunch
|
|
317
|
+
* never retries a burned code). Throws on a join failure; the invite is NOT
|
|
318
|
+
* cleared and sign-in never runs then, so the user can retry the same invite.
|
|
319
|
+
*/
|
|
320
|
+
declare function completeInviteJoin(code: string, idToken: string | null, deps: InviteJoinDeps): Promise<boolean>;
|
|
321
|
+
/** The invite header copy. Role is optional — "Join <Org>?" when absent. */
|
|
322
|
+
declare function inviteHeadline(preview: InvitePreview | null): string;
|
|
323
|
+
|
|
324
|
+
interface LoginScreenProps {
|
|
325
|
+
/** The reactive pre-auth tenant pick (host: useSession().tenant). Re-fetches config on change. */
|
|
326
|
+
activeTenant: string;
|
|
327
|
+
/** The fallback tenant for the consumer-disabled self-heal guard (host: DEFAULT_TENANT). */
|
|
328
|
+
defaultTenant: string;
|
|
329
|
+
/** Reset to the default tenant + persist + bump activeTenant so this screen refetches. */
|
|
330
|
+
onConsumerDisabled: () => void | Promise<void>;
|
|
331
|
+
/** Adopt the session JWT (host: authStore.login → core session + tenantConfirmed). */
|
|
332
|
+
onSignedIn: (jwt: string) => void | Promise<void>;
|
|
333
|
+
/** Open the host's "join a team by name" (OpenJoin) sub-view. Link hidden when omitted. */
|
|
334
|
+
onJoinTeam?: () => void;
|
|
335
|
+
}
|
|
336
|
+
declare function LoginScreen({ activeTenant, defaultTenant, onConsumerDisabled, onSignedIn, onJoinTeam }: LoginScreenProps): react_jsx_runtime.JSX.Element;
|
|
337
|
+
|
|
338
|
+
/**
|
|
339
|
+
* Login — the pure, testable half of LoginScreen (R9B).
|
|
340
|
+
*
|
|
341
|
+
* JSX-free so the tenant client-id derivation, the consumer-disabled self-heal
|
|
342
|
+
* decision, and the sign-in ordering are node-testable without rendering.
|
|
343
|
+
*/
|
|
344
|
+
|
|
345
|
+
/**
|
|
346
|
+
* The Google client ids to sign in with, from the tenant's consumer config.
|
|
347
|
+
* webClientId sets the id_token AUDIENCE the server verifies; iosClientId makes
|
|
348
|
+
* the native account picker show (missing → the SDK silently falls back to a web
|
|
349
|
+
* flow on iOS). Accepts the legacy single `client_id` as the web id.
|
|
350
|
+
*/
|
|
351
|
+
declare function googleClientIds(config: ConsumerCapabilityConfig): {
|
|
352
|
+
webClientId: string;
|
|
353
|
+
iosClientId: string;
|
|
354
|
+
};
|
|
355
|
+
/**
|
|
356
|
+
* Whether a failed config fetch should self-heal by falling back to the default
|
|
357
|
+
* tenant. A consumer-DISABLED tenant 404s with "capability not enabled"; rather
|
|
358
|
+
* than dead-end the user on red text we coerce back to the default and refetch.
|
|
359
|
+
* Guarded by currentTenant !== defaultTenant so we never loop on the default.
|
|
360
|
+
*/
|
|
361
|
+
declare function shouldRecoverToDefaultTenant(errorMsg: string | undefined, currentTenant: string, defaultTenant: string): boolean;
|
|
362
|
+
interface ProviderSignInDeps {
|
|
363
|
+
/** Trade the provider id_token for a session JWT (host injects core.signInWith*). */
|
|
364
|
+
exchange: (idToken: string) => Promise<ConsumerSignInResult>;
|
|
365
|
+
/** Adopt the session JWT. */
|
|
366
|
+
onSignedIn: (jwt: string) => void | Promise<void>;
|
|
367
|
+
}
|
|
368
|
+
/**
|
|
369
|
+
* Complete a provider sign-in with an already-acquired id_token: exchange → sign
|
|
370
|
+
* in. Returns false WITHOUT side effects on a null token (user cancelled the
|
|
371
|
+
* native sheet). Throws on an exchange failure; sign-in never runs then.
|
|
372
|
+
*/
|
|
373
|
+
declare function completeProviderSignIn(idToken: string | null, deps: ProviderSignInDeps): Promise<boolean>;
|
|
374
|
+
|
|
177
375
|
interface Props {
|
|
178
376
|
visible: boolean;
|
|
179
377
|
onClose: () => void;
|
|
@@ -182,38 +380,144 @@ interface Props {
|
|
|
182
380
|
}
|
|
183
381
|
declare function VoiceCallSheet({ visible, onClose, skillSlug }: Props): react_jsx_runtime.JSX.Element | null;
|
|
184
382
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
383
|
+
type CallState = VoiceState;
|
|
384
|
+
type TranscriptEntry = VoiceTranscriptEntry;
|
|
385
|
+
interface InternalState {
|
|
386
|
+
callState: CallState;
|
|
387
|
+
sessionId: string | null;
|
|
388
|
+
error: string | null;
|
|
389
|
+
transcript: TranscriptEntry[];
|
|
390
|
+
aiPartial: string;
|
|
391
|
+
userPartial: string;
|
|
392
|
+
muted: boolean;
|
|
393
|
+
/** User VAD, from the mini-app's speechActivity events. */
|
|
394
|
+
userSpeaking: boolean;
|
|
395
|
+
/** Epoch ms of the last speaking:false, or null before the first utterance. */
|
|
396
|
+
lastUserSpeechEndedAt: number | null;
|
|
397
|
+
/** The WebView should be mounted (a session is wanted / live). */
|
|
398
|
+
mounted: boolean;
|
|
399
|
+
/** The WebView source, computed ONCE at start() so state changes (transcript,
|
|
400
|
+
* partials) never remount the WebView and drop the session. */
|
|
401
|
+
webViewSource: {
|
|
402
|
+
uri: string;
|
|
403
|
+
} | null;
|
|
404
|
+
skillSlug?: string;
|
|
405
|
+
}
|
|
406
|
+
declare class VoiceSessionManager implements VoiceSessionProvider {
|
|
407
|
+
private state;
|
|
408
|
+
private listeners;
|
|
409
|
+
private webView;
|
|
410
|
+
private pending;
|
|
411
|
+
/**
|
|
412
|
+
* WHO owns the one physical session. Set to the caller that started it from
|
|
413
|
+
* idle (a plugin's pluginId, or the PLATFORM symbol for the built-in sheet),
|
|
414
|
+
* and kept after stop until the next start reassigns it — so a plugin can read
|
|
415
|
+
* its own just-ended transcript but another plugin never can.
|
|
416
|
+
*
|
|
417
|
+
* ISOLATION (GPT blocker on 8881225): every access is scoped through this. A
|
|
418
|
+
* different plugin must not read, control, or attach to another plugin's live
|
|
419
|
+
* conversation just because it declared voice.
|
|
420
|
+
*/
|
|
421
|
+
private owner;
|
|
422
|
+
/** The platform (built-in sheet, mic indicator, session host) sees and
|
|
423
|
+
* controls any session — it is the user's own surface. A plugin caller may
|
|
424
|
+
* only touch a session it owns. */
|
|
425
|
+
private canAccess;
|
|
426
|
+
private foreignError;
|
|
427
|
+
/** The offscreen WebView sets its ref here so the session can inject into it. */
|
|
428
|
+
setWebView(ref: {
|
|
429
|
+
injectJavaScript?: (js: string) => void;
|
|
430
|
+
} | null): void;
|
|
431
|
+
/** Whole state — the host reads `mounted` + `webViewSource` to decide what to
|
|
432
|
+
* render, and every reader derives its snapshot from this. */
|
|
433
|
+
getInternal(): Readonly<InternalState>;
|
|
434
|
+
readonly injectedTrackHook = "\n(function() {\n if (window._adaTrackHookInstalled) return;\n window._adaTrackHookInstalled = true;\n window._allAudioTracks = [];\n window._adaPeerConnections = [];\n\n function track(t) {\n if (t && t.kind === 'audio' && window._allAudioTracks.indexOf(t) === -1) {\n window._allAudioTracks.push(t);\n }\n }\n\n try {\n if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {\n const origGUM = navigator.mediaDevices.getUserMedia.bind(navigator.mediaDevices);\n navigator.mediaDevices.getUserMedia = async function(constraints) {\n const stream = await origGUM(constraints);\n if (constraints && constraints.audio) {\n try { stream.getAudioTracks().forEach(track); } catch (e) {}\n }\n return stream;\n };\n }\n } catch (e) {}\n\n try {\n if (window.RTCPeerConnection) {\n const origPC = window.RTCPeerConnection;\n const origAddTrack = origPC.prototype.addTrack;\n const origAddStream = origPC.prototype.addStream;\n const origAddTransceiver = origPC.prototype.addTransceiver;\n\n origPC.prototype.addTrack = function(t) {\n if (t && t.kind === 'audio') track(t);\n return origAddTrack.apply(this, arguments);\n };\n if (origAddStream) {\n origPC.prototype.addStream = function(stream) {\n try { stream.getAudioTracks().forEach(track); } catch (e) {}\n return origAddStream.apply(this, arguments);\n };\n }\n if (origAddTransceiver) {\n origPC.prototype.addTransceiver = function(arg) {\n if (arg && arg.kind === undefined && arg.track && arg.track.kind === 'audio') {\n track(arg.track);\n }\n const tx = origAddTransceiver.apply(this, arguments);\n try {\n if (tx && tx.sender && tx.sender.track && tx.sender.track.kind === 'audio') track(tx.sender.track);\n } catch (e) {}\n return tx;\n };\n }\n }\n } catch (e) {}\n\n window._adaSetMuted = function(muted) {\n let n = 0;\n if (Array.isArray(window._allAudioTracks)) {\n window._allAudioTracks.forEach(function(t) {\n try { t.enabled = !muted; n++; } catch (e) {}\n });\n }\n return n;\n };\n})(); true;\n";
|
|
435
|
+
start(opts?: VoiceStartOptions, caller?: VoiceCaller): Promise<VoiceSnapshot>;
|
|
436
|
+
stop(caller?: VoiceCaller): void;
|
|
437
|
+
setMuted(muted: boolean, caller?: VoiceCaller): void;
|
|
438
|
+
prompt(input: string, caller?: VoiceCaller): void;
|
|
439
|
+
/**
|
|
440
|
+
* Stream a silent observation into the live session — tell the model without
|
|
441
|
+
* asking it to speak. The cheap, high-frequency channel (safe once or twice a
|
|
442
|
+
* second) behind a future props.voice.observe(); today the host uses it to run
|
|
443
|
+
* the real-device stream proof (VOICE_RT_STREAM_DEVICE_PROOF) before the gated
|
|
444
|
+
* plugin API is added. Owner-scoped like every other control.
|
|
445
|
+
*/
|
|
446
|
+
observe(text: string, caller?: VoiceCaller): void;
|
|
447
|
+
getSnapshot(caller?: VoiceCaller): VoiceSnapshot;
|
|
448
|
+
private realSnapshot;
|
|
449
|
+
private foreignSnapshot;
|
|
450
|
+
subscribe(cb: (event: VoiceEvent) => void, caller?: VoiceCaller): VoiceSubscription;
|
|
451
|
+
transcript(caller?: VoiceCaller): TranscriptEntry[];
|
|
452
|
+
private buildUri;
|
|
453
|
+
/** Handle a postMessage from the WebView. `event` is the RN WebView event. */
|
|
454
|
+
handleMessage(event: any): void;
|
|
455
|
+
/** Answer "what device tools do you have?" — the client is the authority. */
|
|
456
|
+
private sendDeviceToolList;
|
|
457
|
+
/** Run a device tool and post the outcome back into the WebView. */
|
|
458
|
+
private runDeviceTool;
|
|
459
|
+
private setState;
|
|
460
|
+
private appendTranscript;
|
|
461
|
+
private emit;
|
|
462
|
+
private waitForConnect;
|
|
463
|
+
private resolvePending;
|
|
464
|
+
private rejectPending;
|
|
465
|
+
/** TEST ONLY: reset the singleton to a clean idle state (mirrors the
|
|
466
|
+
* __resetSessionSyncForTest precedent). Not part of any surface. */
|
|
467
|
+
__resetForTest(): void;
|
|
189
468
|
}
|
|
190
|
-
|
|
469
|
+
/** The one live session. Handed to setVoiceProvider(voiceSession) at startup. */
|
|
470
|
+
declare const voiceSession: VoiceSessionManager;
|
|
471
|
+
|
|
191
472
|
declare function useVoiceCall({ skillSlug }?: {
|
|
192
473
|
skillSlug?: string;
|
|
193
474
|
}): {
|
|
194
|
-
callState:
|
|
475
|
+
callState: _ateam_ai_mobile_plugin_runtime.VoiceState;
|
|
195
476
|
sessionId: string | null;
|
|
196
477
|
error: string | null;
|
|
197
|
-
transcript:
|
|
478
|
+
transcript: _ateam_ai_mobile_plugin_runtime.VoiceTranscriptEntry[];
|
|
198
479
|
aiPartial: string;
|
|
199
480
|
userPartial: string;
|
|
200
481
|
muted: boolean;
|
|
201
|
-
startCall: (
|
|
482
|
+
startCall: (opts?: {
|
|
483
|
+
skillSlug?: string;
|
|
484
|
+
}) => Promise<_ateam_ai_mobile_plugin_runtime.VoiceSnapshot>;
|
|
202
485
|
stopCall: () => void;
|
|
203
486
|
toggleMute: () => void;
|
|
204
|
-
handleWebViewMessage: (event: any) => void;
|
|
205
|
-
getWebViewSource: () => {
|
|
206
|
-
uri: string;
|
|
207
|
-
};
|
|
208
|
-
webViewRef: react.RefObject<any>;
|
|
209
|
-
injectedTrackHook: string;
|
|
210
487
|
};
|
|
211
488
|
|
|
489
|
+
declare function VoiceSessionHost(): react_jsx_runtime.JSX.Element | null;
|
|
490
|
+
|
|
491
|
+
declare function VoiceMicIndicator({ topInset }: {
|
|
492
|
+
topInset?: number;
|
|
493
|
+
}): react_jsx_runtime.JSX.Element | null;
|
|
494
|
+
|
|
212
495
|
/**
|
|
213
496
|
* Host integration points for @ateam-ai-mobile/ui — same DI pattern as
|
|
214
497
|
* @ateam-ai-mobile/plugin-runtime's host.ts. Everything has a safe default; the host
|
|
215
498
|
* (or @ateam-ai-mobile/expo) wires real implementations at startup.
|
|
216
499
|
*/
|
|
500
|
+
|
|
501
|
+
interface OAuthGoogleConfig {
|
|
502
|
+
webClientId?: string;
|
|
503
|
+
iosClientId?: string;
|
|
504
|
+
}
|
|
505
|
+
interface OAuthProvider {
|
|
506
|
+
/** Acquire a Google OIDC id_token. `cfg` present → tenant client ids; absent → host bundled id. Null on user-cancel. */
|
|
507
|
+
signInWithGoogle(cfg?: OAuthGoogleConfig): Promise<string | null>;
|
|
508
|
+
/** Acquire an Apple id_token. Null on user-cancel. */
|
|
509
|
+
signInWithApple(): Promise<string | null>;
|
|
510
|
+
/** AppleAuthentication.isAvailableAsync() (iOS 13+); resolves false everywhere else. Async so the screen probes in an effect, never renders a stale false. */
|
|
511
|
+
isAppleAvailable(): Promise<boolean>;
|
|
512
|
+
/** The real Apple HIG button as a slot — the screen decides WHEN to show it + supplies its layout `style`, the host supplies the native node + HIG chrome. */
|
|
513
|
+
renderAppleButton(props: {
|
|
514
|
+
onPress: () => void;
|
|
515
|
+
disabled: boolean;
|
|
516
|
+
style?: unknown;
|
|
517
|
+
}): ReactNode;
|
|
518
|
+
}
|
|
519
|
+
/** Register a native OAuth implementation (e.g. via @ateam-ai-mobile/expo). */
|
|
520
|
+
declare function setOAuthProvider(oauth: OAuthProvider | null): void;
|
|
217
521
|
interface ClipboardProvider {
|
|
218
522
|
setString(text: string): Promise<void>;
|
|
219
523
|
}
|
|
@@ -230,4 +534,4 @@ declare function setUIActionNavigator(navigate: UIActionNavigator | null): void;
|
|
|
230
534
|
type ExtraHostsGetter = () => string[];
|
|
231
535
|
declare function setPluginWebViewExtraHosts(getter: ExtraHostsGetter | null): void;
|
|
232
536
|
|
|
233
|
-
export { AdasChatScreen, type AdasChatScreenProps, type CallState, ChatInput, type ClipboardProvider, DaySeparator, EmbeddedPluginWebView, JobProgressBar, Lightbox, MessageBubble, Plugin, PluginSurface, TableCardBlock, TenantPicker, type TenantPickerProps, type TranscriptEntry, TypingIndicator, type UIActionRoute, UIActionsRow, VoiceCallSheet, WidgetHost, WidgetWebView, buildPluginBridgeJS, openWidget, setClipboardProvider, setPluginWebViewExtraHosts, setUIActionNavigator, useLightboxStore, usePluginBridge, useVoiceCall, useWidgetHostStore };
|
|
537
|
+
export { AdasChatScreen, type AdasChatScreenProps, type CallState, ChatInput, type ClipboardProvider, DaySeparator, EmbeddedPluginWebView, type HandoffExchangeDeps, HandoffScreen, type HandoffScreenProps, type InviteJoinDeps, JobProgressBar, JoinScreen, type JoinScreenProps, Lightbox, LoginScreen, type LoginScreenProps, MessageBubble, type OAuthGoogleConfig, type OAuthProvider, type OpenJoinDeps, OpenJoinScreen, type OpenJoinScreenProps, Plugin, PluginSurface, type ProviderSignInDeps, TableCardBlock, TenantPicker, type TenantPickerProps, type TranscriptEntry, TypingIndicator, type UIActionRoute, UIActionsRow, VoiceCallSheet, VoiceMicIndicator, VoiceSessionHost, WidgetHost, WidgetWebView, WorkspaceBanner, type WorkspaceBannerProps, buildPluginBridgeJS, completeInviteJoin, completeOpenJoin, completeProviderSignIn, googleClientIds, handoffErrorMessage, inviteHeadline, openJoinErrorMessage, openWidget, runHandoffExchange, setClipboardProvider, setOAuthProvider, setPluginWebViewExtraHosts, setUIActionNavigator, shouldRecoverToDefaultTenant, useLightboxStore, usePluginBridge, useVoiceCall, useWidgetHostStore, voiceSession };
|