realtime-avatar 0.11.0 → 0.11.2
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/{chunk-RVBBZCVM.js → chunk-MJJ6GSAU.js} +1 -1
- package/dist/{chunk-MBQ2VKLC.js → chunk-SKXUGNEK.js} +1 -1
- package/dist/express.d.ts +2 -2
- package/dist/express.js +2 -2
- package/dist/hono.d.ts +2 -2
- package/dist/hono.js +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/nextjs.d.ts +2 -2
- package/dist/nextjs.js +2 -2
- package/dist/{proxy-client-CWvT16wz.d.ts → proxy-client-D1Zm7reb.d.ts} +8 -1
- package/dist/react-native.d.ts +2 -2
- package/dist/react-native.js +8 -6
- package/dist/react.d.ts +12 -3
- package/dist/react.js +70 -15
- package/dist/server.d.ts +1 -1
- package/dist/server.js +1 -1
- package/dist/tanstack-start.d.ts +2 -2
- package/dist/tanstack-start.js +2 -2
- package/dist/{types-DrgyCwLC.d.ts → types-9a0bRdXl.d.ts} +1 -1
- package/dist/{types-FoJMJimV.d.ts → types-nxdohaiH.d.ts} +5 -0
- package/package.json +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { RealtimeAvatar, isQueued, RealtimeAvatarHttpError } from './chunk-
|
|
1
|
+
import { RealtimeAvatar, isQueued, RealtimeAvatarHttpError } from './chunk-SKXUGNEK.js';
|
|
2
2
|
|
|
3
3
|
// ../proxy/src/config.ts
|
|
4
4
|
var json = (body, status = 200) => new Response(JSON.stringify(body), {
|
|
@@ -218,7 +218,7 @@ function isTransient(cause) {
|
|
|
218
218
|
|
|
219
219
|
// ../http-client/src/client.ts
|
|
220
220
|
var DEFAULT_BASE_URL = "https://realtimeavatar.ai/api/v1";
|
|
221
|
-
var SDK_VERSION = "0.11.
|
|
221
|
+
var SDK_VERSION = "0.11.2";
|
|
222
222
|
var RealtimeAvatar = class {
|
|
223
223
|
#apiKey;
|
|
224
224
|
#baseUrl;
|
package/dist/express.d.ts
CHANGED
package/dist/express.js
CHANGED
package/dist/hono.d.ts
CHANGED
package/dist/hono.js
CHANGED
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { a as CallPolicy, C as CallMode, S as StartCallResult, E as EndCallOptions, A as Avatar, b as AvatarUpdate, c as AvatarSourceSwap, d as ClipLibraryDeclaration, e as ClipLibraryUpdate, L as LoopRedirect, f as ClipLibrary, g as AssetKind, h as Asset, i as ListSessionsOptions, U as UsageSessionPage, j as UsageSession, k as CreditBalance, T as TranscriptPayload } from './types-
|
|
2
|
-
export { l as AvatarClip, m as CallConnection, n as CallQueued, o as ClipDeclaration, p as ClipLibraryPlan, q as ClipSource, r as ContextMessage, s as EndCallReason, V as VideoPolicy, t as isQueued } from './types-
|
|
1
|
+
import { a as CallPolicy, C as CallMode, S as StartCallResult, E as EndCallOptions, A as Avatar, b as AvatarUpdate, c as AvatarSourceSwap, d as ClipLibraryDeclaration, e as ClipLibraryUpdate, L as LoopRedirect, f as ClipLibrary, g as AssetKind, h as Asset, i as ListSessionsOptions, U as UsageSessionPage, j as UsageSession, k as CreditBalance, T as TranscriptPayload } from './types-nxdohaiH.js';
|
|
2
|
+
export { l as AvatarClip, m as CallConnection, n as CallQueued, o as ClipDeclaration, p as ClipLibraryPlan, q as ClipSource, r as ContextMessage, s as EndCallReason, V as VideoPolicy, t as isQueued } from './types-nxdohaiH.js';
|
|
3
3
|
import { z } from 'zod';
|
|
4
4
|
|
|
5
5
|
interface RealtimeAvatarOptions {
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { RealtimeAvatar, RealtimeAvatarError, RealtimeAvatarHttpError, clipLibraryDeclarationSchema, isQueued, verifyTranscript } from './chunk-
|
|
1
|
+
export { RealtimeAvatar, RealtimeAvatarError, RealtimeAvatarHttpError, clipLibraryDeclarationSchema, isQueued, verifyTranscript } from './chunk-SKXUGNEK.js';
|
package/dist/nextjs.d.ts
CHANGED
package/dist/nextjs.js
CHANGED
|
@@ -468,7 +468,14 @@ type AvatarVideoSurfaceProps = {
|
|
|
468
468
|
idleReturnDelayMs?: number;
|
|
469
469
|
/**
|
|
470
470
|
* Maximum time without a newly presented decoded frame before the live layer is
|
|
471
|
-
* treated as stalled and
|
|
471
|
+
* treated as stalled and replaced by the idle/poster floor — i.e. how long the LAST
|
|
472
|
+
* live frame is held through a network gap. Default
|
|
473
|
+
* {@link DEFAULT_AVATAR_FRAME_STALL_MS} (2 s). Once two stalls land inside 15 s the
|
|
474
|
+
* link is treated as unstable and the hold steps up to
|
|
475
|
+
* {@link DEFAULT_AVATAR_UNSTABLE_STALL_MS} (4 s) until the window clears, so a
|
|
476
|
+
* flapping link settles on a briefly frozen face rather than a body swap per gap.
|
|
477
|
+
* A disconnect, a turn end (track muted) and a track that never presented a frame
|
|
478
|
+
* are not stalls and do not wait on this.
|
|
472
479
|
*/
|
|
473
480
|
frameStallMs?: number;
|
|
474
481
|
/** Extra className for the box (the layers fill it). */
|
package/dist/react-native.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { LiveKitRoomProps } from '@livekit/react-native';
|
|
2
2
|
export { AudioSession, VideoTrack, VideoTrackProps, registerGlobals } from '@livekit/react-native';
|
|
3
3
|
import { ReactNode, ReactElement } from 'react';
|
|
4
|
-
import { L as LiveKitSessionGrant, A as AvatarVideoFit } from './proxy-client-
|
|
5
|
-
export { a as AdaptivePlayoutController, b as AdaptivePlayoutDecision, c as AdaptivePlayoutOptions, d as AdaptivePlayoutSample, e as ApproachingEndEvent, f as ApproachingEndReason, g as AvatarSessionClient, B as BehaviorSnapshot, C as CallTranscript, h as CallTranscriptSegment, i as CartesiaTtsModel, j as ClipResult, k as ClosingTurnResult, l as CreditsLowEvent, D as DEFAULT_APPROACHING_END_LEAD_SECONDS, m as DEFAULT_CREDITS_LOW_LEAD_SECONDS, n as DEFAULT_GOVERNOR_CONFIG, o as DEFAULT_GRACE_CEILING_SECONDS, p as DEFAULT_GRACE_WINDOW_LEAD_SECONDS, q as DEFAULT_IDLE_SECONDS, r as DEFAULT_IDLE_WARN_LEAD_SECONDS, s as DEFAULT_TURN_TIMEOUT_SECONDS, E as EndReason, t as EndedEvent, u as ExtendResult, F as FishTtsModel, v as FreezeReadingFn, G as Governor, w as GovernorAction, x as GovernorConfig, y as GovernorSignal, z as GovernorState, H as GraceWindowClosedEvent, I as GraceWindowOpenEvent, J as GraceWindowState, K as IdleWarningEvent, M as InboundRtpCursor, N as InboundRtpReading, O as KnownBehaviorState, P as LLMProvider, Q as LLMSelection, R as LiveKitAvatarGrantState, S as LiveKitAvatarGrantStatus, T as LiveKitCapacityState, U as LiveKitConnectionStatus, V as LiveKitSessionRequest, W as LiveKitSessionStartResult, X as MAX_RECONNECT_ATTEMPTS, Y as MAX_SESSION_INSTRUCTIONS_CHARS, Z as ProxyClientOptions, _ as QualityCap, $ as RECONNECT_BACKOFF_MS, a0 as RealtimeAvatarRequestOptions, a1 as RealtimeSessionApi, a2 as RealtimeSessionMedia, a3 as RealtimeSessionRoomSinks, a4 as ReconnectPolicy, a5 as ReconnectingEvent, a6 as RecoveryState, a7 as RetryStep, a8 as SessionBehavior, a9 as SessionClip, aa as SessionClocks, ab as SessionEndReason, ac as SessionLifecycleApi, ad as SessionLifecyclePhase, ae as SessionLifecyclePhaseKind, af as SessionLifecycleRoomBridge, ag as SessionLifecycleRoomBridgeProps, ah as SurfaceLayers, ai as TurnState, aj as TurnTimeoutEvent, ak as UseAvatarQualityGovernorInput, al as UseLiveKitAvatarGrantInput, am as UseRealtimeSessionInput, an as UseSessionLifecycleInput, ao as VoiceSpec, ap as VoiceSpecInput, aq as capacityErrorFromBusy, ar as capacityStateFromGrant, as as createProxyClient, at as isNativeLiveTrackSubscribed, au as knownBehaviorStates, av as mapTurnState, aw as readInboundRtp, ax as sessionBehaviorSchema, ay as sessionClipSchema, az as splitCallTranscript, aA as useAvatarAdaptivePlayoutDelay, aB as useAvatarPlayoutDelay, aC as useAvatarQualityGovernor, aD as useCallTranscript, aE as useLiveKitAvatarGrant, aF as useLiveTrackProducing, aG as useMicLease, aH as useRealtimeSession, aI as useReleaseMicLeaseOnTrackEnded, aJ as useSessionLifecycle } from './proxy-client-
|
|
4
|
+
import { L as LiveKitSessionGrant, A as AvatarVideoFit } from './proxy-client-D1Zm7reb.js';
|
|
5
|
+
export { a as AdaptivePlayoutController, b as AdaptivePlayoutDecision, c as AdaptivePlayoutOptions, d as AdaptivePlayoutSample, e as ApproachingEndEvent, f as ApproachingEndReason, g as AvatarSessionClient, B as BehaviorSnapshot, C as CallTranscript, h as CallTranscriptSegment, i as CartesiaTtsModel, j as ClipResult, k as ClosingTurnResult, l as CreditsLowEvent, D as DEFAULT_APPROACHING_END_LEAD_SECONDS, m as DEFAULT_CREDITS_LOW_LEAD_SECONDS, n as DEFAULT_GOVERNOR_CONFIG, o as DEFAULT_GRACE_CEILING_SECONDS, p as DEFAULT_GRACE_WINDOW_LEAD_SECONDS, q as DEFAULT_IDLE_SECONDS, r as DEFAULT_IDLE_WARN_LEAD_SECONDS, s as DEFAULT_TURN_TIMEOUT_SECONDS, E as EndReason, t as EndedEvent, u as ExtendResult, F as FishTtsModel, v as FreezeReadingFn, G as Governor, w as GovernorAction, x as GovernorConfig, y as GovernorSignal, z as GovernorState, H as GraceWindowClosedEvent, I as GraceWindowOpenEvent, J as GraceWindowState, K as IdleWarningEvent, M as InboundRtpCursor, N as InboundRtpReading, O as KnownBehaviorState, P as LLMProvider, Q as LLMSelection, R as LiveKitAvatarGrantState, S as LiveKitAvatarGrantStatus, T as LiveKitCapacityState, U as LiveKitConnectionStatus, V as LiveKitSessionRequest, W as LiveKitSessionStartResult, X as MAX_RECONNECT_ATTEMPTS, Y as MAX_SESSION_INSTRUCTIONS_CHARS, Z as ProxyClientOptions, _ as QualityCap, $ as RECONNECT_BACKOFF_MS, a0 as RealtimeAvatarRequestOptions, a1 as RealtimeSessionApi, a2 as RealtimeSessionMedia, a3 as RealtimeSessionRoomSinks, a4 as ReconnectPolicy, a5 as ReconnectingEvent, a6 as RecoveryState, a7 as RetryStep, a8 as SessionBehavior, a9 as SessionClip, aa as SessionClocks, ab as SessionEndReason, ac as SessionLifecycleApi, ad as SessionLifecyclePhase, ae as SessionLifecyclePhaseKind, af as SessionLifecycleRoomBridge, ag as SessionLifecycleRoomBridgeProps, ah as SurfaceLayers, ai as TurnState, aj as TurnTimeoutEvent, ak as UseAvatarQualityGovernorInput, al as UseLiveKitAvatarGrantInput, am as UseRealtimeSessionInput, an as UseSessionLifecycleInput, ao as VoiceSpec, ap as VoiceSpecInput, aq as capacityErrorFromBusy, ar as capacityStateFromGrant, as as createProxyClient, at as isNativeLiveTrackSubscribed, au as knownBehaviorStates, av as mapTurnState, aw as readInboundRtp, ax as sessionBehaviorSchema, ay as sessionClipSchema, az as splitCallTranscript, aA as useAvatarAdaptivePlayoutDelay, aB as useAvatarPlayoutDelay, aC as useAvatarQualityGovernor, aD as useCallTranscript, aE as useLiveKitAvatarGrant, aF as useLiveTrackProducing, aG as useMicLease, aH as useRealtimeSession, aI as useReleaseMicLeaseOnTrackEnded, aJ as useSessionLifecycle } from './proxy-client-D1Zm7reb.js';
|
|
6
6
|
import { StyleProp, ViewStyle } from 'react-native';
|
|
7
7
|
export { useChat, useConnectionState, useLocalParticipant, useRoomContext, useTrackToggle, useTranscriptions, useVoiceAssistant } from '@livekit/components-react';
|
|
8
8
|
export { D as DEFAULT_AVATAR_PLAYOUT_DELAY_SECONDS } from './playout-delay-DWOc8iCl.js';
|
package/dist/react-native.js
CHANGED
|
@@ -837,9 +837,10 @@ var step = (g, s, nowMs, cfg = DEFAULT_GOVERNOR_CONFIG) => {
|
|
|
837
837
|
return { governor: g };
|
|
838
838
|
}
|
|
839
839
|
};
|
|
840
|
-
var resolveLowCapQuality = (declaredLayerQualities) => {
|
|
840
|
+
var resolveLowCapQuality = (declaredLayerQualities, failures = 0) => {
|
|
841
841
|
const sorted = [...declaredLayerQualities].sort((a, b) => a - b);
|
|
842
|
-
|
|
842
|
+
if (sorted.length < 2) return 1;
|
|
843
|
+
return failures >= 1 ? sorted[0] : sorted[sorted.length - 2];
|
|
843
844
|
};
|
|
844
845
|
|
|
845
846
|
// ../client/src/react/use-quality-governor.ts
|
|
@@ -959,10 +960,11 @@ function useAvatarQualityGovernor(input) {
|
|
|
959
960
|
return { freezeMs: 0, jitterRising: false };
|
|
960
961
|
}
|
|
961
962
|
};
|
|
962
|
-
const applyCap = (cap) => {
|
|
963
|
+
const applyCap = (cap, failures = 0) => {
|
|
963
964
|
try {
|
|
964
965
|
const lowCap = resolveLowCapQuality(
|
|
965
|
-
(targetPublication?.trackInfo?.layers ?? []).map((l) => l.quality)
|
|
966
|
+
(targetPublication?.trackInfo?.layers ?? []).map((l) => l.quality),
|
|
967
|
+
failures
|
|
966
968
|
);
|
|
967
969
|
targetPublication?.setVideoQuality?.(cap === "low" ? lowCap : VideoQuality.HIGH);
|
|
968
970
|
} catch {
|
|
@@ -987,13 +989,13 @@ function useAvatarQualityGovernor(input) {
|
|
|
987
989
|
pausedSinceTick = false;
|
|
988
990
|
const { governor, action } = step(gov, signal, Date.now(), config);
|
|
989
991
|
gov = governor;
|
|
990
|
-
if (action) applyCap(action.setCap);
|
|
992
|
+
if (action) applyCap(action.setCap, gov.failures);
|
|
991
993
|
} catch {
|
|
992
994
|
} finally {
|
|
993
995
|
tickRunning = false;
|
|
994
996
|
}
|
|
995
997
|
};
|
|
996
|
-
applyCap(gov.cap);
|
|
998
|
+
applyCap(gov.cap, gov.failures);
|
|
997
999
|
const handle = setInterval(() => void tick(), tickMs);
|
|
998
1000
|
return () => {
|
|
999
1001
|
disposed = true;
|
package/dist/react.d.ts
CHANGED
|
@@ -1,12 +1,21 @@
|
|
|
1
1
|
import { RegisteredTool, ToolRegistration } from './tools.js';
|
|
2
2
|
import { ReactNode } from 'react';
|
|
3
|
-
import { g as AvatarSessionClient, A as AvatarVideoFit } from './proxy-client-
|
|
4
|
-
export { a as AdaptivePlayoutController, b as AdaptivePlayoutDecision, c as AdaptivePlayoutOptions, d as AdaptivePlayoutSample, e as ApproachingEndEvent, f as ApproachingEndReason, aK as AvatarVideoSurface, aL as AvatarVideoSurfaceProps, B as BehaviorSnapshot, C as CallTranscript, h as CallTranscriptSegment, i as CartesiaTtsModel, j as ClipResult, k as ClosingTurnResult, l as CreditsLowEvent, D as DEFAULT_APPROACHING_END_LEAD_SECONDS, m as DEFAULT_CREDITS_LOW_LEAD_SECONDS, n as DEFAULT_GOVERNOR_CONFIG, o as DEFAULT_GRACE_CEILING_SECONDS, p as DEFAULT_GRACE_WINDOW_LEAD_SECONDS, q as DEFAULT_IDLE_SECONDS, r as DEFAULT_IDLE_WARN_LEAD_SECONDS, s as DEFAULT_TURN_TIMEOUT_SECONDS, E as EndReason, t as EndedEvent, u as ExtendResult, F as FishTtsModel, v as FreezeReadingFn, G as Governor, w as GovernorAction, x as GovernorConfig, y as GovernorSignal, z as GovernorState, H as GraceWindowClosedEvent, I as GraceWindowOpenEvent, J as GraceWindowState, K as IdleWarningEvent, M as InboundRtpCursor, N as InboundRtpReading, O as KnownBehaviorState, P as LLMProvider, Q as LLMSelection, R as LiveKitAvatarGrantState, S as LiveKitAvatarGrantStatus, T as LiveKitCapacityState, U as LiveKitConnectionStatus, V as LiveKitSessionRequest, W as LiveKitSessionStartResult, aM as LivePlaybackKeeper, X as MAX_RECONNECT_ATTEMPTS, Y as MAX_SESSION_INSTRUCTIONS_CHARS, aN as MIC_LEASE_ENDED_TIMEOUT_MS, aO as MicLease, aP as PlayableVideoElement, Z as ProxyClientOptions, _ as QualityCap, $ as RECONNECT_BACKOFF_MS, aQ as RealtimeAvatarCapacityError, aR as RealtimeAvatarLiveKitRoom, aS as RealtimeAvatarLiveKitRoomProps, a0 as RealtimeAvatarRequestOptions, a1 as RealtimeSessionApi, a2 as RealtimeSessionMedia, a3 as RealtimeSessionRoomSinks, a4 as ReconnectPolicy, a5 as ReconnectingEvent, a6 as RecoveryState, a7 as RetryStep, a8 as SessionBehavior, a9 as SessionClip, aa as SessionClocks, ab as SessionEndReason, ac as SessionLifecycleApi, ad as SessionLifecyclePhase, ae as SessionLifecyclePhaseKind, af as SessionLifecycleRoomBridge, ag as SessionLifecycleRoomBridgeProps, ah as SurfaceLayers, ai as TurnState, aj as TurnTimeoutEvent, ak as UseAvatarQualityGovernorInput, al as UseLiveKitAvatarGrantInput, am as UseRealtimeSessionInput, an as UseSessionLifecycleInput, ao as VoiceSpec, ap as VoiceSpecInput, aq as capacityErrorFromBusy, ar as capacityStateFromGrant, as as createProxyClient, au as knownBehaviorStates, av as mapTurnState, aw as readInboundRtp, ax as sessionBehaviorSchema, ay as sessionClipSchema, aT as shouldReplayPendingTurn, az as splitCallTranscript, aA as useAvatarAdaptivePlayoutDelay, aB as useAvatarPlayoutDelay, aC as useAvatarQualityGovernor, aD as useCallTranscript, aE as useLiveKitAvatarGrant, aG as useMicLease, aH as useRealtimeSession, aI as useReleaseMicLeaseOnTrackEnded, aJ as useSessionLifecycle } from './proxy-client-
|
|
3
|
+
import { g as AvatarSessionClient, A as AvatarVideoFit } from './proxy-client-D1Zm7reb.js';
|
|
4
|
+
export { a as AdaptivePlayoutController, b as AdaptivePlayoutDecision, c as AdaptivePlayoutOptions, d as AdaptivePlayoutSample, e as ApproachingEndEvent, f as ApproachingEndReason, aK as AvatarVideoSurface, aL as AvatarVideoSurfaceProps, B as BehaviorSnapshot, C as CallTranscript, h as CallTranscriptSegment, i as CartesiaTtsModel, j as ClipResult, k as ClosingTurnResult, l as CreditsLowEvent, D as DEFAULT_APPROACHING_END_LEAD_SECONDS, m as DEFAULT_CREDITS_LOW_LEAD_SECONDS, n as DEFAULT_GOVERNOR_CONFIG, o as DEFAULT_GRACE_CEILING_SECONDS, p as DEFAULT_GRACE_WINDOW_LEAD_SECONDS, q as DEFAULT_IDLE_SECONDS, r as DEFAULT_IDLE_WARN_LEAD_SECONDS, s as DEFAULT_TURN_TIMEOUT_SECONDS, E as EndReason, t as EndedEvent, u as ExtendResult, F as FishTtsModel, v as FreezeReadingFn, G as Governor, w as GovernorAction, x as GovernorConfig, y as GovernorSignal, z as GovernorState, H as GraceWindowClosedEvent, I as GraceWindowOpenEvent, J as GraceWindowState, K as IdleWarningEvent, M as InboundRtpCursor, N as InboundRtpReading, O as KnownBehaviorState, P as LLMProvider, Q as LLMSelection, R as LiveKitAvatarGrantState, S as LiveKitAvatarGrantStatus, T as LiveKitCapacityState, U as LiveKitConnectionStatus, V as LiveKitSessionRequest, W as LiveKitSessionStartResult, aM as LivePlaybackKeeper, X as MAX_RECONNECT_ATTEMPTS, Y as MAX_SESSION_INSTRUCTIONS_CHARS, aN as MIC_LEASE_ENDED_TIMEOUT_MS, aO as MicLease, aP as PlayableVideoElement, Z as ProxyClientOptions, _ as QualityCap, $ as RECONNECT_BACKOFF_MS, aQ as RealtimeAvatarCapacityError, aR as RealtimeAvatarLiveKitRoom, aS as RealtimeAvatarLiveKitRoomProps, a0 as RealtimeAvatarRequestOptions, a1 as RealtimeSessionApi, a2 as RealtimeSessionMedia, a3 as RealtimeSessionRoomSinks, a4 as ReconnectPolicy, a5 as ReconnectingEvent, a6 as RecoveryState, a7 as RetryStep, a8 as SessionBehavior, a9 as SessionClip, aa as SessionClocks, ab as SessionEndReason, ac as SessionLifecycleApi, ad as SessionLifecyclePhase, ae as SessionLifecyclePhaseKind, af as SessionLifecycleRoomBridge, ag as SessionLifecycleRoomBridgeProps, ah as SurfaceLayers, ai as TurnState, aj as TurnTimeoutEvent, ak as UseAvatarQualityGovernorInput, al as UseLiveKitAvatarGrantInput, am as UseRealtimeSessionInput, an as UseSessionLifecycleInput, ao as VoiceSpec, ap as VoiceSpecInput, aq as capacityErrorFromBusy, ar as capacityStateFromGrant, as as createProxyClient, au as knownBehaviorStates, av as mapTurnState, aw as readInboundRtp, ax as sessionBehaviorSchema, ay as sessionClipSchema, aT as shouldReplayPendingTurn, az as splitCallTranscript, aA as useAvatarAdaptivePlayoutDelay, aB as useAvatarPlayoutDelay, aC as useAvatarQualityGovernor, aD as useCallTranscript, aE as useLiveKitAvatarGrant, aG as useMicLease, aH as useRealtimeSession, aI as useReleaseMicLeaseOnTrackEnded, aJ as useSessionLifecycle } from './proxy-client-D1Zm7reb.js';
|
|
5
5
|
export { D as DEFAULT_AVATAR_PLAYOUT_DELAY_SECONDS } from './playout-delay-DWOc8iCl.js';
|
|
6
6
|
import 'zod';
|
|
7
7
|
import '@livekit/components-react';
|
|
8
8
|
import 'livekit-client';
|
|
9
9
|
|
|
10
|
+
/**
|
|
11
|
+
* Once a link has proven unstable, hold the frozen live frame this long before
|
|
12
|
+
* falling back to the idle floor. Measured on a prod rtx6000 call through a
|
|
13
|
+
* 900 kbit / 150 ms / 10 % loss link (2026-09-09): after the opening, presented-frame
|
|
14
|
+
* gaps cluster at 650–1150 ms with two multi-second outages around simulcast layer
|
|
15
|
+
* switches. Nothing shorter than a few seconds is worth a body swap on such a link.
|
|
16
|
+
*/
|
|
17
|
+
declare const DEFAULT_AVATAR_UNSTABLE_STALL_MS = 4000;
|
|
18
|
+
|
|
10
19
|
declare function useCharacterTools(tools: Record<string, RegisteredTool>, options?: {
|
|
11
20
|
onResult?: (event: {
|
|
12
21
|
name: string;
|
|
@@ -120,4 +129,4 @@ declare function useAvatarCall(props: AvatarCallProps): {
|
|
|
120
129
|
/** One component: a live character on screen. */
|
|
121
130
|
declare function AvatarCall(props: AvatarCallProps): ReactNode;
|
|
122
131
|
|
|
123
|
-
export { AvatarCall, type AvatarCallEndReason, type AvatarCallHandle, type AvatarCallProps, type AvatarCallStatus, AvatarSessionClient, AvatarVideoFit, useAvatarCall, useCharacterTools };
|
|
132
|
+
export { AvatarCall, type AvatarCallEndReason, type AvatarCallHandle, type AvatarCallProps, type AvatarCallStatus, AvatarSessionClient, AvatarVideoFit, DEFAULT_AVATAR_UNSTABLE_STALL_MS, useAvatarCall, useCharacterTools };
|
package/dist/react.js
CHANGED
|
@@ -1038,9 +1038,10 @@ var step = (g, s, nowMs, cfg = DEFAULT_GOVERNOR_CONFIG) => {
|
|
|
1038
1038
|
return { governor: g };
|
|
1039
1039
|
}
|
|
1040
1040
|
};
|
|
1041
|
-
var resolveLowCapQuality = (declaredLayerQualities) => {
|
|
1041
|
+
var resolveLowCapQuality = (declaredLayerQualities, failures = 0) => {
|
|
1042
1042
|
const sorted = [...declaredLayerQualities].sort((a, b) => a - b);
|
|
1043
|
-
|
|
1043
|
+
if (sorted.length < 2) return 1;
|
|
1044
|
+
return failures >= 1 ? sorted[0] : sorted[sorted.length - 2];
|
|
1044
1045
|
};
|
|
1045
1046
|
|
|
1046
1047
|
// ../client/src/react/use-quality-governor.ts
|
|
@@ -1160,10 +1161,11 @@ function useAvatarQualityGovernor(input) {
|
|
|
1160
1161
|
return { freezeMs: 0, jitterRising: false };
|
|
1161
1162
|
}
|
|
1162
1163
|
};
|
|
1163
|
-
const applyCap = (cap) => {
|
|
1164
|
+
const applyCap = (cap, failures = 0) => {
|
|
1164
1165
|
try {
|
|
1165
1166
|
const lowCap = resolveLowCapQuality(
|
|
1166
|
-
(targetPublication?.trackInfo?.layers ?? []).map((l) => l.quality)
|
|
1167
|
+
(targetPublication?.trackInfo?.layers ?? []).map((l) => l.quality),
|
|
1168
|
+
failures
|
|
1167
1169
|
);
|
|
1168
1170
|
targetPublication?.setVideoQuality?.(cap === "low" ? lowCap : VideoQuality.HIGH);
|
|
1169
1171
|
} catch {
|
|
@@ -1188,13 +1190,13 @@ function useAvatarQualityGovernor(input) {
|
|
|
1188
1190
|
pausedSinceTick = false;
|
|
1189
1191
|
const { governor, action } = step(gov, signal, Date.now(), config);
|
|
1190
1192
|
gov = governor;
|
|
1191
|
-
if (action) applyCap(action.setCap);
|
|
1193
|
+
if (action) applyCap(action.setCap, gov.failures);
|
|
1192
1194
|
} catch {
|
|
1193
1195
|
} finally {
|
|
1194
1196
|
tickRunning = false;
|
|
1195
1197
|
}
|
|
1196
1198
|
};
|
|
1197
|
-
applyCap(gov.cap);
|
|
1199
|
+
applyCap(gov.cap, gov.failures);
|
|
1198
1200
|
const handle = setInterval(() => void tick(), tickMs);
|
|
1199
1201
|
return () => {
|
|
1200
1202
|
disposed = true;
|
|
@@ -1234,9 +1236,48 @@ var FrameRecovery = class {
|
|
|
1234
1236
|
return this.ready;
|
|
1235
1237
|
}
|
|
1236
1238
|
};
|
|
1239
|
+
var AVATAR_FIRST_FRAME_GRACE_MS = 1e3;
|
|
1240
|
+
function firstFrameWaitFreezeMs(waitedMs) {
|
|
1241
|
+
if (!Number.isFinite(waitedMs) || waitedMs <= AVATAR_FIRST_FRAME_GRACE_MS) return 0;
|
|
1242
|
+
return waitedMs - AVATAR_FIRST_FRAME_GRACE_MS;
|
|
1243
|
+
}
|
|
1244
|
+
var DEFAULT_AVATAR_UNSTABLE_STALL_MS = 4e3;
|
|
1245
|
+
var AVATAR_UNSTABLE_LINK_STALLS = 2;
|
|
1246
|
+
var AVATAR_UNSTABLE_LINK_WINDOW_MS = 15e3;
|
|
1247
|
+
var StallEscalation = class {
|
|
1248
|
+
constructor(baseMs, unstableMs = DEFAULT_AVATAR_UNSTABLE_STALL_MS, windowMs = AVATAR_UNSTABLE_LINK_WINDOW_MS, stallsToEscalate = AVATAR_UNSTABLE_LINK_STALLS) {
|
|
1249
|
+
this.baseMs = baseMs;
|
|
1250
|
+
this.windowMs = windowMs;
|
|
1251
|
+
this.stallsToEscalate = stallsToEscalate;
|
|
1252
|
+
this.unstableMs = Math.max(baseMs, unstableMs);
|
|
1253
|
+
}
|
|
1254
|
+
baseMs;
|
|
1255
|
+
windowMs;
|
|
1256
|
+
stallsToEscalate;
|
|
1257
|
+
stallsAtMs = [];
|
|
1258
|
+
unstableMs;
|
|
1259
|
+
/** Record one stall EPISODE (the moment the live layer is hidden), not one poll tick. */
|
|
1260
|
+
recordStall(nowMs) {
|
|
1261
|
+
this.prune(nowMs);
|
|
1262
|
+
this.stallsAtMs.push(nowMs);
|
|
1263
|
+
}
|
|
1264
|
+
/** The threshold in force right now. */
|
|
1265
|
+
thresholdMs(nowMs) {
|
|
1266
|
+
this.prune(nowMs);
|
|
1267
|
+
return this.stallsAtMs.length >= this.stallsToEscalate ? this.unstableMs : this.baseMs;
|
|
1268
|
+
}
|
|
1269
|
+
/** Is the link currently considered unstable (escalated)? */
|
|
1270
|
+
unstable(nowMs) {
|
|
1271
|
+
return this.thresholdMs(nowMs) !== this.baseMs;
|
|
1272
|
+
}
|
|
1273
|
+
prune(nowMs) {
|
|
1274
|
+
const cutoff = nowMs - this.windowMs;
|
|
1275
|
+
while (this.stallsAtMs.length > 0 && this.stallsAtMs[0] < cutoff) this.stallsAtMs.shift();
|
|
1276
|
+
}
|
|
1277
|
+
};
|
|
1237
1278
|
|
|
1238
1279
|
// ../client/src/react/avatar-video-surface.ts
|
|
1239
|
-
var DEFAULT_AVATAR_FRAME_STALL_MS =
|
|
1280
|
+
var DEFAULT_AVATAR_FRAME_STALL_MS = 2e3;
|
|
1240
1281
|
var AVATAR_FRAME_GAP_FREEZE_FLOOR_MS = 100;
|
|
1241
1282
|
function AvatarVideoSurface(props) {
|
|
1242
1283
|
const {
|
|
@@ -1437,7 +1478,7 @@ function isFrameFlowingAt(snapshot) {
|
|
|
1437
1478
|
}
|
|
1438
1479
|
function freezeMsFromFrameGap(gapMs) {
|
|
1439
1480
|
if (!Number.isFinite(gapMs) || gapMs <= AVATAR_FRAME_GAP_FREEZE_FLOOR_MS) return 0;
|
|
1440
|
-
return gapMs;
|
|
1481
|
+
return gapMs - AVATAR_FRAME_GAP_FREEZE_FLOOR_MS;
|
|
1441
1482
|
}
|
|
1442
1483
|
function isFrameFreezeInhibited(snapshot) {
|
|
1443
1484
|
return snapshot.hidden || snapshot.resumePending || !snapshot.trackProducing || !snapshot.seenFrame || snapshot.lastFrameAtMs === null;
|
|
@@ -1445,6 +1486,7 @@ function isFrameFreezeInhibited(snapshot) {
|
|
|
1445
1486
|
function useLiveFrameFlow(wrapRef, trackProducing, trackIdentity, stallAfterMs) {
|
|
1446
1487
|
const boundedStallMs = normalizeFrameStallMs(stallAfterMs);
|
|
1447
1488
|
const recovery = useMemo(() => new FrameRecovery(boundedStallMs), [trackIdentity, boundedStallMs]);
|
|
1489
|
+
const escalation = useMemo(() => new StallEscalation(boundedStallMs), [trackIdentity, boundedStallMs]);
|
|
1448
1490
|
const [flowing, setFlowing] = useState(false);
|
|
1449
1491
|
const [seenFrame, setSeenFrame] = useState(false);
|
|
1450
1492
|
const flowingRef = useRef(false);
|
|
@@ -1452,14 +1494,16 @@ function useLiveFrameFlow(wrapRef, trackProducing, trackIdentity, stallAfterMs)
|
|
|
1452
1494
|
seenFrame: false,
|
|
1453
1495
|
lastFrameAtMs: null,
|
|
1454
1496
|
maxGapMs: 0,
|
|
1455
|
-
resumePending: false
|
|
1497
|
+
resumePending: false,
|
|
1498
|
+
producingSinceMs: null
|
|
1456
1499
|
});
|
|
1457
1500
|
useEffect(() => {
|
|
1458
1501
|
sampleRef.current = {
|
|
1459
1502
|
seenFrame: false,
|
|
1460
1503
|
lastFrameAtMs: null,
|
|
1461
1504
|
maxGapMs: 0,
|
|
1462
|
-
resumePending: document.visibilityState !== "visible"
|
|
1505
|
+
resumePending: document.visibilityState !== "visible",
|
|
1506
|
+
producingSinceMs: trackProducing ? Date.now() : null
|
|
1463
1507
|
};
|
|
1464
1508
|
flowingRef.current = false;
|
|
1465
1509
|
setSeenFrame(false);
|
|
@@ -1477,6 +1521,7 @@ function useLiveFrameFlow(wrapRef, trackProducing, trackIdentity, stallAfterMs)
|
|
|
1477
1521
|
lastCurrentTime = video?.currentTime ?? lastCurrentTime;
|
|
1478
1522
|
const firstFrame = !previous.seenFrame;
|
|
1479
1523
|
sampleRef.current = {
|
|
1524
|
+
producingSinceMs: previous.producingSinceMs,
|
|
1480
1525
|
seenFrame: true,
|
|
1481
1526
|
lastFrameAtMs: now,
|
|
1482
1527
|
// A hidden tab/bfcache resume is a local scheduling gap, not network
|
|
@@ -1488,6 +1533,7 @@ function useLiveFrameFlow(wrapRef, trackProducing, trackIdentity, stallAfterMs)
|
|
|
1488
1533
|
resumePending: false
|
|
1489
1534
|
};
|
|
1490
1535
|
if (firstFrame) setSeenFrame(true);
|
|
1536
|
+
recovery.stallAfterMs = escalation.thresholdMs(now);
|
|
1491
1537
|
const nextFlowing = recovery.frame(now);
|
|
1492
1538
|
if (flowingRef.current !== nextFlowing) {
|
|
1493
1539
|
flowingRef.current = nextFlowing;
|
|
@@ -1533,13 +1579,19 @@ function useLiveFrameFlow(wrapRef, trackProducing, trackIdentity, stallAfterMs)
|
|
|
1533
1579
|
lastCurrentTime = video.currentTime;
|
|
1534
1580
|
markFrame();
|
|
1535
1581
|
}
|
|
1582
|
+
const nowMs = Date.now();
|
|
1583
|
+
const stallAfterMs2 = escalation.thresholdMs(nowMs);
|
|
1584
|
+
recovery.stallAfterMs = stallAfterMs2;
|
|
1536
1585
|
const frameFresh = isFrameFlowingAt({
|
|
1537
1586
|
seenFrame: sampleRef.current.seenFrame,
|
|
1538
1587
|
lastFrameAtMs: sampleRef.current.lastFrameAtMs,
|
|
1539
|
-
nowMs
|
|
1540
|
-
stallAfterMs:
|
|
1588
|
+
nowMs,
|
|
1589
|
+
stallAfterMs: stallAfterMs2
|
|
1541
1590
|
});
|
|
1542
|
-
if (!frameFresh && sampleRef.current.seenFrame)
|
|
1591
|
+
if (!frameFresh && sampleRef.current.seenFrame) {
|
|
1592
|
+
if (flowingRef.current) escalation.recordStall(nowMs);
|
|
1593
|
+
recovery.stall();
|
|
1594
|
+
}
|
|
1543
1595
|
const nextFlowing = frameFresh && recovery.ready;
|
|
1544
1596
|
if (flowingRef.current !== nextFlowing) {
|
|
1545
1597
|
flowingRef.current = nextFlowing;
|
|
@@ -1553,11 +1605,14 @@ function useLiveFrameFlow(wrapRef, trackProducing, trackIdentity, stallAfterMs)
|
|
|
1553
1605
|
stopObserving();
|
|
1554
1606
|
cancelFrameCallback();
|
|
1555
1607
|
};
|
|
1556
|
-
}, [wrapRef, trackProducing, trackIdentity, boundedStallMs, recovery]);
|
|
1608
|
+
}, [wrapRef, trackProducing, trackIdentity, boundedStallMs, recovery, escalation]);
|
|
1557
1609
|
const freezeReading = useCallback(() => {
|
|
1558
1610
|
const sample = sampleRef.current;
|
|
1559
1611
|
const lastFrameAtMs = sample.lastFrameAtMs;
|
|
1560
1612
|
const hidden = typeof document !== "undefined" && document.visibilityState !== "visible";
|
|
1613
|
+
if (!hidden && !sample.resumePending && trackProducing && !sample.seenFrame && sample.producingSinceMs !== null) {
|
|
1614
|
+
return { freezeMsInWindow: firstFrameWaitFreezeMs(Date.now() - sample.producingSinceMs), inhibited: false };
|
|
1615
|
+
}
|
|
1561
1616
|
const inhibited = isFrameFreezeInhibited({
|
|
1562
1617
|
hidden,
|
|
1563
1618
|
resumePending: sample.resumePending,
|
|
@@ -3164,4 +3219,4 @@ function createProxyClient(options) {
|
|
|
3164
3219
|
};
|
|
3165
3220
|
}
|
|
3166
3221
|
|
|
3167
|
-
export { AdaptivePlayoutController, AvatarCall, AvatarVideoSurface, DEFAULT_APPROACHING_END_LEAD_SECONDS, DEFAULT_AVATAR_PLAYOUT_DELAY_SECONDS, DEFAULT_CREDITS_LOW_LEAD_SECONDS, DEFAULT_GOVERNOR_CONFIG, DEFAULT_GRACE_CEILING_SECONDS, DEFAULT_GRACE_WINDOW_LEAD_SECONDS, DEFAULT_IDLE_SECONDS, DEFAULT_IDLE_WARN_LEAD_SECONDS, DEFAULT_TURN_TIMEOUT_SECONDS, MAX_RECONNECT_ATTEMPTS, MAX_SESSION_INSTRUCTIONS_CHARS, MIC_LEASE_ENDED_TIMEOUT_MS, RECONNECT_BACKOFF_MS, RealtimeAvatarCapacityError, RealtimeAvatarLiveKitRoom, SessionLifecycleRoomBridge, capacityErrorFromBusy, capacityStateFromGrant, createProxyClient, knownBehaviorStates, mapTurnState, readInboundRtp, sessionBehaviorSchema, sessionClipSchema, shouldReplayPendingTurn, splitCallTranscript, useAvatarAdaptivePlayoutDelay, useAvatarCall, useAvatarPlayoutDelay, useAvatarQualityGovernor, useCallTranscript, useCharacterTools, useLiveKitAvatarGrant, useMicLease, useRealtimeSession, useReleaseMicLeaseOnTrackEnded, useSessionLifecycle };
|
|
3222
|
+
export { AdaptivePlayoutController, AvatarCall, AvatarVideoSurface, DEFAULT_APPROACHING_END_LEAD_SECONDS, DEFAULT_AVATAR_PLAYOUT_DELAY_SECONDS, DEFAULT_AVATAR_UNSTABLE_STALL_MS, DEFAULT_CREDITS_LOW_LEAD_SECONDS, DEFAULT_GOVERNOR_CONFIG, DEFAULT_GRACE_CEILING_SECONDS, DEFAULT_GRACE_WINDOW_LEAD_SECONDS, DEFAULT_IDLE_SECONDS, DEFAULT_IDLE_WARN_LEAD_SECONDS, DEFAULT_TURN_TIMEOUT_SECONDS, MAX_RECONNECT_ATTEMPTS, MAX_SESSION_INSTRUCTIONS_CHARS, MIC_LEASE_ENDED_TIMEOUT_MS, RECONNECT_BACKOFF_MS, RealtimeAvatarCapacityError, RealtimeAvatarLiveKitRoom, SessionLifecycleRoomBridge, capacityErrorFromBusy, capacityStateFromGrant, createProxyClient, knownBehaviorStates, mapTurnState, readInboundRtp, sessionBehaviorSchema, sessionClipSchema, shouldReplayPendingTurn, splitCallTranscript, useAvatarAdaptivePlayoutDelay, useAvatarCall, useAvatarPlayoutDelay, useAvatarQualityGovernor, useCallTranscript, useCharacterTools, useLiveKitAvatarGrant, useMicLease, useRealtimeSession, useReleaseMicLeaseOnTrackEnded, useSessionLifecycle };
|
package/dist/server.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export { RealtimeAvatar, RealtimeAvatarError, RealtimeAvatarHttpError, RealtimeAvatarOptions, StartCallOptions, clipLibraryDeclarationSchema, verifyTranscript } from './index.js';
|
|
2
|
-
export { h as Asset, g as AssetKind, A as Avatar, l as AvatarClip, c as AvatarSourceSwap, b as AvatarUpdate, m as CallConnection, C as CallMode, a as CallPolicy, n as CallQueued, o as ClipDeclaration, f as ClipLibrary, d as ClipLibraryDeclaration, p as ClipLibraryPlan, e as ClipLibraryUpdate, q as ClipSource, r as ContextMessage, k as CreditBalance, E as EndCallOptions, s as EndCallReason, i as ListSessionsOptions, L as LoopRedirect, S as StartCallResult, T as TranscriptPayload, j as UsageSession, U as UsageSessionPage, V as VideoPolicy, t as isQueued } from './types-
|
|
2
|
+
export { h as Asset, g as AssetKind, A as Avatar, l as AvatarClip, c as AvatarSourceSwap, b as AvatarUpdate, m as CallConnection, C as CallMode, a as CallPolicy, n as CallQueued, o as ClipDeclaration, f as ClipLibrary, d as ClipLibraryDeclaration, p as ClipLibraryPlan, e as ClipLibraryUpdate, q as ClipSource, r as ContextMessage, k as CreditBalance, E as EndCallOptions, s as EndCallReason, i as ListSessionsOptions, L as LoopRedirect, S as StartCallResult, T as TranscriptPayload, j as UsageSession, U as UsageSessionPage, V as VideoPolicy, t as isQueued } from './types-nxdohaiH.js';
|
|
3
3
|
import 'zod';
|
package/dist/server.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { RealtimeAvatar, RealtimeAvatarError, RealtimeAvatarHttpError, clipLibraryDeclarationSchema, isQueued, verifyTranscript } from './chunk-
|
|
1
|
+
export { RealtimeAvatar, RealtimeAvatarError, RealtimeAvatarHttpError, clipLibraryDeclarationSchema, isQueued, verifyTranscript } from './chunk-SKXUGNEK.js';
|
package/dist/tanstack-start.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { P as ProxyConfig } from './types-
|
|
2
|
-
import './types-
|
|
1
|
+
import { P as ProxyConfig } from './types-9a0bRdXl.js';
|
|
2
|
+
import './types-nxdohaiH.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* TanStack Start. Mount at `routes/api/realtime-avatar/$.ts` — the trailing `$` is Start's
|
package/dist/tanstack-start.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { C as CallMode, a as CallPolicy } from './types-
|
|
1
|
+
import { C as CallMode, a as CallPolicy } from './types-nxdohaiH.js';
|
|
2
2
|
|
|
3
3
|
/** The three things a caller can ask the proxy to do. Gate on these, not on URLs. */
|
|
4
4
|
type ProxyOperation = "connect" | "end" | "avatars" | "credits";
|
|
@@ -645,6 +645,11 @@ interface components {
|
|
|
645
645
|
documentation: string;
|
|
646
646
|
/** @description Set when the failure is worth retrying as-is. */
|
|
647
647
|
retryable?: boolean;
|
|
648
|
+
/**
|
|
649
|
+
* Format: uuid
|
|
650
|
+
* @description Server-generated correlation ID, also returned in X-Request-ID on correlated failures. Quote this when contacting support. Detailed diagnostics require separate operational access.
|
|
651
|
+
*/
|
|
652
|
+
requestId?: string;
|
|
648
653
|
/**
|
|
649
654
|
* @description Present on `403 insufficient_scope` — the one scope this operation needed and the key did not carry. Repeated in the `WWW-Authenticate` challenge as `scope=`.
|
|
650
655
|
* @enum {string}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "realtime-avatar",
|
|
3
|
-
"version": "0.11.
|
|
3
|
+
"version": "0.11.2",
|
|
4
4
|
"description": "Realtime Avatar SDK. `realtime-avatar` and the route adapters hold your API key and are server-only; `realtime-avatar/react`, `/browser` and `/tools` never can — importing a server entry into a browser build throws at bundle time.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "The Influence Company",
|