realtime-avatar 0.26.0 → 0.27.0

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/README.md CHANGED
@@ -222,7 +222,7 @@ all), and the `video` policy types are deliberately not one-to-one with the wire
222
222
 
223
223
  ```ts
224
224
  // calls
225
- rta.startCall({ avatarId, mode?, instructions?, context?, maxSeconds?, video?, recording?, connectionHistory?, transcript?, metadata? })
225
+ rta.startCall({ avatarId, mode?, instructions?, context?, maxSeconds?, video?, recording?, connectionHistory?, transcript?, metadata?, llm? })
226
226
  rta.endCall(sessionId, { reason? }) // free an abandoned call's slot; idempotent, never throws
227
227
  rta.leaveQueue(queueTicketId, { reason? }) // give up a queued call's place in line; idempotent, never throws
228
228
 
@@ -322,6 +322,9 @@ connects), a mute made then is kept when the call goes live, and after `end()` t
322
322
  once the call ended). While it is `blocked`, `AvatarCall` shows a "Tap to turn on sound" button,
323
323
  top-centre in a polite live region, that calls `call.startAudio()`. Pass `audioUnlockPrompt` a
324
324
  function to render your own (your words, your placement), or `false` for nothing.
325
+ The small "live" badge over the video is on by default; pass `showLiveBadge={false}` when your own
326
+ UI already shows the call's status. `AvatarVideoSurface` takes the same prop, plus `debug` to show
327
+ the live layer's resolution on the badge while you develop.
325
328
  `startAudio()` must run inside a click or tap handler; it never rejects and resolves whether
326
329
  playback is allowed afterwards.
327
330
 
@@ -665,7 +665,7 @@ var liveKitSessionReleaseReasonSchema = z.enum([
665
665
 
666
666
  // ../http-client/src/client.ts
667
667
  var DEFAULT_BASE_URL = "https://realtimeavatar.ai/api/v1";
668
- var SDK_VERSION = "0.26.0";
668
+ var SDK_VERSION = "0.27.0";
669
669
  var RealtimeAvatar = class {
670
670
  #apiKey;
671
671
  #baseUrl;
@@ -717,6 +717,11 @@ var RealtimeAvatar = class {
717
717
  if (options.recording !== void 0) body.recording = recordingModeSchema.parse(options.recording);
718
718
  if (options.connectionHistory !== void 0) body.connection_history = options.connectionHistory;
719
719
  if (options.clientTools) body.capabilities = ["client_tools"];
720
+ if (options.llm !== void 0) {
721
+ const { backend, model, baseUrl, token } = options.llm;
722
+ body.llm = model === void 0 ? { backend } : { backend, model };
723
+ body.external_llm = { base_url: baseUrl, token };
724
+ }
720
725
  if (options.transcript !== void 0) {
721
726
  body.transcript_webhook = { url: options.transcript.url, secret: options.transcript.secret };
722
727
  }
@@ -1,4 +1,4 @@
1
- import { sessionModeSchema, liveKitSessionReleaseReasonSchema, RealtimeAvatar, ROUTE_TIMEOUT_MS, isQueued, RealtimeAvatarHttpError, RealtimeAvatarError } from './chunk-HMESE54B.js';
1
+ import { sessionModeSchema, liveKitSessionReleaseReasonSchema, RealtimeAvatar, ROUTE_TIMEOUT_MS, isQueued, RealtimeAvatarHttpError, RealtimeAvatarError } from './chunk-NMJQEGYW.js';
2
2
  import { z } from 'zod';
3
3
 
4
4
  // ../http-client/src/generated/error-semantics.ts
package/dist/express.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { P as ProxyConfig } from './types-C7B7jOx6.js';
2
- import './types-D77jgSms.js';
1
+ import { P as ProxyConfig } from './types-JtCwa0Ip.js';
2
+ import './types-6MUqx800.js';
3
3
  import 'zod';
4
4
 
5
5
  type Expressish = {
package/dist/express.js CHANGED
@@ -1,5 +1,5 @@
1
- import { createProxyHandler } from './chunk-XJPGQMEW.js';
2
- import './chunk-HMESE54B.js';
1
+ import { createProxyHandler } from './chunk-SUKZ77GL.js';
2
+ import './chunk-NMJQEGYW.js';
3
3
  import './chunk-MCIXU6XP.js';
4
4
 
5
5
  // ../proxy/src/express.ts
package/dist/hono.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { P as ProxyConfig } from './types-C7B7jOx6.js';
2
- import './types-D77jgSms.js';
1
+ import { P as ProxyConfig } from './types-JtCwa0Ip.js';
2
+ import './types-6MUqx800.js';
3
3
  import 'zod';
4
4
 
5
5
  /**
package/dist/hono.js CHANGED
@@ -1,5 +1,5 @@
1
- import { createProxyHandler } from './chunk-XJPGQMEW.js';
2
- import './chunk-HMESE54B.js';
1
+ import { createProxyHandler } from './chunk-SUKZ77GL.js';
2
+ import './chunk-NMJQEGYW.js';
3
3
  import './chunk-MCIXU6XP.js';
4
4
 
5
5
  // ../proxy/src/hono.ts
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 ListRecordingsQuery, l as ListRecordingsResponse, R as RecordingArtifact, m as RecordingAccessResponse, n as CreditBalance, T as TranscriptPayload } from './types-D77jgSms.js';
2
- export { o as AvatarClip, p as CallConnection, q as CallQueued, r as ClipDeclaration, s as ClipLibraryPlan, t as ClipSource, u as ContextMessage, v as EndCallReason, w as RecordingArtifactStatus, x as RecordingMode, V as VideoPolicy, y as isQueued, z as listRecordingsResponseSchema, B as recordingAccessResponseSchema, D as recordingArtifactSchema, F as recordingModeSchema } from './types-D77jgSms.js';
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 ListRecordingsQuery, l as ListRecordingsResponse, R as RecordingArtifact, m as RecordingAccessResponse, n as CreditBalance, T as TranscriptPayload } from './types-6MUqx800.js';
2
+ export { o as AvatarClip, p as CallConnection, q as CallQueued, r as ClipDeclaration, s as ClipLibraryPlan, t as ClipSource, u as ContextMessage, v as EndCallReason, w as ExternalLlm, x as RecordingArtifactStatus, y as RecordingMode, V as VideoPolicy, z as isQueued, B as listRecordingsResponseSchema, D as recordingAccessResponseSchema, F as recordingArtifactSchema, G as recordingModeSchema } from './types-6MUqx800.js';
3
3
  import { ConnectionHistoryResponse } from './connection-history.js';
4
4
  import { z } from 'zod';
5
5
 
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- export { RealtimeAvatar, RealtimeAvatarError, RealtimeAvatarHttpError, clipLibraryDeclarationSchema, isQueued, listRecordingsResponseSchema, recordingAccessResponseSchema, recordingArtifactSchema, recordingModeSchema, verifyTranscript } from './chunk-HMESE54B.js';
1
+ export { RealtimeAvatar, RealtimeAvatarError, RealtimeAvatarHttpError, clipLibraryDeclarationSchema, isQueued, listRecordingsResponseSchema, recordingAccessResponseSchema, recordingArtifactSchema, recordingModeSchema, verifyTranscript } from './chunk-NMJQEGYW.js';
2
2
  import './chunk-MCIXU6XP.js';
package/dist/nextjs.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { P as ProxyConfig } from './types-C7B7jOx6.js';
2
- import './types-D77jgSms.js';
1
+ import { P as ProxyConfig } from './types-JtCwa0Ip.js';
2
+ import './types-6MUqx800.js';
3
3
  import 'zod';
4
4
 
5
5
  /**
package/dist/nextjs.js CHANGED
@@ -1,5 +1,5 @@
1
- import { createProxyHandler } from './chunk-XJPGQMEW.js';
2
- import './chunk-HMESE54B.js';
1
+ import { createProxyHandler } from './chunk-SUKZ77GL.js';
2
+ import './chunk-NMJQEGYW.js';
3
3
  import './chunk-MCIXU6XP.js';
4
4
 
5
5
  // ../proxy/src/nextjs.ts
@@ -715,8 +715,16 @@ type AvatarVideoSurfaceProps = {
715
715
  * against the box and stays clickable while she is live.
716
716
  */
717
717
  children?: ReactNode;
718
- /** Surface a small "live · WxH" badge when the live layer is shown. Default true. */
718
+ /**
719
+ * Surface a small "live" badge when the live layer is shown. Default true. Turn it off when
720
+ * your own UI already says the call is live.
721
+ */
719
722
  showLiveBadge?: boolean;
723
+ /**
724
+ * Show diagnostic readouts: today, the live layer's resolution on the badge
725
+ * ("live · 576×1010"). Default false. A development aid, never product copy.
726
+ */
727
+ debug?: boolean;
720
728
  /**
721
729
  * Reclaim the flat 0.5s de-jitter cushion on clean networks: a 1Hz closed loop
722
730
  * over `getStats()` that descends toward a 150ms floor while jitter and loss stay
@@ -1,7 +1,7 @@
1
1
  import { LiveKitRoomProps } from '@livekit/react-native';
2
2
  export { AudioSession, VideoTrack, VideoTrackProps, registerGlobals } from '@livekit/react-native';
3
- import { L as LiveKitSessionGrant, A as AvatarVideoFit } from './proxy-client-C8M_G_Kk.js';
4
- export { a as AdaptivePlayoutController, b as AdaptivePlayoutDecision, c as AdaptivePlayoutOptions, d as AdaptivePlayoutSample, e as ApproachingEndEvent, f as ApproachingEndReason, g as AvatarConnectionDetails, h as AvatarSessionClient, B as BehaviorSnapshot, C as CallTranscript, i as CallTranscriptSegment, j as CartesiaTtsModel, k as ClipResult, l as ClosingTurnResult, m as CreditsLowEvent, D as DEFAULT_APPROACHING_END_LEAD_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, u as DeclaredInputSource, E as EndReason, v as EndedEvent, w as ExtendResult, F as FishTtsModel, x as FreezeReadingFn, G as Governor, y as GovernorAction, z as GovernorConfig, H as GovernorSignal, I as GovernorState, J as GraceWindowClosedEvent, K as GraceWindowOpenEvent, M as GraceWindowState, N as IdleWarningEvent, O as InboundRtpCursor, P as InboundRtpReading, Q as KnownBehaviorState, R as LLMProvider, S as LLMSelection, T as LiveKitAvatarGrantState, U as LiveKitAvatarGrantStatus, V as LiveKitCapacityState, W as LiveKitConnectionStatus, X as LiveKitSessionRequest, Y as LiveKitSessionStartResult, Z as MAX_RECONNECT_ATTEMPTS, _ as MAX_SESSION_INSTRUCTIONS_CHARS, $ as ProxyClientOptions, a0 as QualityCap, a1 as RECONNECT_BACKOFF_MS, a2 as RealtimeAvatarRequestOptions, a3 as RealtimeSessionApi, a4 as RealtimeSessionMedia, a5 as RealtimeSessionRoomSinks, a6 as ReconnectPolicy, a7 as ReconnectingEvent, a8 as RecoveryState, a9 as RetryStep, aa as SendTurnOptions, ab as SessionBehavior, ac as SessionClip, ad as SessionClocks, ae as SessionEndReason, af as SessionLifecycleApi, ag as SessionLifecyclePhase, ah as SessionLifecyclePhaseKind, ai as SessionLifecycleRoomBridge, aj as SessionLifecycleRoomBridgeProps, ak as SurfaceLayers, al as TranscriptSender, am as TranscriptSenderOptions, an as TurnState, ao as TurnTimeoutEvent, ap as UseAvatarQualityGovernorInput, aq as UseLiveKitAvatarGrantInput, ar as UseRealtimeSessionInput, as as UseSessionLifecycleInput, at as VoiceSpec, au as VoiceSpecInput, av as capacityErrorFromBusy, aw as capacityStateFromGrant, ax as createProxyClient, ay as isNativeLiveTrackSubscribed, az as knownBehaviorStates, aA as mapTurnState, aB as readInboundRtp, aC as sessionBehaviorSchema, aD as sessionClipSchema, aE as splitCallTranscript, aF as useAvatarAdaptivePlayoutDelay, aG as useAvatarCamera, aH as useAvatarPlayoutDelay, aI as useAvatarQualityGovernor, aJ as useCallTranscript, aK as useLiveKitAvatarGrant, aL as useLiveTrackProducing, aM as useMicLease, aN as useRealtimeSession, aO as useReleaseMicLeaseOnTrackEnded, aP as useSessionLifecycle } from './proxy-client-C8M_G_Kk.js';
3
+ import { L as LiveKitSessionGrant, A as AvatarVideoFit } from './proxy-client-D75TLU5X.js';
4
+ export { a as AdaptivePlayoutController, b as AdaptivePlayoutDecision, c as AdaptivePlayoutOptions, d as AdaptivePlayoutSample, e as ApproachingEndEvent, f as ApproachingEndReason, g as AvatarConnectionDetails, h as AvatarSessionClient, B as BehaviorSnapshot, C as CallTranscript, i as CallTranscriptSegment, j as CartesiaTtsModel, k as ClipResult, l as ClosingTurnResult, m as CreditsLowEvent, D as DEFAULT_APPROACHING_END_LEAD_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, u as DeclaredInputSource, E as EndReason, v as EndedEvent, w as ExtendResult, F as FishTtsModel, x as FreezeReadingFn, G as Governor, y as GovernorAction, z as GovernorConfig, H as GovernorSignal, I as GovernorState, J as GraceWindowClosedEvent, K as GraceWindowOpenEvent, M as GraceWindowState, N as IdleWarningEvent, O as InboundRtpCursor, P as InboundRtpReading, Q as KnownBehaviorState, R as LLMProvider, S as LLMSelection, T as LiveKitAvatarGrantState, U as LiveKitAvatarGrantStatus, V as LiveKitCapacityState, W as LiveKitConnectionStatus, X as LiveKitSessionRequest, Y as LiveKitSessionStartResult, Z as MAX_RECONNECT_ATTEMPTS, _ as MAX_SESSION_INSTRUCTIONS_CHARS, $ as ProxyClientOptions, a0 as QualityCap, a1 as RECONNECT_BACKOFF_MS, a2 as RealtimeAvatarRequestOptions, a3 as RealtimeSessionApi, a4 as RealtimeSessionMedia, a5 as RealtimeSessionRoomSinks, a6 as ReconnectPolicy, a7 as ReconnectingEvent, a8 as RecoveryState, a9 as RetryStep, aa as SendTurnOptions, ab as SessionBehavior, ac as SessionClip, ad as SessionClocks, ae as SessionEndReason, af as SessionLifecycleApi, ag as SessionLifecyclePhase, ah as SessionLifecyclePhaseKind, ai as SessionLifecycleRoomBridge, aj as SessionLifecycleRoomBridgeProps, ak as SurfaceLayers, al as TranscriptSender, am as TranscriptSenderOptions, an as TurnState, ao as TurnTimeoutEvent, ap as UseAvatarQualityGovernorInput, aq as UseLiveKitAvatarGrantInput, ar as UseRealtimeSessionInput, as as UseSessionLifecycleInput, at as VoiceSpec, au as VoiceSpecInput, av as capacityErrorFromBusy, aw as capacityStateFromGrant, ax as createProxyClient, ay as isNativeLiveTrackSubscribed, az as knownBehaviorStates, aA as mapTurnState, aB as readInboundRtp, aC as sessionBehaviorSchema, aD as sessionClipSchema, aE as splitCallTranscript, aF as useAvatarAdaptivePlayoutDelay, aG as useAvatarCamera, aH as useAvatarPlayoutDelay, aI as useAvatarQualityGovernor, aJ as useCallTranscript, aK as useLiveKitAvatarGrant, aL as useLiveTrackProducing, aM as useMicLease, aN as useRealtimeSession, aO as useReleaseMicLeaseOnTrackEnded, aP as useSessionLifecycle } from './proxy-client-D75TLU5X.js';
5
5
  import { ReactNode, ReactElement } from 'react';
6
6
  import { StyleProp, ViewStyle } from 'react-native';
7
7
  export { useChat, useConnectionState, useLocalParticipant, useRoomContext, useTrackToggle, useTranscriptions, useVoiceAssistant } from '@livekit/components-react';
@@ -87,8 +87,13 @@ type AvatarVideoSurfaceProps = {
87
87
  style?: StyleProp<ViewStyle>;
88
88
  /** Overlay content rendered above both media layers (badges, chrome, scrims). */
89
89
  children?: ReactNode;
90
- /** Surface a small "live · WxH" badge when the live layer is shown. Default true. */
90
+ /**
91
+ * Surface a small "live" badge when the live layer is shown. Default true. Turn it off when
92
+ * your own UI already says the call is live.
93
+ */
91
94
  showLiveBadge?: boolean;
95
+ /** Show diagnostic readouts: today, the live layer's resolution on the badge. Default false. */
96
+ debug?: boolean;
92
97
  /**
93
98
  * Reclaim the flat 0.5s de-jitter cushion on clean networks — the same opt-in
94
99
  * closed loop the web surface takes, sharing the same implementation. Default
@@ -1416,6 +1416,9 @@ function useAvatarQualityGovernor(input) {
1416
1416
  }
1417
1417
 
1418
1418
  // ../client/src/react/avatar-video-surface.ts
1419
+ function liveBadgeLabel(dims, debug) {
1420
+ return debug && dims && dims.width > 0 && dims.height > 0 ? `live \xB7 ${dims.width}\xD7${dims.height}` : "live";
1421
+ }
1419
1422
  function resolveSurfaceLayers(input) {
1420
1423
  return {
1421
1424
  showPoster: Boolean(input.poster),
@@ -1491,6 +1494,7 @@ function AvatarVideoSurface(props) {
1491
1494
  style,
1492
1495
  children,
1493
1496
  showLiveBadge = true,
1497
+ debug = false,
1494
1498
  adaptivePlayout = false,
1495
1499
  onPlayoutDelayChange,
1496
1500
  testID
@@ -1533,7 +1537,7 @@ function AvatarVideoSurface(props) {
1533
1537
  });
1534
1538
  const resizeMode = fit === "cover" ? "cover" : "contain";
1535
1539
  const liveDims = videoTrack?.publication?.dimensions ?? null;
1536
- const liveLabel = showLive && liveDims && liveDims.width > 0 && liveDims.height > 0 ? `live \xB7 ${liveDims.width}\xD7${liveDims.height}` : "live";
1540
+ const liveLabel = liveBadgeLabel(liveDims, debug);
1537
1541
  const posterLayer = layers.showPoster ? createElement(Image, {
1538
1542
  key: "poster",
1539
1543
  source: { uri: poster },
package/dist/react.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { ToolRegistration, RegisteredTool } from './tools.js';
2
- import { aj as SessionLifecycleRoomBridgeProps, h as AvatarSessionClient, A as AvatarVideoFit, aQ as CallMicrophone, aR as CallAudioPlayback, aS as CallMicrophoneProblem } from './proxy-client-C8M_G_Kk.js';
3
- export { a as AdaptivePlayoutController, b as AdaptivePlayoutDecision, c as AdaptivePlayoutOptions, d as AdaptivePlayoutSample, e as ApproachingEndEvent, f as ApproachingEndReason, g as AvatarConnectionDetails, aT as AvatarVideoSurface, aU as AvatarVideoSurfaceProps, B as BehaviorSnapshot, C as CallTranscript, i as CallTranscriptSegment, j as CartesiaTtsModel, k as ClipResult, l as ClosingTurnResult, m as CreditsLowEvent, D as DEFAULT_APPROACHING_END_LEAD_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, u as DeclaredInputSource, E as EndReason, v as EndedEvent, w as ExtendResult, F as FishTtsModel, x as FreezeReadingFn, G as Governor, y as GovernorAction, z as GovernorConfig, H as GovernorSignal, I as GovernorState, J as GraceWindowClosedEvent, K as GraceWindowOpenEvent, M as GraceWindowState, N as IdleWarningEvent, O as InboundRtpCursor, P as InboundRtpReading, Q as KnownBehaviorState, R as LLMProvider, S as LLMSelection, T as LiveKitAvatarGrantState, U as LiveKitAvatarGrantStatus, V as LiveKitCapacityState, W as LiveKitConnectionStatus, X as LiveKitSessionRequest, Y as LiveKitSessionStartResult, aV as LivePlaybackKeeper, Z as MAX_RECONNECT_ATTEMPTS, _ as MAX_SESSION_INSTRUCTIONS_CHARS, aW as MIC_LEASE_ENDED_TIMEOUT_MS, aX as MicLease, aY as NETWORK_QUALITY_POLICY, aZ as NetworkQualityStatus, a_ as PlayableVideoElement, $ as ProxyClientOptions, a0 as QualityCap, a1 as RECONNECT_BACKOFF_MS, a$ as RealtimeAvatarCapacityError, b0 as RealtimeAvatarLiveKitRoom, b1 as RealtimeAvatarLiveKitRoomProps, a2 as RealtimeAvatarRequestOptions, a3 as RealtimeSessionApi, a4 as RealtimeSessionMedia, a5 as RealtimeSessionRoomSinks, a6 as ReconnectPolicy, a7 as ReconnectingEvent, a8 as RecoveryState, a9 as RetryStep, aa as SendTurnOptions, ab as SessionBehavior, ac as SessionClip, ad as SessionClocks, ae as SessionEndReason, af as SessionLifecycleApi, ag as SessionLifecyclePhase, ah as SessionLifecyclePhaseKind, ai as SessionLifecycleRoomBridge, ak as SurfaceLayers, al as TranscriptSender, am as TranscriptSenderOptions, an as TurnState, ao as TurnTimeoutEvent, ap as UseAvatarQualityGovernorInput, aq as UseLiveKitAvatarGrantInput, ar as UseRealtimeSessionInput, as as UseSessionLifecycleInput, at as VoiceSpec, au as VoiceSpecInput, av as capacityErrorFromBusy, aw as capacityStateFromGrant, ax as createProxyClient, az as knownBehaviorStates, aA as mapTurnState, aB as readInboundRtp, aC as sessionBehaviorSchema, aD as sessionClipSchema, b2 as shouldReplayPendingTurn, aE as splitCallTranscript, aF as useAvatarAdaptivePlayoutDelay, aG as useAvatarCamera, aH as useAvatarPlayoutDelay, aI as useAvatarQualityGovernor, aJ as useCallTranscript, aK as useLiveKitAvatarGrant, aM as useMicLease, aN as useRealtimeSession, aO as useReleaseMicLeaseOnTrackEnded, aP as useSessionLifecycle } from './proxy-client-C8M_G_Kk.js';
2
+ import { aj as SessionLifecycleRoomBridgeProps, h as AvatarSessionClient, A as AvatarVideoFit, aQ as CallMicrophone, aR as CallAudioPlayback, aS as CallMicrophoneProblem } from './proxy-client-D75TLU5X.js';
3
+ export { a as AdaptivePlayoutController, b as AdaptivePlayoutDecision, c as AdaptivePlayoutOptions, d as AdaptivePlayoutSample, e as ApproachingEndEvent, f as ApproachingEndReason, g as AvatarConnectionDetails, aT as AvatarVideoSurface, aU as AvatarVideoSurfaceProps, B as BehaviorSnapshot, C as CallTranscript, i as CallTranscriptSegment, j as CartesiaTtsModel, k as ClipResult, l as ClosingTurnResult, m as CreditsLowEvent, D as DEFAULT_APPROACHING_END_LEAD_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, u as DeclaredInputSource, E as EndReason, v as EndedEvent, w as ExtendResult, F as FishTtsModel, x as FreezeReadingFn, G as Governor, y as GovernorAction, z as GovernorConfig, H as GovernorSignal, I as GovernorState, J as GraceWindowClosedEvent, K as GraceWindowOpenEvent, M as GraceWindowState, N as IdleWarningEvent, O as InboundRtpCursor, P as InboundRtpReading, Q as KnownBehaviorState, R as LLMProvider, S as LLMSelection, T as LiveKitAvatarGrantState, U as LiveKitAvatarGrantStatus, V as LiveKitCapacityState, W as LiveKitConnectionStatus, X as LiveKitSessionRequest, Y as LiveKitSessionStartResult, aV as LivePlaybackKeeper, Z as MAX_RECONNECT_ATTEMPTS, _ as MAX_SESSION_INSTRUCTIONS_CHARS, aW as MIC_LEASE_ENDED_TIMEOUT_MS, aX as MicLease, aY as NETWORK_QUALITY_POLICY, aZ as NetworkQualityStatus, a_ as PlayableVideoElement, $ as ProxyClientOptions, a0 as QualityCap, a1 as RECONNECT_BACKOFF_MS, a$ as RealtimeAvatarCapacityError, b0 as RealtimeAvatarLiveKitRoom, b1 as RealtimeAvatarLiveKitRoomProps, a2 as RealtimeAvatarRequestOptions, a3 as RealtimeSessionApi, a4 as RealtimeSessionMedia, a5 as RealtimeSessionRoomSinks, a6 as ReconnectPolicy, a7 as ReconnectingEvent, a8 as RecoveryState, a9 as RetryStep, aa as SendTurnOptions, ab as SessionBehavior, ac as SessionClip, ad as SessionClocks, ae as SessionEndReason, af as SessionLifecycleApi, ag as SessionLifecyclePhase, ah as SessionLifecyclePhaseKind, ai as SessionLifecycleRoomBridge, ak as SurfaceLayers, al as TranscriptSender, am as TranscriptSenderOptions, an as TurnState, ao as TurnTimeoutEvent, ap as UseAvatarQualityGovernorInput, aq as UseLiveKitAvatarGrantInput, ar as UseRealtimeSessionInput, as as UseSessionLifecycleInput, at as VoiceSpec, au as VoiceSpecInput, av as capacityErrorFromBusy, aw as capacityStateFromGrant, ax as createProxyClient, az as knownBehaviorStates, aA as mapTurnState, aB as readInboundRtp, aC as sessionBehaviorSchema, aD as sessionClipSchema, b2 as shouldReplayPendingTurn, aE as splitCallTranscript, aF as useAvatarAdaptivePlayoutDelay, aG as useAvatarCamera, aH as useAvatarPlayoutDelay, aI as useAvatarQualityGovernor, aJ as useCallTranscript, aK as useLiveKitAvatarGrant, aM as useMicLease, aN as useRealtimeSession, aO as useReleaseMicLeaseOnTrackEnded, aP as useSessionLifecycle } from './proxy-client-D75TLU5X.js';
4
4
  import { CSSProperties, ReactNode } from 'react';
5
5
  import * as react_jsx_runtime from 'react/jsx-runtime';
6
6
  import { R as RecordingArtifact } from './recording-DjswTx5B.js';
@@ -138,6 +138,11 @@ type AvatarCallProps = Pick<SessionLifecycleRoomBridgeProps, "onConnectionDetail
138
138
  /** A still shown before the idle clip is playable. */
139
139
  poster?: string | null;
140
140
  fit?: AvatarVideoFit;
141
+ /**
142
+ * The small "live" badge over the video while she is live. Default true. Set false when your
143
+ * own UI already shows the call's status.
144
+ */
145
+ showLiveBadge?: boolean;
141
146
  /** Adds your classes to the call's box. The box sizes itself inline; to resize it, use `style`. */
142
147
  className?: string;
143
148
  /** Inline style for the call's box, spread over its own (`height`, `aspectRatio`, …). */
package/dist/react.js CHANGED
@@ -1756,6 +1756,7 @@ function AvatarVideoSurface(props) {
1756
1756
  style,
1757
1757
  children,
1758
1758
  showLiveBadge = true,
1759
+ debug = false,
1759
1760
  adaptivePlayout = false,
1760
1761
  onPlayoutDelayChange
1761
1762
  } = props;
@@ -1819,7 +1820,6 @@ function AvatarVideoSurface(props) {
1819
1820
  );
1820
1821
  useLiveResumeOnProducing(liveWrapRef, trackProducing);
1821
1822
  const fitStyle = fit === "cover" ? AVATAR_VIDEO_FIT_COVER : AVATAR_VIDEO_FIT_CONTAIN;
1822
- const liveLabel = showLive && liveDims && liveDims.width > 0 && liveDims.height > 0 ? `${liveDims.width}\xD7${liveDims.height}` : null;
1823
1823
  const layers = resolveSurfaceLayers({ idleVideoUrl, poster });
1824
1824
  const backFitStyle = fitStyle;
1825
1825
  const posterLayer = layers.showPoster ? createElement("img", {
@@ -1874,7 +1874,7 @@ function AvatarVideoSurface(props) {
1874
1874
  "span",
1875
1875
  { key: "badge", style: AVATAR_VIDEO_BADGE },
1876
1876
  createElement("span", { key: "dot", style: AVATAR_VIDEO_BADGE_DOT, "aria-hidden": true }),
1877
- liveLabel ? `live \xB7 ${liveLabel}` : "live"
1877
+ liveBadgeLabel(liveDims, debug)
1878
1878
  ) : null;
1879
1879
  return createElement(
1880
1880
  "div",
@@ -1895,6 +1895,9 @@ function AvatarVideoSurface(props) {
1895
1895
  children == null || children === false ? null : createElement("div", { key: "overlay", style: AVATAR_VIDEO_OVERLAY, "data-testid": "avatar-overlay" }, children)
1896
1896
  );
1897
1897
  }
1898
+ function liveBadgeLabel(dims, debug) {
1899
+ return debug && dims && dims.width > 0 && dims.height > 0 ? `live \xB7 ${dims.width}\xD7${dims.height}` : "live";
1900
+ }
1898
1901
  function resolveSurfaceLayers(input) {
1899
1902
  return {
1900
1903
  showPoster: Boolean(input.poster),
@@ -4333,6 +4336,7 @@ function useAvatarCall(props) {
4333
4336
  idleVideoUrl: props.idleVideoUrl ?? null,
4334
4337
  poster: props.poster ?? null,
4335
4338
  fit: props.fit ?? "cover",
4339
+ showLiveBadge: props.showLiveBadge,
4336
4340
  className: props.className,
4337
4341
  style: props.style
4338
4342
  },
package/dist/server.d.ts CHANGED
@@ -1,4 +1,4 @@
1
1
  export { RealtimeAvatar, RealtimeAvatarError, RealtimeAvatarHttpError, RealtimeAvatarOptions, StartCallOptions, clipLibraryDeclarationSchema, verifyTranscript } from './index.js';
2
- export { h as Asset, g as AssetKind, A as Avatar, o as AvatarClip, c as AvatarSourceSwap, b as AvatarUpdate, p as CallConnection, C as CallMode, a as CallPolicy, q as CallQueued, r as ClipDeclaration, f as ClipLibrary, d as ClipLibraryDeclaration, s as ClipLibraryPlan, e as ClipLibraryUpdate, t as ClipSource, u as ContextMessage, n as CreditBalance, E as EndCallOptions, v as EndCallReason, k as ListRecordingsQuery, l as ListRecordingsResponse, i as ListSessionsOptions, L as LoopRedirect, m as RecordingAccessResponse, R as RecordingArtifact, w as RecordingArtifactStatus, x as RecordingMode, S as StartCallResult, T as TranscriptPayload, j as UsageSession, U as UsageSessionPage, V as VideoPolicy, y as isQueued, z as listRecordingsResponseSchema, B as recordingAccessResponseSchema, D as recordingArtifactSchema, F as recordingModeSchema } from './types-D77jgSms.js';
2
+ export { h as Asset, g as AssetKind, A as Avatar, o as AvatarClip, c as AvatarSourceSwap, b as AvatarUpdate, p as CallConnection, C as CallMode, a as CallPolicy, q as CallQueued, r as ClipDeclaration, f as ClipLibrary, d as ClipLibraryDeclaration, s as ClipLibraryPlan, e as ClipLibraryUpdate, t as ClipSource, u as ContextMessage, n as CreditBalance, E as EndCallOptions, v as EndCallReason, w as ExternalLlm, k as ListRecordingsQuery, l as ListRecordingsResponse, i as ListSessionsOptions, L as LoopRedirect, m as RecordingAccessResponse, R as RecordingArtifact, x as RecordingArtifactStatus, y as RecordingMode, S as StartCallResult, T as TranscriptPayload, j as UsageSession, U as UsageSessionPage, V as VideoPolicy, z as isQueued, B as listRecordingsResponseSchema, D as recordingAccessResponseSchema, F as recordingArtifactSchema, G as recordingModeSchema } from './types-6MUqx800.js';
3
3
  import './connection-history.js';
4
4
  import 'zod';
package/dist/server.js CHANGED
@@ -1,2 +1,2 @@
1
- export { RealtimeAvatar, RealtimeAvatarError, RealtimeAvatarHttpError, clipLibraryDeclarationSchema, isQueued, listRecordingsResponseSchema, recordingAccessResponseSchema, recordingArtifactSchema, recordingModeSchema, verifyTranscript } from './chunk-HMESE54B.js';
1
+ export { RealtimeAvatar, RealtimeAvatarError, RealtimeAvatarHttpError, clipLibraryDeclarationSchema, isQueued, listRecordingsResponseSchema, recordingAccessResponseSchema, recordingArtifactSchema, recordingModeSchema, verifyTranscript } from './chunk-NMJQEGYW.js';
2
2
  import './chunk-MCIXU6XP.js';
@@ -1,5 +1,5 @@
1
- import { P as ProxyConfig } from './types-C7B7jOx6.js';
2
- import './types-D77jgSms.js';
1
+ import { P as ProxyConfig } from './types-JtCwa0Ip.js';
2
+ import './types-6MUqx800.js';
3
3
  import 'zod';
4
4
 
5
5
  /**
@@ -1,5 +1,5 @@
1
- import { createProxyHandler } from './chunk-XJPGQMEW.js';
2
- import './chunk-HMESE54B.js';
1
+ import { createProxyHandler } from './chunk-SUKZ77GL.js';
2
+ import './chunk-NMJQEGYW.js';
3
3
  import './chunk-MCIXU6XP.js';
4
4
 
5
5
  // src/tanstack-start.ts
@@ -26,8 +26,11 @@ interface components {
26
26
  }[];
27
27
  initial_say?: string;
28
28
  llm?: {
29
- /** @enum {string} */
30
- backend?: "local" | "gemini" | "openai";
29
+ /**
30
+ * @description Which model answers the turns. `external` is enabled per workspace for server-to-server callers and needs endpoint configuration that is not part of this document; a workspace without it is refused with 403.
31
+ * @enum {string}
32
+ */
33
+ backend?: "local" | "gemini" | "openai" | "external";
31
34
  model?: string | null;
32
35
  } | null;
33
36
  max_session_seconds?: number;
@@ -1630,6 +1633,34 @@ type VideoPolicy = {
1630
1633
  } | {
1631
1634
  mode: "generative";
1632
1635
  };
1636
+ /** The session `llm` on the wire, from the published contract. */
1637
+ type WireLlm = NonNullable<Wire["LiveKitSessionRequest"]["llm"]>;
1638
+ /**
1639
+ * DERIVATION: `backend` and `model` index the contract's `llm`. `baseUrl` and `token` are sent as
1640
+ * `external_llm`, which the platform marks server-authoritative and therefore REDACTS from the
1641
+ * published document, so they cannot be derived from it; they are written here, like
1642
+ * `clientTools` → `capabilities`.
1643
+ *
1644
+ * Answer this call's turns from an OpenAI-compatible endpoint YOUR SERVER hosts. The platform
1645
+ * keeps listening, turn-taking, interruption, her voice and her face; each reply is streamed
1646
+ * from `POST {baseUrl}/chat/completions` instead of the platform's model.
1647
+ *
1648
+ * Enabled per workspace: a workspace without it, or an endpoint host it has not allowlisted, is
1649
+ * refused with 403. A failure before the first token of a reply (an error, a stall, an empty
1650
+ * answer) speaks that reply from the platform's model instead, so the call never goes silent.
1651
+ */
1652
+ interface ExternalLlm {
1653
+ backend: Extract<NonNullable<WireLlm["backend"]>, "external">;
1654
+ /** https only. The worker POSTs `{baseUrl}/chat/completions` with `stream: true`. */
1655
+ baseUrl: string;
1656
+ /**
1657
+ * Sent as `Authorization: Bearer <token>` on every turn of this call. Mint it per call and
1658
+ * short-lived: it outlives nothing but the call. 16–4096 characters.
1659
+ */
1660
+ token: string;
1661
+ /** Sent as `model`. Omit it to let your endpoint choose. */
1662
+ model?: NonNullable<WireLlm["model"]>;
1663
+ }
1633
1664
  /** What YOUR SERVER decides about a call. Never accept any of this from a browser. */
1634
1665
  interface CallPolicy {
1635
1666
  /** Ask the platform to grant the SDK's optional LiveKit connection history collector. */
@@ -1666,6 +1697,12 @@ interface CallPolicy {
1666
1697
  * connects. Putting tools on the mint returns 422 (the request schema is strict).
1667
1698
  */
1668
1699
  clientTools?: boolean;
1700
+ /**
1701
+ * Who answers her turns: an endpoint your server hosts. Omit it and the platform's model does.
1702
+ * It carries a credential, so it is a server decision like everything here, and the browser
1703
+ * entries of this package cannot send it.
1704
+ */
1705
+ llm?: ExternalLlm;
1669
1706
  /** Receive the two-sided transcript, signed, after the call ends. */
1670
1707
  transcript?: {
1671
1708
  url: string;
@@ -1918,4 +1955,4 @@ interface TranscriptPayload {
1918
1955
  client_metadata: Record<string, string>;
1919
1956
  }
1920
1957
 
1921
- export { type Avatar as A, recordingAccessResponseSchema as B, type CallMode as C, recordingArtifactSchema as D, type EndCallOptions as E, recordingModeSchema as F, type LoopRedirect as L, type RecordingArtifact as R, type StartCallResult as S, type TranscriptPayload as T, type UsageSessionPage as U, type VideoPolicy as V, type CallPolicy as a, type AvatarUpdate as b, type AvatarSourceSwap as c, type ClipLibraryDeclaration as d, type ClipLibraryUpdate as e, type ClipLibrary as f, type AssetKind as g, type Asset as h, type ListSessionsOptions as i, type UsageSession as j, type ListRecordingsQuery as k, type ListRecordingsResponse as l, type RecordingAccessResponse as m, type CreditBalance as n, type AvatarClip as o, type CallConnection as p, type CallQueued as q, type ClipDeclaration as r, type ClipLibraryPlan as s, type ClipSource as t, type ContextMessage as u, type EndCallReason as v, type RecordingArtifactStatus as w, type RecordingMode as x, isQueued as y, listRecordingsResponseSchema as z };
1958
+ export { type Avatar as A, listRecordingsResponseSchema as B, type CallMode as C, recordingAccessResponseSchema as D, type EndCallOptions as E, recordingArtifactSchema as F, recordingModeSchema as G, type LoopRedirect as L, type RecordingArtifact as R, type StartCallResult as S, type TranscriptPayload as T, type UsageSessionPage as U, type VideoPolicy as V, type CallPolicy as a, type AvatarUpdate as b, type AvatarSourceSwap as c, type ClipLibraryDeclaration as d, type ClipLibraryUpdate as e, type ClipLibrary as f, type AssetKind as g, type Asset as h, type ListSessionsOptions as i, type UsageSession as j, type ListRecordingsQuery as k, type ListRecordingsResponse as l, type RecordingAccessResponse as m, type CreditBalance as n, type AvatarClip as o, type CallConnection as p, type CallQueued as q, type ClipDeclaration as r, type ClipLibraryPlan as s, type ClipSource as t, type ContextMessage as u, type EndCallReason as v, type ExternalLlm as w, type RecordingArtifactStatus as x, type RecordingMode as y, isQueued as z };
@@ -1,4 +1,4 @@
1
- import { C as CallMode, a as CallPolicy } from './types-D77jgSms.js';
1
+ import { C as CallMode, a as CallPolicy } from './types-6MUqx800.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";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "realtime-avatar",
3
- "version": "0.26.0",
3
+ "version": "0.27.0",
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",