realtime-avatar 0.5.4 → 0.6.1
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-XZ5DRDND.js → chunk-2Q6BHD2C.js} +1 -1
- package/dist/{chunk-I3BFZHMQ.js → chunk-ZRJ6DJKX.js} +7 -2
- 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 +4 -3
- package/dist/index.js +1 -1
- package/dist/nextjs.d.ts +2 -2
- package/dist/nextjs.js +2 -2
- package/dist/{proxy-client-DylBmlgX.d.ts → proxy-client-BIadEcDj.d.ts} +14 -0
- package/dist/react-native.d.ts +2 -2
- package/dist/react-native.js +21 -1
- package/dist/react.d.ts +2 -2
- package/dist/react.js +21 -1
- 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-CHrhuhYb.d.ts → types-BvVsHgYE.d.ts} +1 -1
- package/dist/{types-BeGuvyra.d.ts → types-BvkgmmnO.d.ts} +45 -1
- package/package.json +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { RealtimeAvatar, isQueued, RealtimeAvatarHttpError } from './chunk-
|
|
1
|
+
import { RealtimeAvatar, isQueued, RealtimeAvatarHttpError } from './chunk-ZRJ6DJKX.js';
|
|
2
2
|
|
|
3
3
|
// ../proxy/src/config.ts
|
|
4
4
|
var json = (body, status = 200) => new Response(JSON.stringify(body), {
|
|
@@ -43,7 +43,7 @@ function isTransient(cause) {
|
|
|
43
43
|
|
|
44
44
|
// ../http-client/src/client.ts
|
|
45
45
|
var DEFAULT_BASE_URL = "https://realtimeavatar.ai/api/v1";
|
|
46
|
-
var SDK_VERSION = "0.
|
|
46
|
+
var SDK_VERSION = "0.6.1";
|
|
47
47
|
var RealtimeAvatar = class {
|
|
48
48
|
#apiKey;
|
|
49
49
|
#baseUrl;
|
|
@@ -301,7 +301,8 @@ var RealtimeAvatar = class {
|
|
|
301
301
|
* concurrent writer surfaces as a 409 instead of a lost update. Omit it to declare
|
|
302
302
|
* unconditionally.
|
|
303
303
|
*
|
|
304
|
-
* At most 12 clips:
|
|
304
|
+
* At most 12 clips: up to six `idle`, up to two `listen`, the rest `gesture`. Several
|
|
305
|
+
* idles are a resting ROTATION she drifts between, not alternatives to one. An uploaded
|
|
305
306
|
* clip (`source: { assetId }`) must start AND end on the avatar's rest pose — pose
|
|
306
307
|
* validation rejects it otherwise (`status: "failed"`, the verdict in `poseCheck`),
|
|
307
308
|
* and the rest of the library is untouched.
|
|
@@ -541,6 +542,10 @@ function toUsageSessionPage(raw) {
|
|
|
541
542
|
sessions: rows.filter(isRecord).map((row) => ({
|
|
542
543
|
sessionId: String(row.sessionId ?? ""),
|
|
543
544
|
avatarId: typeof row.avatarId === "string" ? row.avatarId : null,
|
|
545
|
+
// Added to the contract alongside avatarId so a usage row is readable without a
|
|
546
|
+
// second lookup. Defensive like its siblings: an older server that omits it
|
|
547
|
+
// yields null rather than the string "undefined".
|
|
548
|
+
avatarName: typeof row.avatarName === "string" ? row.avatarName : null,
|
|
544
549
|
status: usageStatus(row.status),
|
|
545
550
|
startedAt: typeof row.startedAt === "string" ? row.startedAt : null,
|
|
546
551
|
endedAt: typeof row.endedAt === "string" ? row.endedAt : null,
|
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 ClipDeclaration, e as ClipLibraryUpdate, L as LoopRedirect, f as ClipLibrary, g as ClipSyncResult, h as AssetKind, i as Asset, j as ListSessionsOptions, U as UsageSessionPage, k as UsageSession, l as CreditBalance, T as TranscriptPayload } from './types-
|
|
2
|
-
export { m as AvatarClip, n as CallConnection, o as CallQueued, p as ClipLibraryPlan, q as ClipSource, r as ContextMessage, s as EndCallReason, V as VideoPolicy, t as VideoState, u 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 ClipDeclaration, e as ClipLibraryUpdate, L as LoopRedirect, f as ClipLibrary, g as ClipSyncResult, h as AssetKind, i as Asset, j as ListSessionsOptions, U as UsageSessionPage, k as UsageSession, l as CreditBalance, T as TranscriptPayload } from './types-BvkgmmnO.js';
|
|
2
|
+
export { m as AvatarClip, n as CallConnection, o as CallQueued, p as ClipLibraryPlan, q as ClipSource, r as ContextMessage, s as EndCallReason, V as VideoPolicy, t as VideoState, u as isQueued } from './types-BvkgmmnO.js';
|
|
3
3
|
|
|
4
4
|
interface RealtimeAvatarOptions {
|
|
5
5
|
/** `tic_live_…` or `tic_test_…`. Server-side only — never ship this to a browser. */
|
|
@@ -182,7 +182,8 @@ declare class RealtimeAvatar {
|
|
|
182
182
|
* concurrent writer surfaces as a 409 instead of a lost update. Omit it to declare
|
|
183
183
|
* unconditionally.
|
|
184
184
|
*
|
|
185
|
-
* At most 12 clips:
|
|
185
|
+
* At most 12 clips: up to six `idle`, up to two `listen`, the rest `gesture`. Several
|
|
186
|
+
* idles are a resting ROTATION she drifts between, not alternatives to one. An uploaded
|
|
186
187
|
* clip (`source: { assetId }`) must start AND end on the avatar's rest pose — pose
|
|
187
188
|
* validation rejects it otherwise (`status: "failed"`, the verdict in `poseCheck`),
|
|
188
189
|
* and the rest of the library is untouched.
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { RealtimeAvatar, RealtimeAvatarError, RealtimeAvatarHttpError, isQueued, verifyTranscript } from './chunk-
|
|
1
|
+
export { RealtimeAvatar, RealtimeAvatarError, RealtimeAvatarHttpError, isQueued, verifyTranscript } from './chunk-ZRJ6DJKX.js';
|
package/dist/nextjs.d.ts
CHANGED
package/dist/nextjs.js
CHANGED
|
@@ -1167,6 +1167,20 @@ type UseSessionLifecycleInput<T extends LLMProvider = LLMProvider> = {
|
|
|
1167
1167
|
reconnectBackoffMs?: number[];
|
|
1168
1168
|
/** Auto-reconnect give-up bound. Default {@link MAX_RECONNECT_ATTEMPTS}. */
|
|
1169
1169
|
maxReconnectAttempts?: number;
|
|
1170
|
+
/**
|
|
1171
|
+
* How long a held grant may sit UNCONNECTED before we give the slot back
|
|
1172
|
+
* (seconds). Default {@link DEFAULT_CONNECT_WATCHDOG_SECONDS}.
|
|
1173
|
+
*
|
|
1174
|
+
* A grant that never reaches a live room is invisible to every other timer here:
|
|
1175
|
+
* the idle clock only runs once connected, and LiveKit reports no disconnect for
|
|
1176
|
+
* a room that was never joined. Without this the slot is held until the PLATFORM's
|
|
1177
|
+
* join timeout (75s at time of writing) — and on a plan whose ceiling is 1, that is
|
|
1178
|
+
* the caller's only slot, so their retry is refused by a call they never saw.
|
|
1179
|
+
* Measured in prod: 8 of 12 never-connected sessions held for 76-81s.
|
|
1180
|
+
*
|
|
1181
|
+
* Set 0 to disable (the platform timeout remains the backstop).
|
|
1182
|
+
*/
|
|
1183
|
+
connectWatchdogSeconds?: number;
|
|
1170
1184
|
/** Forwarded to {@link useLiveKitAvatarGrant}. Defaults true (queue auto-retry). */
|
|
1171
1185
|
autoRetryBusy?: boolean;
|
|
1172
1186
|
requestOptions?: UseLiveKitAvatarGrantInput<T>["requestOptions"];
|
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_AVATAR_PLAYOUT_DELAY_SECONDS, n as DEFAULT_CREDITS_LOW_LEAD_SECONDS, o as DEFAULT_GOVERNOR_CONFIG, p as DEFAULT_GRACE_CEILING_SECONDS, q as DEFAULT_GRACE_WINDOW_LEAD_SECONDS, r as DEFAULT_IDLE_SECONDS, s as DEFAULT_IDLE_WARN_LEAD_SECONDS, t as DEFAULT_TURN_TIMEOUT_SECONDS, E as EndReason, u as EndedEvent, v as ExtendResult, F as FishTtsModel, w as FreezeReadingFn, G as Governor, x as GovernorAction, y as GovernorConfig, z as GovernorSignal, H as GovernorState, I as GraceWindowClosedEvent, J as GraceWindowOpenEvent, K as GraceWindowState, M as IdleWarningEvent, N as InboundRtpCursor, O as InboundRtpReading, P as KnownBehaviorState, Q as LLMProvider, R as LLMSelection, S as LiveKitAvatarGrantState, T as LiveKitAvatarGrantStatus, U as LiveKitCapacityState, V as LiveKitConnectionStatus, W as LiveKitSessionRequest, X as LiveKitSessionStartResult, Y as MAX_RECONNECT_ATTEMPTS, Z as MAX_SESSION_INSTRUCTIONS_CHARS, _ as ProxyClientOptions, $ as QualityCap, a0 as RECONNECT_BACKOFF_MS, a1 as RealtimeAvatarRequestOptions, a2 as RealtimeSessionApi, a3 as RealtimeSessionMedia, a4 as RealtimeSessionRoomSinks, a5 as ReconnectPolicy, a6 as ReconnectingEvent, a7 as RecoveryState, a8 as RetryStep, a9 as SessionBehavior, aa as SessionClip, ab as SessionClocks, ac as SessionEndReason, ad as SessionLifecycleApi, ae as SessionLifecyclePhase, af as SessionLifecyclePhaseKind, ag as SessionLifecycleRoomBridge, ah as SessionLifecycleRoomBridgeProps, ai as SurfaceLayers, aj as TurnState, ak as TurnTimeoutEvent, al as UseAvatarQualityGovernorInput, am as UseLiveKitAvatarGrantInput, an as UseRealtimeSessionInput, ao as UseSessionLifecycleInput, ap as VoiceSpec, aq as VoiceSpecInput, ar as capacityErrorFromBusy, as as capacityStateFromGrant, at as createProxyClient, au as isNativeLiveTrackSubscribed, av as knownBehaviorStates, aw as mapTurnState, ax as readInboundRtp, ay as sessionBehaviorSchema, az as sessionClipSchema, aA as splitCallTranscript, aB as useAvatarAdaptivePlayoutDelay, aC as useAvatarPlayoutDelay, aD as useAvatarQualityGovernor, aE as useCallTranscript, aF as useLiveKitAvatarGrant, aG as useLiveTrackProducing, aH as useMicLease, aI as useRealtimeSession, aJ as useReleaseMicLeaseOnTrackEnded, aK as useSessionLifecycle } from './proxy-client-
|
|
4
|
+
import { L as LiveKitSessionGrant, A as AvatarVideoFit } from './proxy-client-BIadEcDj.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_AVATAR_PLAYOUT_DELAY_SECONDS, n as DEFAULT_CREDITS_LOW_LEAD_SECONDS, o as DEFAULT_GOVERNOR_CONFIG, p as DEFAULT_GRACE_CEILING_SECONDS, q as DEFAULT_GRACE_WINDOW_LEAD_SECONDS, r as DEFAULT_IDLE_SECONDS, s as DEFAULT_IDLE_WARN_LEAD_SECONDS, t as DEFAULT_TURN_TIMEOUT_SECONDS, E as EndReason, u as EndedEvent, v as ExtendResult, F as FishTtsModel, w as FreezeReadingFn, G as Governor, x as GovernorAction, y as GovernorConfig, z as GovernorSignal, H as GovernorState, I as GraceWindowClosedEvent, J as GraceWindowOpenEvent, K as GraceWindowState, M as IdleWarningEvent, N as InboundRtpCursor, O as InboundRtpReading, P as KnownBehaviorState, Q as LLMProvider, R as LLMSelection, S as LiveKitAvatarGrantState, T as LiveKitAvatarGrantStatus, U as LiveKitCapacityState, V as LiveKitConnectionStatus, W as LiveKitSessionRequest, X as LiveKitSessionStartResult, Y as MAX_RECONNECT_ATTEMPTS, Z as MAX_SESSION_INSTRUCTIONS_CHARS, _ as ProxyClientOptions, $ as QualityCap, a0 as RECONNECT_BACKOFF_MS, a1 as RealtimeAvatarRequestOptions, a2 as RealtimeSessionApi, a3 as RealtimeSessionMedia, a4 as RealtimeSessionRoomSinks, a5 as ReconnectPolicy, a6 as ReconnectingEvent, a7 as RecoveryState, a8 as RetryStep, a9 as SessionBehavior, aa as SessionClip, ab as SessionClocks, ac as SessionEndReason, ad as SessionLifecycleApi, ae as SessionLifecyclePhase, af as SessionLifecyclePhaseKind, ag as SessionLifecycleRoomBridge, ah as SessionLifecycleRoomBridgeProps, ai as SurfaceLayers, aj as TurnState, ak as TurnTimeoutEvent, al as UseAvatarQualityGovernorInput, am as UseLiveKitAvatarGrantInput, an as UseRealtimeSessionInput, ao as UseSessionLifecycleInput, ap as VoiceSpec, aq as VoiceSpecInput, ar as capacityErrorFromBusy, as as capacityStateFromGrant, at as createProxyClient, au as isNativeLiveTrackSubscribed, av as knownBehaviorStates, aw as mapTurnState, ax as readInboundRtp, ay as sessionBehaviorSchema, az as sessionClipSchema, aA as splitCallTranscript, aB as useAvatarAdaptivePlayoutDelay, aC as useAvatarPlayoutDelay, aD as useAvatarQualityGovernor, aE as useCallTranscript, aF as useLiveKitAvatarGrant, aG as useLiveTrackProducing, aH as useMicLease, aI as useRealtimeSession, aJ as useReleaseMicLeaseOnTrackEnded, aK as useSessionLifecycle } from './proxy-client-BIadEcDj.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 { DisconnectReason, RemoteAudioTrack, RemoteTrack, RemoteVideoTrack, Room, RoomEvent, SendTextOptions, Track } from 'livekit-client';
|
package/dist/react-native.js
CHANGED
|
@@ -358,7 +358,12 @@ function useLiveKitAvatarGrant(input) {
|
|
|
358
358
|
setState({ status: "requesting", grant: null, busy: null, error: null });
|
|
359
359
|
}
|
|
360
360
|
void client.createLiveKitSessionOrBusy(request, requestOptions).then((result) => {
|
|
361
|
-
if (cancelled)
|
|
361
|
+
if (cancelled) {
|
|
362
|
+
if (result.status !== "busy") {
|
|
363
|
+
void client.releaseLiveKitSession(result.grant.session_id, "superseded");
|
|
364
|
+
}
|
|
365
|
+
return;
|
|
366
|
+
}
|
|
362
367
|
if (result.status === "busy") {
|
|
363
368
|
queueTicketRef.current = result.busy.queue_ticket_id ?? queueTicketRef.current;
|
|
364
369
|
setState({ status: "busy", grant: null, busy: result.busy, error: null });
|
|
@@ -1494,6 +1499,7 @@ function resolveIdleTimeoutMs(args) {
|
|
|
1494
1499
|
if (grantIdleSeconds > 0) return grantIdleSeconds * 1e3;
|
|
1495
1500
|
return DEFAULT_IDLE_SECONDS * 1e3;
|
|
1496
1501
|
}
|
|
1502
|
+
var DEFAULT_CONNECT_WATCHDOG_SECONDS = 12;
|
|
1497
1503
|
function resolveWarnBeforeMs(idleTimeoutMs, override, idleWarnLeadSeconds) {
|
|
1498
1504
|
if (idleTimeoutMs <= 0) return 0;
|
|
1499
1505
|
const maxLeadMs = Math.max(0, idleTimeoutMs - 1e3);
|
|
@@ -1518,6 +1524,7 @@ function useSessionLifecycle(input) {
|
|
|
1518
1524
|
reconnectBackoffMs,
|
|
1519
1525
|
maxReconnectAttempts,
|
|
1520
1526
|
autoRetryBusy = true,
|
|
1527
|
+
connectWatchdogSeconds,
|
|
1521
1528
|
requestOptions,
|
|
1522
1529
|
onBehaviorChange
|
|
1523
1530
|
} = input;
|
|
@@ -1527,6 +1534,7 @@ function useSessionLifecycle(input) {
|
|
|
1527
1534
|
);
|
|
1528
1535
|
const reconnectPolicyRef = useRef(reconnectPolicy);
|
|
1529
1536
|
reconnectPolicyRef.current = reconnectPolicy;
|
|
1537
|
+
const connectWatchdogMs = typeof connectWatchdogSeconds === "number" && Number.isFinite(connectWatchdogSeconds) ? Math.max(0, Math.floor(connectWatchdogSeconds)) * 1e3 : DEFAULT_CONNECT_WATCHDOG_SECONDS * 1e3;
|
|
1530
1538
|
const grantState = useLiveKitAvatarGrant({
|
|
1531
1539
|
client,
|
|
1532
1540
|
session,
|
|
@@ -1685,6 +1693,16 @@ function useSessionLifecycle(input) {
|
|
|
1685
1693
|
},
|
|
1686
1694
|
[active, onConnected]
|
|
1687
1695
|
);
|
|
1696
|
+
useEffect(() => {
|
|
1697
|
+
if (!active || connected || connectWatchdogMs <= 0) return;
|
|
1698
|
+
if (grantState.status !== "ready" || !grantState.grant) return;
|
|
1699
|
+
if (recovery.kind === "failed" || recovery.kind === "ended") return;
|
|
1700
|
+
const timer = window.setTimeout(() => {
|
|
1701
|
+
releaseRef.current("disconnected");
|
|
1702
|
+
setRecovery({ kind: "reconnecting", attempt: attemptRef.current });
|
|
1703
|
+
}, connectWatchdogMs);
|
|
1704
|
+
return () => window.clearTimeout(timer);
|
|
1705
|
+
}, [active, connected, connectWatchdogMs, grantState.status, grantState.grant, recovery.kind]);
|
|
1688
1706
|
useEffect(() => {
|
|
1689
1707
|
if (!active || !needsFreshGrant(recovery)) return;
|
|
1690
1708
|
const step2 = retryStep(attemptRef.current, reconnectPolicyRef.current);
|
|
@@ -1700,6 +1718,7 @@ function useSessionLifecycle(input) {
|
|
|
1700
1718
|
attemptRef.current = step2.attempt;
|
|
1701
1719
|
setAttempt(step2.attempt);
|
|
1702
1720
|
refreshBaselineCapacityRef.current = capacityRef.current;
|
|
1721
|
+
releaseRef.current("superseded");
|
|
1703
1722
|
setRecovery({ kind: "refreshing", attempt: step2.attempt });
|
|
1704
1723
|
refreshRef.current();
|
|
1705
1724
|
}, step2.delayMs);
|
|
@@ -1712,6 +1731,7 @@ function useSessionLifecycle(input) {
|
|
|
1712
1731
|
attemptRef.current = 0;
|
|
1713
1732
|
setAttempt(0);
|
|
1714
1733
|
refreshBaselineCapacityRef.current = capacityRef.current;
|
|
1734
|
+
releaseRef.current("superseded");
|
|
1715
1735
|
setRecovery({ kind: "refreshing", attempt: 0 });
|
|
1716
1736
|
refreshRef.current();
|
|
1717
1737
|
}, [active, clearTimer, recovery.kind]);
|
package/dist/react.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ReactNode } from 'react';
|
|
2
|
-
import { g as AvatarSessionClient, A as AvatarVideoFit } from './proxy-client-
|
|
3
|
-
export { a as AdaptivePlayoutController, b as AdaptivePlayoutDecision, c as AdaptivePlayoutOptions, d as AdaptivePlayoutSample, e as ApproachingEndEvent, f as ApproachingEndReason, aL as AvatarVideoSurface, aM 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_AVATAR_PLAYOUT_DELAY_SECONDS, n as DEFAULT_CREDITS_LOW_LEAD_SECONDS, o as DEFAULT_GOVERNOR_CONFIG, p as DEFAULT_GRACE_CEILING_SECONDS, q as DEFAULT_GRACE_WINDOW_LEAD_SECONDS, r as DEFAULT_IDLE_SECONDS, s as DEFAULT_IDLE_WARN_LEAD_SECONDS, t as DEFAULT_TURN_TIMEOUT_SECONDS, E as EndReason, u as EndedEvent, v as ExtendResult, F as FishTtsModel, w as FreezeReadingFn, G as Governor, x as GovernorAction, y as GovernorConfig, z as GovernorSignal, H as GovernorState, I as GraceWindowClosedEvent, J as GraceWindowOpenEvent, K as GraceWindowState, M as IdleWarningEvent, N as InboundRtpCursor, O as InboundRtpReading, P as KnownBehaviorState, Q as LLMProvider, R as LLMSelection, S as LiveKitAvatarGrantState, T as LiveKitAvatarGrantStatus, U as LiveKitCapacityState, V as LiveKitConnectionStatus, W as LiveKitSessionRequest, X as LiveKitSessionStartResult, aN as LivePlaybackKeeper, Y as MAX_RECONNECT_ATTEMPTS, Z as MAX_SESSION_INSTRUCTIONS_CHARS, aO as MIC_LEASE_ENDED_TIMEOUT_MS, aP as MicLease, aQ as PlayableVideoElement, _ as ProxyClientOptions, $ as QualityCap, a0 as RECONNECT_BACKOFF_MS, aR as RealtimeAvatarCapacityError, aS as RealtimeAvatarLiveKitRoom, aT as RealtimeAvatarLiveKitRoomProps, a1 as RealtimeAvatarRequestOptions, a2 as RealtimeSessionApi, a3 as RealtimeSessionMedia, a4 as RealtimeSessionRoomSinks, a5 as ReconnectPolicy, a6 as ReconnectingEvent, a7 as RecoveryState, a8 as RetryStep, a9 as SessionBehavior, aa as SessionClip, ab as SessionClocks, ac as SessionEndReason, ad as SessionLifecycleApi, ae as SessionLifecyclePhase, af as SessionLifecyclePhaseKind, ag as SessionLifecycleRoomBridge, ah as SessionLifecycleRoomBridgeProps, ai as SurfaceLayers, aj as TurnState, ak as TurnTimeoutEvent, al as UseAvatarQualityGovernorInput, am as UseLiveKitAvatarGrantInput, an as UseRealtimeSessionInput, ao as UseSessionLifecycleInput, ap as VoiceSpec, aq as VoiceSpecInput, ar as capacityErrorFromBusy, as as capacityStateFromGrant, at as createProxyClient, av as knownBehaviorStates, aw as mapTurnState, ax as readInboundRtp, ay as sessionBehaviorSchema, az as sessionClipSchema, aU as shouldReplayPendingTurn, aA as splitCallTranscript, aB as useAvatarAdaptivePlayoutDelay, aC as useAvatarPlayoutDelay, aD as useAvatarQualityGovernor, aE as useCallTranscript, aF as useLiveKitAvatarGrant, aH as useMicLease, aI as useRealtimeSession, aJ as useReleaseMicLeaseOnTrackEnded, aK as useSessionLifecycle } from './proxy-client-
|
|
2
|
+
import { g as AvatarSessionClient, A as AvatarVideoFit } from './proxy-client-BIadEcDj.js';
|
|
3
|
+
export { a as AdaptivePlayoutController, b as AdaptivePlayoutDecision, c as AdaptivePlayoutOptions, d as AdaptivePlayoutSample, e as ApproachingEndEvent, f as ApproachingEndReason, aL as AvatarVideoSurface, aM 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_AVATAR_PLAYOUT_DELAY_SECONDS, n as DEFAULT_CREDITS_LOW_LEAD_SECONDS, o as DEFAULT_GOVERNOR_CONFIG, p as DEFAULT_GRACE_CEILING_SECONDS, q as DEFAULT_GRACE_WINDOW_LEAD_SECONDS, r as DEFAULT_IDLE_SECONDS, s as DEFAULT_IDLE_WARN_LEAD_SECONDS, t as DEFAULT_TURN_TIMEOUT_SECONDS, E as EndReason, u as EndedEvent, v as ExtendResult, F as FishTtsModel, w as FreezeReadingFn, G as Governor, x as GovernorAction, y as GovernorConfig, z as GovernorSignal, H as GovernorState, I as GraceWindowClosedEvent, J as GraceWindowOpenEvent, K as GraceWindowState, M as IdleWarningEvent, N as InboundRtpCursor, O as InboundRtpReading, P as KnownBehaviorState, Q as LLMProvider, R as LLMSelection, S as LiveKitAvatarGrantState, T as LiveKitAvatarGrantStatus, U as LiveKitCapacityState, V as LiveKitConnectionStatus, W as LiveKitSessionRequest, X as LiveKitSessionStartResult, aN as LivePlaybackKeeper, Y as MAX_RECONNECT_ATTEMPTS, Z as MAX_SESSION_INSTRUCTIONS_CHARS, aO as MIC_LEASE_ENDED_TIMEOUT_MS, aP as MicLease, aQ as PlayableVideoElement, _ as ProxyClientOptions, $ as QualityCap, a0 as RECONNECT_BACKOFF_MS, aR as RealtimeAvatarCapacityError, aS as RealtimeAvatarLiveKitRoom, aT as RealtimeAvatarLiveKitRoomProps, a1 as RealtimeAvatarRequestOptions, a2 as RealtimeSessionApi, a3 as RealtimeSessionMedia, a4 as RealtimeSessionRoomSinks, a5 as ReconnectPolicy, a6 as ReconnectingEvent, a7 as RecoveryState, a8 as RetryStep, a9 as SessionBehavior, aa as SessionClip, ab as SessionClocks, ac as SessionEndReason, ad as SessionLifecycleApi, ae as SessionLifecyclePhase, af as SessionLifecyclePhaseKind, ag as SessionLifecycleRoomBridge, ah as SessionLifecycleRoomBridgeProps, ai as SurfaceLayers, aj as TurnState, ak as TurnTimeoutEvent, al as UseAvatarQualityGovernorInput, am as UseLiveKitAvatarGrantInput, an as UseRealtimeSessionInput, ao as UseSessionLifecycleInput, ap as VoiceSpec, aq as VoiceSpecInput, ar as capacityErrorFromBusy, as as capacityStateFromGrant, at as createProxyClient, av as knownBehaviorStates, aw as mapTurnState, ax as readInboundRtp, ay as sessionBehaviorSchema, az as sessionClipSchema, aU as shouldReplayPendingTurn, aA as splitCallTranscript, aB as useAvatarAdaptivePlayoutDelay, aC as useAvatarPlayoutDelay, aD as useAvatarQualityGovernor, aE as useCallTranscript, aF as useLiveKitAvatarGrant, aH as useMicLease, aI as useRealtimeSession, aJ as useReleaseMicLeaseOnTrackEnded, aK as useSessionLifecycle } from './proxy-client-BIadEcDj.js';
|
|
4
4
|
import '@livekit/components-react';
|
|
5
5
|
import 'livekit-client';
|
|
6
6
|
import 'zod';
|
package/dist/react.js
CHANGED
|
@@ -317,7 +317,12 @@ function useLiveKitAvatarGrant(input) {
|
|
|
317
317
|
setState({ status: "requesting", grant: null, busy: null, error: null });
|
|
318
318
|
}
|
|
319
319
|
void client.createLiveKitSessionOrBusy(request, requestOptions).then((result) => {
|
|
320
|
-
if (cancelled)
|
|
320
|
+
if (cancelled) {
|
|
321
|
+
if (result.status !== "busy") {
|
|
322
|
+
void client.releaseLiveKitSession(result.grant.session_id, "superseded");
|
|
323
|
+
}
|
|
324
|
+
return;
|
|
325
|
+
}
|
|
321
326
|
if (result.status === "busy") {
|
|
322
327
|
queueTicketRef.current = result.busy.queue_ticket_id ?? queueTicketRef.current;
|
|
323
328
|
setState({ status: "busy", grant: null, busy: result.busy, error: null });
|
|
@@ -1717,6 +1722,7 @@ function resolveIdleTimeoutMs(args) {
|
|
|
1717
1722
|
if (grantIdleSeconds > 0) return grantIdleSeconds * 1e3;
|
|
1718
1723
|
return DEFAULT_IDLE_SECONDS * 1e3;
|
|
1719
1724
|
}
|
|
1725
|
+
var DEFAULT_CONNECT_WATCHDOG_SECONDS = 12;
|
|
1720
1726
|
function resolveWarnBeforeMs(idleTimeoutMs, override, idleWarnLeadSeconds) {
|
|
1721
1727
|
if (idleTimeoutMs <= 0) return 0;
|
|
1722
1728
|
const maxLeadMs = Math.max(0, idleTimeoutMs - 1e3);
|
|
@@ -1741,6 +1747,7 @@ function useSessionLifecycle(input) {
|
|
|
1741
1747
|
reconnectBackoffMs,
|
|
1742
1748
|
maxReconnectAttempts,
|
|
1743
1749
|
autoRetryBusy = true,
|
|
1750
|
+
connectWatchdogSeconds,
|
|
1744
1751
|
requestOptions,
|
|
1745
1752
|
onBehaviorChange
|
|
1746
1753
|
} = input;
|
|
@@ -1750,6 +1757,7 @@ function useSessionLifecycle(input) {
|
|
|
1750
1757
|
);
|
|
1751
1758
|
const reconnectPolicyRef = useRef(reconnectPolicy);
|
|
1752
1759
|
reconnectPolicyRef.current = reconnectPolicy;
|
|
1760
|
+
const connectWatchdogMs = typeof connectWatchdogSeconds === "number" && Number.isFinite(connectWatchdogSeconds) ? Math.max(0, Math.floor(connectWatchdogSeconds)) * 1e3 : DEFAULT_CONNECT_WATCHDOG_SECONDS * 1e3;
|
|
1753
1761
|
const grantState = useLiveKitAvatarGrant({
|
|
1754
1762
|
client,
|
|
1755
1763
|
session,
|
|
@@ -1908,6 +1916,16 @@ function useSessionLifecycle(input) {
|
|
|
1908
1916
|
},
|
|
1909
1917
|
[active, onConnected]
|
|
1910
1918
|
);
|
|
1919
|
+
useEffect(() => {
|
|
1920
|
+
if (!active || connected || connectWatchdogMs <= 0) return;
|
|
1921
|
+
if (grantState.status !== "ready" || !grantState.grant) return;
|
|
1922
|
+
if (recovery.kind === "failed" || recovery.kind === "ended") return;
|
|
1923
|
+
const timer = window.setTimeout(() => {
|
|
1924
|
+
releaseRef.current("disconnected");
|
|
1925
|
+
setRecovery({ kind: "reconnecting", attempt: attemptRef.current });
|
|
1926
|
+
}, connectWatchdogMs);
|
|
1927
|
+
return () => window.clearTimeout(timer);
|
|
1928
|
+
}, [active, connected, connectWatchdogMs, grantState.status, grantState.grant, recovery.kind]);
|
|
1911
1929
|
useEffect(() => {
|
|
1912
1930
|
if (!active || !needsFreshGrant(recovery)) return;
|
|
1913
1931
|
const step2 = retryStep(attemptRef.current, reconnectPolicyRef.current);
|
|
@@ -1923,6 +1941,7 @@ function useSessionLifecycle(input) {
|
|
|
1923
1941
|
attemptRef.current = step2.attempt;
|
|
1924
1942
|
setAttempt(step2.attempt);
|
|
1925
1943
|
refreshBaselineCapacityRef.current = capacityRef.current;
|
|
1944
|
+
releaseRef.current("superseded");
|
|
1926
1945
|
setRecovery({ kind: "refreshing", attempt: step2.attempt });
|
|
1927
1946
|
refreshRef.current();
|
|
1928
1947
|
}, step2.delayMs);
|
|
@@ -1935,6 +1954,7 @@ function useSessionLifecycle(input) {
|
|
|
1935
1954
|
attemptRef.current = 0;
|
|
1936
1955
|
setAttempt(0);
|
|
1937
1956
|
refreshBaselineCapacityRef.current = capacityRef.current;
|
|
1957
|
+
releaseRef.current("superseded");
|
|
1938
1958
|
setRecovery({ kind: "refreshing", attempt: 0 });
|
|
1939
1959
|
refreshRef.current();
|
|
1940
1960
|
}, [active, clearTimer, recovery.kind]);
|
package/dist/server.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export { RealtimeAvatar, RealtimeAvatarError, RealtimeAvatarHttpError, RealtimeAvatarOptions, StartCallOptions, verifyTranscript } from './index.js';
|
|
2
|
-
export { i as Asset, h as AssetKind, A as Avatar, m as AvatarClip, c as AvatarSourceSwap, b as AvatarUpdate, n as CallConnection, C as CallMode, a as CallPolicy, o as CallQueued, d as ClipDeclaration, f as ClipLibrary, p as ClipLibraryPlan, e as ClipLibraryUpdate, q as ClipSource, g as ClipSyncResult, r as ContextMessage, l as CreditBalance, E as EndCallOptions, s as EndCallReason, j as ListSessionsOptions, L as LoopRedirect, S as StartCallResult, T as TranscriptPayload, k as UsageSession, U as UsageSessionPage, V as VideoPolicy, t as VideoState, u as isQueued } from './types-
|
|
2
|
+
export { i as Asset, h as AssetKind, A as Avatar, m as AvatarClip, c as AvatarSourceSwap, b as AvatarUpdate, n as CallConnection, C as CallMode, a as CallPolicy, o as CallQueued, d as ClipDeclaration, f as ClipLibrary, p as ClipLibraryPlan, e as ClipLibraryUpdate, q as ClipSource, g as ClipSyncResult, r as ContextMessage, l as CreditBalance, E as EndCallOptions, s as EndCallReason, j as ListSessionsOptions, L as LoopRedirect, S as StartCallResult, T as TranscriptPayload, k as UsageSession, U as UsageSessionPage, V as VideoPolicy, t as VideoState, u as isQueued } from './types-BvkgmmnO.js';
|
package/dist/server.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { RealtimeAvatar, RealtimeAvatarError, RealtimeAvatarHttpError, isQueued, verifyTranscript } from './chunk-
|
|
1
|
+
export { RealtimeAvatar, RealtimeAvatarError, RealtimeAvatarHttpError, isQueued, verifyTranscript } from './chunk-ZRJ6DJKX.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-BvVsHgYE.js';
|
|
2
|
+
import './types-BvkgmmnO.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-BvkgmmnO.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";
|
|
@@ -144,7 +144,9 @@ interface components {
|
|
|
144
144
|
client_metadata?: {
|
|
145
145
|
[key: string]: string;
|
|
146
146
|
};
|
|
147
|
+
/** @description DEPRECATED, no-op. Accepted and ignored. The faster hesitation ceiling this requested is now the default for every session, so sending it changes nothing. Safe to stop sending; the field is retained only so existing callers do not break. */
|
|
147
148
|
fast_endpointing?: boolean;
|
|
149
|
+
require_ready_clip_library?: boolean;
|
|
148
150
|
};
|
|
149
151
|
LiveKitSessionGrant: {
|
|
150
152
|
/**
|
|
@@ -268,7 +270,7 @@ interface components {
|
|
|
268
270
|
emotion?: string | null;
|
|
269
271
|
language?: string | null;
|
|
270
272
|
};
|
|
271
|
-
};
|
|
273
|
+
} | unknown | unknown;
|
|
272
274
|
llm?: {
|
|
273
275
|
/** @enum {string} */
|
|
274
276
|
provider: "local" | "gemini" | "openai";
|
|
@@ -392,6 +394,7 @@ interface components {
|
|
|
392
394
|
data: {
|
|
393
395
|
sessionId: string;
|
|
394
396
|
avatarId: string | null;
|
|
397
|
+
avatarName: string | null;
|
|
395
398
|
/** @enum {string} */
|
|
396
399
|
status: "reserved" | "started" | "released" | "failed";
|
|
397
400
|
startedAt: string | null;
|
|
@@ -410,6 +413,31 @@ interface components {
|
|
|
410
413
|
/** Format: date-time */
|
|
411
414
|
to: string;
|
|
412
415
|
};
|
|
416
|
+
ListAvatarsResponse: {
|
|
417
|
+
data: {
|
|
418
|
+
id: string;
|
|
419
|
+
tenantId: string;
|
|
420
|
+
displayName: string;
|
|
421
|
+
/** @enum {string} */
|
|
422
|
+
sourceKind: "image" | "video";
|
|
423
|
+
/** @enum {string} */
|
|
424
|
+
modelId: "realtime-avatar-live-v1" | "realtime-avatar-video-v1";
|
|
425
|
+
sourceAssetId: string | null;
|
|
426
|
+
/** @enum {string} */
|
|
427
|
+
status: "draft" | "preprocessing" | "ready" | "failed" | "disabled" | "deleted";
|
|
428
|
+
error: string | null;
|
|
429
|
+
/** @enum {string} */
|
|
430
|
+
idleVideoStatus: "none" | "queued" | "generating" | "ready" | "failed";
|
|
431
|
+
defaultVoiceId: string | null;
|
|
432
|
+
llm: {
|
|
433
|
+
/** @enum {string} */
|
|
434
|
+
provider: "local" | "gemini" | "openai";
|
|
435
|
+
model?: string | null;
|
|
436
|
+
} | null;
|
|
437
|
+
createdAt: string;
|
|
438
|
+
updatedAt: string;
|
|
439
|
+
}[];
|
|
440
|
+
};
|
|
413
441
|
ListAvatarClipsResponse: {
|
|
414
442
|
data: {
|
|
415
443
|
clipId: string;
|
|
@@ -421,6 +449,7 @@ interface components {
|
|
|
421
449
|
whenHint: string | null;
|
|
422
450
|
/** @enum {string} */
|
|
423
451
|
source: "generated" | "uploaded";
|
|
452
|
+
uploadAssetId: string | null;
|
|
424
453
|
motionPrompt: string | null;
|
|
425
454
|
durationSeconds: number | null;
|
|
426
455
|
anchorVersion: number;
|
|
@@ -484,6 +513,7 @@ interface components {
|
|
|
484
513
|
whenHint: string | null;
|
|
485
514
|
/** @enum {string} */
|
|
486
515
|
source: "generated" | "uploaded";
|
|
516
|
+
uploadAssetId: string | null;
|
|
487
517
|
motionPrompt: string | null;
|
|
488
518
|
durationSeconds: number | null;
|
|
489
519
|
anchorVersion: number;
|
|
@@ -546,6 +576,20 @@ interface components {
|
|
|
546
576
|
OkResponse: {
|
|
547
577
|
ok: boolean;
|
|
548
578
|
};
|
|
579
|
+
Error: {
|
|
580
|
+
/** @description Human-readable message. Not a stable contract — switch on `code` or `status`. */
|
|
581
|
+
error: string;
|
|
582
|
+
/** @description Repeats the HTTP status in the body. Absent on unhandled 500s. */
|
|
583
|
+
status?: number;
|
|
584
|
+
/** @description Machine-readable discriminator, present where the failure has one — billing, clip-library and loop refusals all carry it. Switch on this rather than on `error`, whose wording is not a contract. The set is open and grows with the API; the codes a given endpoint can return are documented with that endpoint at https://realtimeavatar.ai/docs/api-reference. */
|
|
585
|
+
code?: string;
|
|
586
|
+
/** @description Set when the failure is worth retrying as-is. */
|
|
587
|
+
retryable?: boolean;
|
|
588
|
+
/** @description Present on 402 — where to send the user to top up. */
|
|
589
|
+
billingUrl?: string;
|
|
590
|
+
} & {
|
|
591
|
+
[key: string]: unknown;
|
|
592
|
+
};
|
|
549
593
|
};
|
|
550
594
|
responses: never;
|
|
551
595
|
parameters: never;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "realtime-avatar",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.1",
|
|
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",
|