@ateam-ai-mobile/ui 0.1.8 → 0.1.10
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 +63 -47
- package/dist/index.d.ts +63 -47
- package/dist/index.js +163 -70
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +195 -102
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
- package/src/auth/HandoffScreen.tsx +3 -11
- package/src/auth/LoginScreen.tsx +68 -17
- package/src/auth/OpenJoinScreen.tsx +4 -6
- package/src/auth/handoffExchange.ts +6 -9
- package/src/auth/login.ts +5 -10
- package/src/auth/openJoin.ts +5 -8
- package/src/index.ts +1 -1
- package/src/plugin/EmbeddedPluginWebView.tsx +4 -1
- package/src/voice/voiceSession.ts +150 -64
package/dist/index.d.mts
CHANGED
|
@@ -3,7 +3,7 @@ import { Message, JobProgress, UIAction, AdasSession, TenantMembership, HandoffE
|
|
|
3
3
|
import * as React$1 from 'react';
|
|
4
4
|
import React__default, { ReactNode } from 'react';
|
|
5
5
|
import * as _ateam_ai_mobile_plugin_runtime from '@ateam-ai-mobile/plugin-runtime';
|
|
6
|
-
import { PluginSurfaceMeta, PlatformPluginManifest, VoiceState, VoiceTranscriptEntry, VoiceSessionProvider, VoicePersona, VoiceStartOptions, VoiceCaller, VoiceSnapshot, VoiceEvent, VoiceSubscription } from '@ateam-ai-mobile/plugin-runtime';
|
|
6
|
+
import { PluginSurfaceMeta, PlatformPluginManifest, VoiceState, VoiceTranscriptEntry, VoiceSessionProvider, VoiceDeviceToolCall, VoicePersona, VoiceStartOptions, VoiceCaller, VoiceSnapshot, VoiceEvent, VoiceSubscription } from '@ateam-ai-mobile/plugin-runtime';
|
|
7
7
|
import * as zustand from 'zustand';
|
|
8
8
|
|
|
9
9
|
interface AdasChatScreenProps {
|
|
@@ -184,12 +184,6 @@ declare function WorkspaceBanner({ topInset }: WorkspaceBannerProps): react_jsx_
|
|
|
184
184
|
interface HandoffScreenProps {
|
|
185
185
|
/** The one-time handoff code the host captured from the deep link (null = nothing pending). */
|
|
186
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
187
|
/** Adopt the session JWT (host wires its authStore.login → core session + tenantConfirmed). */
|
|
194
188
|
onSignedIn: (jwt: string) => void | Promise<void>;
|
|
195
189
|
/** Clear the consumed single-use code so a relaunch never retries it. Called after success. */
|
|
@@ -197,32 +191,30 @@ interface HandoffScreenProps {
|
|
|
197
191
|
/** Back to sign in — the host toggles the pre-auth phase (not a router). */
|
|
198
192
|
onCancel: () => void;
|
|
199
193
|
}
|
|
200
|
-
declare function HandoffScreen({ code,
|
|
194
|
+
declare function HandoffScreen({ code, onSignedIn, onDone, onCancel }: HandoffScreenProps): react_jsx_runtime.JSX.Element;
|
|
201
195
|
|
|
202
196
|
/**
|
|
203
197
|
* Handoff exchange — the pure, testable half of HandoffScreen (R9B).
|
|
204
198
|
*
|
|
205
199
|
* Kept JSX-free in its own module (like R6's runLogoutTeardown) so the
|
|
206
|
-
* security-sensitive error mapper and the
|
|
200
|
+
* security-sensitive error mapper and the sign-in-before-clear ORDERING can be
|
|
207
201
|
* node-tested directly, without rendering the RN component.
|
|
208
202
|
*/
|
|
209
203
|
|
|
210
204
|
interface HandoffExchangeDeps {
|
|
211
205
|
/** Trade the one-time code for a session JWT (host injects core.exchangeHandoff). */
|
|
212
206
|
exchange: (code: string) => Promise<HandoffExchangeResult>;
|
|
213
|
-
/** Adopt the handed-off tenant (host's single tenant writer). */
|
|
214
|
-
onAdoptTenant: (tenant: string) => void | Promise<void>;
|
|
215
207
|
/** Adopt the session JWT. */
|
|
216
208
|
onSignedIn: (jwt: string) => void | Promise<void>;
|
|
217
209
|
/** Clear the consumed single-use code. */
|
|
218
210
|
onDone: () => void;
|
|
219
211
|
}
|
|
220
212
|
/**
|
|
221
|
-
* Run the handoff: exchange →
|
|
222
|
-
*
|
|
223
|
-
*
|
|
224
|
-
*
|
|
225
|
-
*
|
|
213
|
+
* Run the handoff: exchange → sign in → clear the code, in that exact order. The
|
|
214
|
+
* handed-off tenant is the JWT's own `tenant` claim (getTenant() reads it), so a
|
|
215
|
+
* cross-tenant handoff is scoped correctly with nothing for the host to store.
|
|
216
|
+
* Throws on any failure (the caller maps it to a user-facing message);
|
|
217
|
+
* onSignedIn / onDone never run on the error path.
|
|
226
218
|
*/
|
|
227
219
|
declare function runHandoffExchange(code: string, deps: HandoffExchangeDeps): Promise<void>;
|
|
228
220
|
/**
|
|
@@ -236,19 +228,17 @@ declare function runHandoffExchange(code: string, deps: HandoffExchangeDeps): Pr
|
|
|
236
228
|
declare function handoffErrorMessage(msg?: string): string;
|
|
237
229
|
|
|
238
230
|
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
231
|
/** Adopt the session JWT (host: authStore.login → core session + tenantConfirmed). */
|
|
242
232
|
onSignedIn: (jwt: string) => void | Promise<void>;
|
|
243
233
|
/** Back to sign in — the host toggles the pre-auth phase (not a router). */
|
|
244
234
|
onBack: () => void;
|
|
245
235
|
}
|
|
246
|
-
declare function OpenJoinScreen({
|
|
236
|
+
declare function OpenJoinScreen({ onSignedIn, onBack }: OpenJoinScreenProps): react_jsx_runtime.JSX.Element;
|
|
247
237
|
|
|
248
238
|
/**
|
|
249
239
|
* Open self-signup — the pure, testable half of OpenJoinScreen (R9B).
|
|
250
240
|
*
|
|
251
|
-
* JSX-free so the join ORDERING (join →
|
|
241
|
+
* JSX-free so the join ORDERING (join → sign in) and the error
|
|
252
242
|
* mapper are node-testable without rendering. The native id_token acquisition
|
|
253
243
|
* happens in the component via getOAuthProvider(); the acquired token is passed
|
|
254
244
|
* in here, so this module stays pure and provider-free.
|
|
@@ -257,8 +247,6 @@ declare function OpenJoinScreen({ onAdoptTenant, onSignedIn, onBack }: OpenJoinS
|
|
|
257
247
|
interface OpenJoinDeps {
|
|
258
248
|
/** Exchange { tenant, id_token } for a session JWT (host injects core.openJoinWith*). */
|
|
259
249
|
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
250
|
/** Adopt the session JWT. */
|
|
263
251
|
onSignedIn: (jwt: string) => void | Promise<void>;
|
|
264
252
|
}
|
|
@@ -267,10 +255,10 @@ interface OpenJoinDeps {
|
|
|
267
255
|
*
|
|
268
256
|
* Returns false WITHOUT side effects when idToken is null — the caller acquired
|
|
269
257
|
* no token (the user cancelled the native sheet, or it returned none), which is
|
|
270
|
-
* a silent no-op, never an error. Otherwise: join →
|
|
271
|
-
*
|
|
272
|
-
* the
|
|
273
|
-
* a
|
|
258
|
+
* a silent no-op, never an error. Otherwise: join → sign in. The joined tenant
|
|
259
|
+
* is the returned JWT's own `tenant` claim (getTenant() reads it), so there is
|
|
260
|
+
* nothing for the host to store. Throws on a join failure (the caller maps it to
|
|
261
|
+
* a message); sign-in never runs then.
|
|
274
262
|
*/
|
|
275
263
|
declare function completeOpenJoin(slug: string, idToken: string | null, deps: OpenJoinDeps): Promise<boolean>;
|
|
276
264
|
/**
|
|
@@ -322,18 +310,19 @@ declare function completeInviteJoin(code: string, idToken: string | null, deps:
|
|
|
322
310
|
declare function inviteHeadline(preview: InvitePreview | null): string;
|
|
323
311
|
|
|
324
312
|
interface LoginScreenProps {
|
|
325
|
-
/** The reactive pre-auth
|
|
313
|
+
/** The reactive pre-auth team (host: useSession().tenant). Re-fetches config on change.
|
|
314
|
+
* '' → the screen asks for the team. */
|
|
326
315
|
activeTenant: string;
|
|
327
|
-
/** The
|
|
328
|
-
|
|
329
|
-
/**
|
|
316
|
+
/** The user named a team to sign in to: the host stores it as its signed-out pick. */
|
|
317
|
+
onPickTenant: (tenant: string) => void | Promise<void>;
|
|
318
|
+
/** The team has no consumer sign-in: the host clears its pick (the screen asks for another). */
|
|
330
319
|
onConsumerDisabled: () => void | Promise<void>;
|
|
331
320
|
/** Adopt the session JWT (host: authStore.login → core session + tenantConfirmed). */
|
|
332
321
|
onSignedIn: (jwt: string) => void | Promise<void>;
|
|
333
322
|
/** Open the host's "join a team by name" (OpenJoin) sub-view. Link hidden when omitted. */
|
|
334
323
|
onJoinTeam?: () => void;
|
|
335
324
|
}
|
|
336
|
-
declare function LoginScreen({ activeTenant,
|
|
325
|
+
declare function LoginScreen({ activeTenant, onPickTenant, onConsumerDisabled, onSignedIn, onJoinTeam }: LoginScreenProps): react_jsx_runtime.JSX.Element;
|
|
337
326
|
|
|
338
327
|
/**
|
|
339
328
|
* Login — the pure, testable half of LoginScreen (R9B).
|
|
@@ -353,12 +342,11 @@ declare function googleClientIds(config: ConsumerCapabilityConfig): {
|
|
|
353
342
|
iosClientId: string;
|
|
354
343
|
};
|
|
355
344
|
/**
|
|
356
|
-
* Whether a failed config fetch
|
|
357
|
-
*
|
|
358
|
-
*
|
|
359
|
-
* Guarded by currentTenant !== defaultTenant so we never loop on the default.
|
|
345
|
+
* Whether a failed config fetch means the picked tenant has no consumer sign-in
|
|
346
|
+
* ("capability not enabled" 404). The host then clears its pick and shows its
|
|
347
|
+
* team picker — it never falls back to a default tenant.
|
|
360
348
|
*/
|
|
361
|
-
declare function
|
|
349
|
+
declare function isConsumerDisabled(errorMsg: string | undefined): boolean;
|
|
362
350
|
interface ProviderSignInDeps {
|
|
363
351
|
/** Trade the provider id_token for a session JWT (host injects core.signInWith*). */
|
|
364
352
|
exchange: (idToken: string) => Promise<ConsumerSignInResult>;
|
|
@@ -382,6 +370,13 @@ declare function VoiceCallSheet({ visible, onClose, skillSlug }: Props): react_j
|
|
|
382
370
|
|
|
383
371
|
type CallState = VoiceState;
|
|
384
372
|
type TranscriptEntry = VoiceTranscriptEntry;
|
|
373
|
+
/** A finished call, tagged with the session owner's pluginId when the tool is
|
|
374
|
+
* that plugin's own; null when it is not (another solution's tool, the
|
|
375
|
+
* platform's, an unregistered name, no name) — then only the platform sees it. */
|
|
376
|
+
interface DeviceToolRecord {
|
|
377
|
+
owner: string | null;
|
|
378
|
+
call: VoiceDeviceToolCall;
|
|
379
|
+
}
|
|
385
380
|
interface InternalState {
|
|
386
381
|
callState: CallState;
|
|
387
382
|
sessionId: string | null;
|
|
@@ -394,11 +389,11 @@ interface InternalState {
|
|
|
394
389
|
userSpeaking: boolean;
|
|
395
390
|
/** Epoch ms of the last speaking:false, or null before the first utterance. */
|
|
396
391
|
lastUserSpeechEndedAt: number | null;
|
|
397
|
-
/**
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
392
|
+
/** This session's finished device-tool calls: the LATEST per owner tag (see
|
|
393
|
+
* DeviceToolRecord), in the order they finished. The platform reads the last
|
|
394
|
+
* one; the owning plugin reads its own (lastDeviceToolFor) — one store, both
|
|
395
|
+
* views derived from it. */
|
|
396
|
+
deviceToolCalls: DeviceToolRecord[];
|
|
402
397
|
/** The WebView should be mounted (a session is wanted / live). */
|
|
403
398
|
mounted: boolean;
|
|
404
399
|
/** The WebView source, computed ONCE at start() so state changes (transcript,
|
|
@@ -461,6 +456,11 @@ declare class VoiceSessionManager implements VoiceSessionProvider {
|
|
|
461
456
|
* and the bundleManager registers a plugin's tools under that same id (never
|
|
462
457
|
* the bundle's own short `id`), so exact equality is the whole check. */
|
|
463
458
|
private toolScope;
|
|
459
|
+
/** Bumped whenever a session begins or ends. A device-tool call remembers the
|
|
460
|
+
* epoch it arrived in, and its outcome is recorded only if that session is
|
|
461
|
+
* still the current one — a tool that finishes after hang-up (or after a new
|
|
462
|
+
* call started) must not show up as the new session's last call. */
|
|
463
|
+
private sessionEpoch;
|
|
464
464
|
/** The platform (built-in sheet, mic indicator, session host) sees and
|
|
465
465
|
* controls any session — it is the user's own surface. A plugin caller may
|
|
466
466
|
* only touch a session it owns. */
|
|
@@ -486,13 +486,30 @@ declare class VoiceSessionManager implements VoiceSessionProvider {
|
|
|
486
486
|
*/
|
|
487
487
|
observe(text: string, caller?: VoiceCaller): void;
|
|
488
488
|
getSnapshot(caller?: VoiceCaller): VoiceSnapshot;
|
|
489
|
+
/** The snapshot for a caller that may access the session. Everything is the
|
|
490
|
+
* session's, except `lastDeviceTool`, which is scoped to the caller's tools. */
|
|
489
491
|
private realSnapshot;
|
|
492
|
+
/**
|
|
493
|
+
* The last finished device-tool call THIS caller may see. The platform (the
|
|
494
|
+
* user's own surface) sees every call. A plugin sees only calls to tools it
|
|
495
|
+
* registered — even on a session it owns, the model can call another
|
|
496
|
+
* solution's tool (a normal call offers every registered tool), and that
|
|
497
|
+
* tool's name and error are not this plugin's to read.
|
|
498
|
+
*/
|
|
499
|
+
private lastDeviceToolFor;
|
|
490
500
|
private foreignSnapshot;
|
|
491
501
|
subscribe(cb: (event: VoiceEvent) => void, caller?: VoiceCaller): VoiceSubscription;
|
|
492
502
|
transcript(caller?: VoiceCaller): TranscriptEntry[];
|
|
493
503
|
private buildUri;
|
|
494
504
|
/** Handle a postMessage from the WebView. `event` is the RN WebView event. */
|
|
495
505
|
handleMessage(event: any): void;
|
|
506
|
+
/**
|
|
507
|
+
* One device-tool call, arrival to outcome: validate → authorize → run. The
|
|
508
|
+
* answer goes back to the mini-app (the model reads it) AND becomes
|
|
509
|
+
* `lastDeviceTool` — the same object, recorded only once it is known, so a
|
|
510
|
+
* refused call never looks like one that ran.
|
|
511
|
+
*/
|
|
512
|
+
private handleDeviceToolCall;
|
|
496
513
|
/**
|
|
497
514
|
* Final authorization = Core's frozen allowset ∩ the current valid local
|
|
498
515
|
* registry, bound to the ACTIVE session. All must hold:
|
|
@@ -506,15 +523,14 @@ declare class VoiceSessionManager implements VoiceSessionProvider {
|
|
|
506
523
|
* No fallback to the live registry alone, ever.
|
|
507
524
|
*/
|
|
508
525
|
private isToolAuthorized;
|
|
509
|
-
/**
|
|
510
|
-
*
|
|
511
|
-
|
|
512
|
-
private postDeviceToolRefusal;
|
|
526
|
+
/** Answer the mini-app's pending device-tool request (a call's outcome, or the
|
|
527
|
+
* tool list) — it resolves the request with this payload by correlationId. */
|
|
528
|
+
private postDeviceToolResult;
|
|
513
529
|
/** PROPOSE the phone's available tools — this is an offer to Core, not the
|
|
514
530
|
* authorization set. Core sanitizes it and returns the accepted set in a
|
|
515
531
|
* `deviceToolAllowset` message, which is what actually gates execution. */
|
|
516
532
|
private sendDeviceToolList;
|
|
517
|
-
/** Run
|
|
533
|
+
/** Run an authorized device tool. Never throws: every failure is an answer. */
|
|
518
534
|
private runDeviceTool;
|
|
519
535
|
private setState;
|
|
520
536
|
private appendTranscript;
|
|
@@ -594,4 +610,4 @@ declare function setUIActionNavigator(navigate: UIActionNavigator | null): void;
|
|
|
594
610
|
type ExtraHostsGetter = () => string[];
|
|
595
611
|
declare function setPluginWebViewExtraHosts(getter: ExtraHostsGetter | null): void;
|
|
596
612
|
|
|
597
|
-
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,
|
|
613
|
+
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, isConsumerDisabled, openJoinErrorMessage, openWidget, runHandoffExchange, setClipboardProvider, setOAuthProvider, setPluginWebViewExtraHosts, setUIActionNavigator, useLightboxStore, usePluginBridge, useVoiceCall, useWidgetHostStore, voiceSession };
|
package/dist/index.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { Message, JobProgress, UIAction, AdasSession, TenantMembership, HandoffE
|
|
|
3
3
|
import * as React$1 from 'react';
|
|
4
4
|
import React__default, { ReactNode } from 'react';
|
|
5
5
|
import * as _ateam_ai_mobile_plugin_runtime from '@ateam-ai-mobile/plugin-runtime';
|
|
6
|
-
import { PluginSurfaceMeta, PlatformPluginManifest, VoiceState, VoiceTranscriptEntry, VoiceSessionProvider, VoicePersona, VoiceStartOptions, VoiceCaller, VoiceSnapshot, VoiceEvent, VoiceSubscription } from '@ateam-ai-mobile/plugin-runtime';
|
|
6
|
+
import { PluginSurfaceMeta, PlatformPluginManifest, VoiceState, VoiceTranscriptEntry, VoiceSessionProvider, VoiceDeviceToolCall, VoicePersona, VoiceStartOptions, VoiceCaller, VoiceSnapshot, VoiceEvent, VoiceSubscription } from '@ateam-ai-mobile/plugin-runtime';
|
|
7
7
|
import * as zustand from 'zustand';
|
|
8
8
|
|
|
9
9
|
interface AdasChatScreenProps {
|
|
@@ -184,12 +184,6 @@ declare function WorkspaceBanner({ topInset }: WorkspaceBannerProps): react_jsx_
|
|
|
184
184
|
interface HandoffScreenProps {
|
|
185
185
|
/** The one-time handoff code the host captured from the deep link (null = nothing pending). */
|
|
186
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
187
|
/** Adopt the session JWT (host wires its authStore.login → core session + tenantConfirmed). */
|
|
194
188
|
onSignedIn: (jwt: string) => void | Promise<void>;
|
|
195
189
|
/** Clear the consumed single-use code so a relaunch never retries it. Called after success. */
|
|
@@ -197,32 +191,30 @@ interface HandoffScreenProps {
|
|
|
197
191
|
/** Back to sign in — the host toggles the pre-auth phase (not a router). */
|
|
198
192
|
onCancel: () => void;
|
|
199
193
|
}
|
|
200
|
-
declare function HandoffScreen({ code,
|
|
194
|
+
declare function HandoffScreen({ code, onSignedIn, onDone, onCancel }: HandoffScreenProps): react_jsx_runtime.JSX.Element;
|
|
201
195
|
|
|
202
196
|
/**
|
|
203
197
|
* Handoff exchange — the pure, testable half of HandoffScreen (R9B).
|
|
204
198
|
*
|
|
205
199
|
* Kept JSX-free in its own module (like R6's runLogoutTeardown) so the
|
|
206
|
-
* security-sensitive error mapper and the
|
|
200
|
+
* security-sensitive error mapper and the sign-in-before-clear ORDERING can be
|
|
207
201
|
* node-tested directly, without rendering the RN component.
|
|
208
202
|
*/
|
|
209
203
|
|
|
210
204
|
interface HandoffExchangeDeps {
|
|
211
205
|
/** Trade the one-time code for a session JWT (host injects core.exchangeHandoff). */
|
|
212
206
|
exchange: (code: string) => Promise<HandoffExchangeResult>;
|
|
213
|
-
/** Adopt the handed-off tenant (host's single tenant writer). */
|
|
214
|
-
onAdoptTenant: (tenant: string) => void | Promise<void>;
|
|
215
207
|
/** Adopt the session JWT. */
|
|
216
208
|
onSignedIn: (jwt: string) => void | Promise<void>;
|
|
217
209
|
/** Clear the consumed single-use code. */
|
|
218
210
|
onDone: () => void;
|
|
219
211
|
}
|
|
220
212
|
/**
|
|
221
|
-
* Run the handoff: exchange →
|
|
222
|
-
*
|
|
223
|
-
*
|
|
224
|
-
*
|
|
225
|
-
*
|
|
213
|
+
* Run the handoff: exchange → sign in → clear the code, in that exact order. The
|
|
214
|
+
* handed-off tenant is the JWT's own `tenant` claim (getTenant() reads it), so a
|
|
215
|
+
* cross-tenant handoff is scoped correctly with nothing for the host to store.
|
|
216
|
+
* Throws on any failure (the caller maps it to a user-facing message);
|
|
217
|
+
* onSignedIn / onDone never run on the error path.
|
|
226
218
|
*/
|
|
227
219
|
declare function runHandoffExchange(code: string, deps: HandoffExchangeDeps): Promise<void>;
|
|
228
220
|
/**
|
|
@@ -236,19 +228,17 @@ declare function runHandoffExchange(code: string, deps: HandoffExchangeDeps): Pr
|
|
|
236
228
|
declare function handoffErrorMessage(msg?: string): string;
|
|
237
229
|
|
|
238
230
|
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
231
|
/** Adopt the session JWT (host: authStore.login → core session + tenantConfirmed). */
|
|
242
232
|
onSignedIn: (jwt: string) => void | Promise<void>;
|
|
243
233
|
/** Back to sign in — the host toggles the pre-auth phase (not a router). */
|
|
244
234
|
onBack: () => void;
|
|
245
235
|
}
|
|
246
|
-
declare function OpenJoinScreen({
|
|
236
|
+
declare function OpenJoinScreen({ onSignedIn, onBack }: OpenJoinScreenProps): react_jsx_runtime.JSX.Element;
|
|
247
237
|
|
|
248
238
|
/**
|
|
249
239
|
* Open self-signup — the pure, testable half of OpenJoinScreen (R9B).
|
|
250
240
|
*
|
|
251
|
-
* JSX-free so the join ORDERING (join →
|
|
241
|
+
* JSX-free so the join ORDERING (join → sign in) and the error
|
|
252
242
|
* mapper are node-testable without rendering. The native id_token acquisition
|
|
253
243
|
* happens in the component via getOAuthProvider(); the acquired token is passed
|
|
254
244
|
* in here, so this module stays pure and provider-free.
|
|
@@ -257,8 +247,6 @@ declare function OpenJoinScreen({ onAdoptTenant, onSignedIn, onBack }: OpenJoinS
|
|
|
257
247
|
interface OpenJoinDeps {
|
|
258
248
|
/** Exchange { tenant, id_token } for a session JWT (host injects core.openJoinWith*). */
|
|
259
249
|
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
250
|
/** Adopt the session JWT. */
|
|
263
251
|
onSignedIn: (jwt: string) => void | Promise<void>;
|
|
264
252
|
}
|
|
@@ -267,10 +255,10 @@ interface OpenJoinDeps {
|
|
|
267
255
|
*
|
|
268
256
|
* Returns false WITHOUT side effects when idToken is null — the caller acquired
|
|
269
257
|
* no token (the user cancelled the native sheet, or it returned none), which is
|
|
270
|
-
* a silent no-op, never an error. Otherwise: join →
|
|
271
|
-
*
|
|
272
|
-
* the
|
|
273
|
-
* a
|
|
258
|
+
* a silent no-op, never an error. Otherwise: join → sign in. The joined tenant
|
|
259
|
+
* is the returned JWT's own `tenant` claim (getTenant() reads it), so there is
|
|
260
|
+
* nothing for the host to store. Throws on a join failure (the caller maps it to
|
|
261
|
+
* a message); sign-in never runs then.
|
|
274
262
|
*/
|
|
275
263
|
declare function completeOpenJoin(slug: string, idToken: string | null, deps: OpenJoinDeps): Promise<boolean>;
|
|
276
264
|
/**
|
|
@@ -322,18 +310,19 @@ declare function completeInviteJoin(code: string, idToken: string | null, deps:
|
|
|
322
310
|
declare function inviteHeadline(preview: InvitePreview | null): string;
|
|
323
311
|
|
|
324
312
|
interface LoginScreenProps {
|
|
325
|
-
/** The reactive pre-auth
|
|
313
|
+
/** The reactive pre-auth team (host: useSession().tenant). Re-fetches config on change.
|
|
314
|
+
* '' → the screen asks for the team. */
|
|
326
315
|
activeTenant: string;
|
|
327
|
-
/** The
|
|
328
|
-
|
|
329
|
-
/**
|
|
316
|
+
/** The user named a team to sign in to: the host stores it as its signed-out pick. */
|
|
317
|
+
onPickTenant: (tenant: string) => void | Promise<void>;
|
|
318
|
+
/** The team has no consumer sign-in: the host clears its pick (the screen asks for another). */
|
|
330
319
|
onConsumerDisabled: () => void | Promise<void>;
|
|
331
320
|
/** Adopt the session JWT (host: authStore.login → core session + tenantConfirmed). */
|
|
332
321
|
onSignedIn: (jwt: string) => void | Promise<void>;
|
|
333
322
|
/** Open the host's "join a team by name" (OpenJoin) sub-view. Link hidden when omitted. */
|
|
334
323
|
onJoinTeam?: () => void;
|
|
335
324
|
}
|
|
336
|
-
declare function LoginScreen({ activeTenant,
|
|
325
|
+
declare function LoginScreen({ activeTenant, onPickTenant, onConsumerDisabled, onSignedIn, onJoinTeam }: LoginScreenProps): react_jsx_runtime.JSX.Element;
|
|
337
326
|
|
|
338
327
|
/**
|
|
339
328
|
* Login — the pure, testable half of LoginScreen (R9B).
|
|
@@ -353,12 +342,11 @@ declare function googleClientIds(config: ConsumerCapabilityConfig): {
|
|
|
353
342
|
iosClientId: string;
|
|
354
343
|
};
|
|
355
344
|
/**
|
|
356
|
-
* Whether a failed config fetch
|
|
357
|
-
*
|
|
358
|
-
*
|
|
359
|
-
* Guarded by currentTenant !== defaultTenant so we never loop on the default.
|
|
345
|
+
* Whether a failed config fetch means the picked tenant has no consumer sign-in
|
|
346
|
+
* ("capability not enabled" 404). The host then clears its pick and shows its
|
|
347
|
+
* team picker — it never falls back to a default tenant.
|
|
360
348
|
*/
|
|
361
|
-
declare function
|
|
349
|
+
declare function isConsumerDisabled(errorMsg: string | undefined): boolean;
|
|
362
350
|
interface ProviderSignInDeps {
|
|
363
351
|
/** Trade the provider id_token for a session JWT (host injects core.signInWith*). */
|
|
364
352
|
exchange: (idToken: string) => Promise<ConsumerSignInResult>;
|
|
@@ -382,6 +370,13 @@ declare function VoiceCallSheet({ visible, onClose, skillSlug }: Props): react_j
|
|
|
382
370
|
|
|
383
371
|
type CallState = VoiceState;
|
|
384
372
|
type TranscriptEntry = VoiceTranscriptEntry;
|
|
373
|
+
/** A finished call, tagged with the session owner's pluginId when the tool is
|
|
374
|
+
* that plugin's own; null when it is not (another solution's tool, the
|
|
375
|
+
* platform's, an unregistered name, no name) — then only the platform sees it. */
|
|
376
|
+
interface DeviceToolRecord {
|
|
377
|
+
owner: string | null;
|
|
378
|
+
call: VoiceDeviceToolCall;
|
|
379
|
+
}
|
|
385
380
|
interface InternalState {
|
|
386
381
|
callState: CallState;
|
|
387
382
|
sessionId: string | null;
|
|
@@ -394,11 +389,11 @@ interface InternalState {
|
|
|
394
389
|
userSpeaking: boolean;
|
|
395
390
|
/** Epoch ms of the last speaking:false, or null before the first utterance. */
|
|
396
391
|
lastUserSpeechEndedAt: number | null;
|
|
397
|
-
/**
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
392
|
+
/** This session's finished device-tool calls: the LATEST per owner tag (see
|
|
393
|
+
* DeviceToolRecord), in the order they finished. The platform reads the last
|
|
394
|
+
* one; the owning plugin reads its own (lastDeviceToolFor) — one store, both
|
|
395
|
+
* views derived from it. */
|
|
396
|
+
deviceToolCalls: DeviceToolRecord[];
|
|
402
397
|
/** The WebView should be mounted (a session is wanted / live). */
|
|
403
398
|
mounted: boolean;
|
|
404
399
|
/** The WebView source, computed ONCE at start() so state changes (transcript,
|
|
@@ -461,6 +456,11 @@ declare class VoiceSessionManager implements VoiceSessionProvider {
|
|
|
461
456
|
* and the bundleManager registers a plugin's tools under that same id (never
|
|
462
457
|
* the bundle's own short `id`), so exact equality is the whole check. */
|
|
463
458
|
private toolScope;
|
|
459
|
+
/** Bumped whenever a session begins or ends. A device-tool call remembers the
|
|
460
|
+
* epoch it arrived in, and its outcome is recorded only if that session is
|
|
461
|
+
* still the current one — a tool that finishes after hang-up (or after a new
|
|
462
|
+
* call started) must not show up as the new session's last call. */
|
|
463
|
+
private sessionEpoch;
|
|
464
464
|
/** The platform (built-in sheet, mic indicator, session host) sees and
|
|
465
465
|
* controls any session — it is the user's own surface. A plugin caller may
|
|
466
466
|
* only touch a session it owns. */
|
|
@@ -486,13 +486,30 @@ declare class VoiceSessionManager implements VoiceSessionProvider {
|
|
|
486
486
|
*/
|
|
487
487
|
observe(text: string, caller?: VoiceCaller): void;
|
|
488
488
|
getSnapshot(caller?: VoiceCaller): VoiceSnapshot;
|
|
489
|
+
/** The snapshot for a caller that may access the session. Everything is the
|
|
490
|
+
* session's, except `lastDeviceTool`, which is scoped to the caller's tools. */
|
|
489
491
|
private realSnapshot;
|
|
492
|
+
/**
|
|
493
|
+
* The last finished device-tool call THIS caller may see. The platform (the
|
|
494
|
+
* user's own surface) sees every call. A plugin sees only calls to tools it
|
|
495
|
+
* registered — even on a session it owns, the model can call another
|
|
496
|
+
* solution's tool (a normal call offers every registered tool), and that
|
|
497
|
+
* tool's name and error are not this plugin's to read.
|
|
498
|
+
*/
|
|
499
|
+
private lastDeviceToolFor;
|
|
490
500
|
private foreignSnapshot;
|
|
491
501
|
subscribe(cb: (event: VoiceEvent) => void, caller?: VoiceCaller): VoiceSubscription;
|
|
492
502
|
transcript(caller?: VoiceCaller): TranscriptEntry[];
|
|
493
503
|
private buildUri;
|
|
494
504
|
/** Handle a postMessage from the WebView. `event` is the RN WebView event. */
|
|
495
505
|
handleMessage(event: any): void;
|
|
506
|
+
/**
|
|
507
|
+
* One device-tool call, arrival to outcome: validate → authorize → run. The
|
|
508
|
+
* answer goes back to the mini-app (the model reads it) AND becomes
|
|
509
|
+
* `lastDeviceTool` — the same object, recorded only once it is known, so a
|
|
510
|
+
* refused call never looks like one that ran.
|
|
511
|
+
*/
|
|
512
|
+
private handleDeviceToolCall;
|
|
496
513
|
/**
|
|
497
514
|
* Final authorization = Core's frozen allowset ∩ the current valid local
|
|
498
515
|
* registry, bound to the ACTIVE session. All must hold:
|
|
@@ -506,15 +523,14 @@ declare class VoiceSessionManager implements VoiceSessionProvider {
|
|
|
506
523
|
* No fallback to the live registry alone, ever.
|
|
507
524
|
*/
|
|
508
525
|
private isToolAuthorized;
|
|
509
|
-
/**
|
|
510
|
-
*
|
|
511
|
-
|
|
512
|
-
private postDeviceToolRefusal;
|
|
526
|
+
/** Answer the mini-app's pending device-tool request (a call's outcome, or the
|
|
527
|
+
* tool list) — it resolves the request with this payload by correlationId. */
|
|
528
|
+
private postDeviceToolResult;
|
|
513
529
|
/** PROPOSE the phone's available tools — this is an offer to Core, not the
|
|
514
530
|
* authorization set. Core sanitizes it and returns the accepted set in a
|
|
515
531
|
* `deviceToolAllowset` message, which is what actually gates execution. */
|
|
516
532
|
private sendDeviceToolList;
|
|
517
|
-
/** Run
|
|
533
|
+
/** Run an authorized device tool. Never throws: every failure is an answer. */
|
|
518
534
|
private runDeviceTool;
|
|
519
535
|
private setState;
|
|
520
536
|
private appendTranscript;
|
|
@@ -594,4 +610,4 @@ declare function setUIActionNavigator(navigate: UIActionNavigator | null): void;
|
|
|
594
610
|
type ExtraHostsGetter = () => string[];
|
|
595
611
|
declare function setPluginWebViewExtraHosts(getter: ExtraHostsGetter | null): void;
|
|
596
612
|
|
|
597
|
-
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,
|
|
613
|
+
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, isConsumerDisabled, openJoinErrorMessage, openWidget, runHandoffExchange, setClipboardProvider, setOAuthProvider, setPluginWebViewExtraHosts, setUIActionNavigator, useLightboxStore, usePluginBridge, useVoiceCall, useWidgetHostStore, voiceSession };
|