realtime-avatar 0.27.0 → 0.27.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.
@@ -177,6 +177,8 @@ function RealtimeAvatarLiveKitRoom(props) {
177
177
  LiveKitRoom,
178
178
  {
179
179
  ...roomProps,
180
+ // Keep the room and its in-room observers scoped to the grant, as on web.
181
+ key: grant?.session_id ?? "no-session",
180
182
  serverUrl: grant?.livekit_url,
181
183
  token: grant?.participant_token,
182
184
  connect: shouldConnect,
@@ -1712,6 +1714,8 @@ var transcriptionOptionsSchema = z.object({
1712
1714
  languageCodes: transcriptionWireSchema.shape.language_codes,
1713
1715
  customVocabulary: transcriptionWireSchema.shape.custom_vocabulary
1714
1716
  }).strict();
1717
+ var schema02 = z.enum(["minor-sexual-content-v1"]);
1718
+ var contentPolicySchema = schema02;
1715
1719
 
1716
1720
  // ../client/src/wire.ts
1717
1721
  var DEFAULT_AVATAR_ID = "maria";
@@ -1878,7 +1882,8 @@ z.object({
1878
1882
  support_edits: sessionSupportEditsSchema.optional(),
1879
1883
  transcript_webhook: transcriptWebhookSchema.optional(),
1880
1884
  client_metadata: clientMetadataSchema.optional(),
1881
- connection_history: z.boolean().optional()
1885
+ connection_history: z.boolean().optional(),
1886
+ content_policy: contentPolicySchema.optional()
1882
1887
  }).strict().superRefine((value, ctx) => {
1883
1888
  if (value.support_edits && value.render_backend === "generative") {
1884
1889
  ctx.addIssue({
@@ -1946,7 +1951,8 @@ z.object({
1946
1951
  supportEdits: sessionSupportEditsSchema.optional(),
1947
1952
  transcriptWebhook: transcriptWebhookSchema.optional(),
1948
1953
  clientMetadata: clientMetadataSchema.optional(),
1949
- connectionHistory: z.boolean().optional()
1954
+ connectionHistory: z.boolean().optional(),
1955
+ contentPolicy: contentPolicySchema.optional()
1950
1956
  }).strict();
1951
1957
  z.object({
1952
1958
  recording: recordingArtifactSchema.optional(),
@@ -2395,7 +2401,8 @@ function lifecyclePhaseFrom(args) {
2395
2401
  kind: "reconnectable",
2396
2402
  reconnecting: true,
2397
2403
  attempt: recovery.attempt,
2398
- strategy: "fresh-grant"
2404
+ strategy: "fresh-grant",
2405
+ ...recovery.reason ? { reason: recovery.reason } : {}
2399
2406
  };
2400
2407
  }
2401
2408
  if (recovery.kind === "failed") {
@@ -2403,11 +2410,16 @@ function lifecyclePhaseFrom(args) {
2403
2410
  kind: "reconnectable",
2404
2411
  reconnecting: false,
2405
2412
  attempt: MAX_RECONNECT_ATTEMPTS,
2406
- strategy: "fresh-grant"
2413
+ strategy: "fresh-grant",
2414
+ ...recovery.reason ? { reason: recovery.reason } : {}
2407
2415
  };
2408
2416
  }
2409
2417
  if (recovery.kind === "ended") {
2410
- return recovery.reason ? { kind: "ended", reason: recovery.reason } : { kind: "ended" };
2418
+ return {
2419
+ kind: "ended",
2420
+ ...recovery.reason ? { reason: recovery.reason } : {},
2421
+ ...recovery.code ? { code: recovery.code } : {}
2422
+ };
2411
2423
  }
2412
2424
  switch (capacity.kind) {
2413
2425
  case "idle":
@@ -2420,7 +2432,7 @@ function lifecyclePhaseFrom(args) {
2420
2432
  return { kind: "ended", reason: "error" };
2421
2433
  case "active": {
2422
2434
  if (!connected || !agentPresent) {
2423
- return { kind: "connecting", grant: capacity.grant };
2435
+ return { kind: "connecting", grant: capacity.grant, waitingFor: connected ? "agent" : "transport" };
2424
2436
  }
2425
2437
  if (idle.kind === "idle-warning") {
2426
2438
  return { kind: "idle-warning", secondsRemaining: idle.secondsRemaining, deadlineAt: idle.deadlineAt };
@@ -2448,6 +2460,7 @@ function resolveIdleTimeoutMs(args) {
2448
2460
  return DEFAULT_IDLE_SECONDS * 1e3;
2449
2461
  }
2450
2462
  var DEFAULT_CONNECT_WATCHDOG_SECONDS = 12;
2463
+ var DEFAULT_READY_TIMEOUT_SECONDS = 30;
2451
2464
  function resolveWarnBeforeMs(idleTimeoutMs, override, idleWarnLeadSeconds) {
2452
2465
  if (idleTimeoutMs <= 0) return 0;
2453
2466
  const maxLeadMs = Math.max(0, idleTimeoutMs - 1e3);
@@ -2473,6 +2486,7 @@ function useSessionLifecycle(input) {
2473
2486
  maxReconnectAttempts,
2474
2487
  autoRetryBusy = true,
2475
2488
  connectWatchdogSeconds,
2489
+ readyTimeoutSeconds,
2476
2490
  requestOptions,
2477
2491
  onBehaviorChange
2478
2492
  } = input;
@@ -2483,17 +2497,27 @@ function useSessionLifecycle(input) {
2483
2497
  const reconnectPolicyRef = useRef(reconnectPolicy);
2484
2498
  reconnectPolicyRef.current = reconnectPolicy;
2485
2499
  const connectWatchdogMs = typeof connectWatchdogSeconds === "number" && Number.isFinite(connectWatchdogSeconds) ? Math.max(0, Math.floor(connectWatchdogSeconds)) * 1e3 : DEFAULT_CONNECT_WATCHDOG_SECONDS * 1e3;
2500
+ const readyTimeoutMs = typeof readyTimeoutSeconds === "number" && Number.isFinite(readyTimeoutSeconds) && readyTimeoutSeconds > 0 ? Math.max(1, Math.floor(readyTimeoutSeconds)) * 1e3 : DEFAULT_READY_TIMEOUT_SECONDS * 1e3;
2486
2501
  const [userEnded, setUserEnded] = useState(false);
2487
2502
  const userEndedRef = useRef(false);
2503
+ const [readinessFailed, setReadinessFailed] = useState(false);
2504
+ const readinessFailureRef = useRef(null);
2505
+ const readinessRef = useRef(null);
2506
+ const readyGrantRef = useRef(null);
2507
+ const agentWaitRef = useRef(null);
2488
2508
  const phaseRef = useRef({ kind: "idle" });
2489
2509
  const grantState = useLiveKitAvatarGrant({
2490
2510
  client,
2491
2511
  session,
2492
- active: active && !userEnded,
2512
+ active: active && !userEnded && !readinessFailed,
2493
2513
  autoRetryBusy,
2494
2514
  requestOptions
2495
2515
  });
2496
2516
  const capacity = grantState.capacity;
2517
+ const grantId = grantState.grant?.session_id ?? null;
2518
+ const grantIdRef = useRef(null);
2519
+ grantIdRef.current = grantId;
2520
+ const retiredGrantRef = useRef(null);
2497
2521
  const [recovery, setRecovery] = useState({ kind: "connected" });
2498
2522
  const recoveryRef = useRef(recovery);
2499
2523
  recoveryRef.current = recovery;
@@ -2516,8 +2540,19 @@ function useSessionLifecycle(input) {
2516
2540
  grantIdleSeconds: grantState.grant?.idle_timeout_seconds ?? 0
2517
2541
  });
2518
2542
  const warnAtMs = resolveWarnBeforeMs(idleTimeoutMs, warnBeforeMs, idleWarnLeadSeconds);
2519
- const [agentPresent, setAgentPresentState] = useState(false);
2520
- const [connected, setConnected] = useState(false);
2543
+ const [agentObservation, setAgentObservation] = useState({ grantId: null, present: false });
2544
+ const [connectionObservation, setConnectionObservation] = useState({ grantId: null, connected: false });
2545
+ const agentPresent = agentObservation.grantId === grantId && agentObservation.present;
2546
+ const connected = connectionObservation.grantId === grantId && connectionObservation.connected;
2547
+ connectedRef.current = connected;
2548
+ const setAgentPresentState = useCallback((present) => {
2549
+ const owner = grantIdRef.current;
2550
+ setAgentObservation((prev) => prev.grantId === owner && prev.present === present ? prev : { grantId: owner, present });
2551
+ }, []);
2552
+ const setConnected = useCallback((value) => {
2553
+ const owner = grantIdRef.current;
2554
+ setConnectionObservation((prev) => prev.grantId === owner && prev.connected === value ? prev : { grantId: owner, connected: value });
2555
+ }, []);
2521
2556
  const lastActivityRef = useRef(Date.now());
2522
2557
  const leaveRoomRef = useRef(null);
2523
2558
  const [, setClockTick] = useState(0);
@@ -2534,7 +2569,11 @@ function useSessionLifecycle(input) {
2534
2569
  refreshBaselineCapacityRef.current = null;
2535
2570
  attemptRef.current = 0;
2536
2571
  setAttempt(0);
2537
- setRecovery(userEndedRef.current ? { kind: "ended", reason: "user" } : { kind: "connected" });
2572
+ readinessRef.current = null;
2573
+ readyGrantRef.current = null;
2574
+ agentWaitRef.current = null;
2575
+ retiredGrantRef.current = null;
2576
+ setRecovery(userEndedRef.current ? { kind: "ended", reason: "user" } : readinessFailureRef.current ? { kind: "ended", reason: "error", code: readinessFailureRef.current } : { kind: "connected" });
2538
2577
  setConnected(false);
2539
2578
  setAgentPresentState(false);
2540
2579
  lastActivityRef.current = Date.now();
@@ -2543,26 +2582,33 @@ function useSessionLifecycle(input) {
2543
2582
  if (active) return;
2544
2583
  userEndedRef.current = false;
2545
2584
  setUserEnded(false);
2585
+ readinessFailureRef.current = null;
2586
+ setReadinessFailed(false);
2546
2587
  reset();
2547
2588
  }, [active, reset]);
2548
2589
  const markActivity = useCallback(() => {
2590
+ if (grantId === null || grantIdRef.current !== grantId) return;
2549
2591
  lastActivityRef.current = Date.now();
2550
2592
  setClockTick((value) => value + 1);
2551
- }, []);
2593
+ }, [grantId]);
2552
2594
  const stayConnected = useCallback(() => {
2595
+ if (grantId === null || grantIdRef.current !== grantId) return;
2553
2596
  if (!connectedRef.current) return;
2554
2597
  lastActivityRef.current = Date.now();
2555
2598
  setClockTick((value) => value + 1);
2556
- }, []);
2599
+ }, [grantId]);
2557
2600
  const setAgentPresent = useCallback((present) => {
2558
- setAgentPresentState((prev) => {
2559
- if (present && !prev) lastActivityRef.current = Date.now();
2560
- return present;
2601
+ if (grantId === null || grantIdRef.current !== grantId) return;
2602
+ if (userEndedRef.current || readinessFailureRef.current || retiredGrantRef.current !== null && retiredGrantRef.current === grantIdRef.current) return;
2603
+ setAgentObservation((prev) => {
2604
+ if (present && (prev.grantId !== grantId || !prev.present)) lastActivityRef.current = Date.now();
2605
+ return prev.grantId === grantId && prev.present === present ? prev : { grantId, present };
2561
2606
  });
2562
- }, []);
2607
+ }, [grantId]);
2563
2608
  const registerLeaveRoom = useCallback((leave) => {
2609
+ if (grantId === null || grantIdRef.current !== grantId) return;
2564
2610
  leaveRoomRef.current = leave;
2565
- }, []);
2611
+ }, [grantId]);
2566
2612
  const endIdle = useCallback(() => {
2567
2613
  if (!connectedRef.current) return;
2568
2614
  clearTimer();
@@ -2574,24 +2620,25 @@ function useSessionLifecycle(input) {
2574
2620
  leaveRoomRef.current?.();
2575
2621
  }, [clearTimer]);
2576
2622
  const onConnected = useCallback(() => {
2577
- if (userEndedRef.current) return;
2623
+ if (grantId === null || grantIdRef.current !== grantId) return;
2624
+ if (userEndedRef.current || readinessFailureRef.current || retiredGrantRef.current !== null && retiredGrantRef.current === grantIdRef.current) return;
2578
2625
  clearTimer();
2579
2626
  connectedRef.current = true;
2580
2627
  manualReconnectPendingRef.current = false;
2581
2628
  refreshBaselineCapacityRef.current = null;
2582
2629
  setConnected(true);
2583
- attemptRef.current = 0;
2584
- setAttempt(0);
2630
+ if (readinessRef.current) readinessRef.current.sawTransport = true;
2585
2631
  setRecovery({ kind: "connected" });
2586
2632
  lastActivityRef.current = Date.now();
2587
- }, [clearTimer]);
2633
+ }, [clearTimer, grantId]);
2588
2634
  const onDisconnected = useCallback(
2589
2635
  (reason) => {
2590
- if (!active || userEndedRef.current) return;
2636
+ if (grantId === null || grantIdRef.current !== grantId) return;
2637
+ if (!active || userEndedRef.current || readinessFailureRef.current) return;
2591
2638
  const action = disconnectAction(reason, connectedRef.current);
2592
2639
  if (action === "noop") return;
2593
2640
  if (action === "reset") {
2594
- if (recoveryRef.current.kind === "refreshing") return;
2641
+ if (recoveryRef.current.kind === "refreshing" || recoveryRef.current.kind === "reconnecting") return;
2595
2642
  reset();
2596
2643
  return;
2597
2644
  }
@@ -2608,11 +2655,12 @@ function useSessionLifecycle(input) {
2608
2655
  refreshBaselineCapacityRef.current = null;
2609
2656
  setRecovery({ kind: "reconnecting", attempt: attemptRef.current });
2610
2657
  },
2611
- [active, reset]
2658
+ [active, reset, grantId]
2612
2659
  );
2613
2660
  const onConnectionError = useCallback(
2614
2661
  (error) => {
2615
- if (!active || userEndedRef.current || !isRecoverableConnectionError(error)) return;
2662
+ if (grantId === null || grantIdRef.current !== grantId) return;
2663
+ if (!active || userEndedRef.current || readinessFailureRef.current || !isRecoverableConnectionError(error)) return;
2616
2664
  connectedRef.current = false;
2617
2665
  setConnected(false);
2618
2666
  setAgentPresentState(false);
@@ -2623,7 +2671,7 @@ function useSessionLifecycle(input) {
2623
2671
  return { kind: "reconnecting", attempt: attemptRef.current };
2624
2672
  });
2625
2673
  },
2626
- [active]
2674
+ [active, grantId]
2627
2675
  );
2628
2676
  useEffect(() => {
2629
2677
  if (capacity.kind === "error" && recovery.kind === "connected") manualReconnectPendingRef.current = false;
@@ -2633,11 +2681,12 @@ function useSessionLifecycle(input) {
2633
2681
  const baseline = refreshBaselineCapacityRef.current;
2634
2682
  if (baseline?.kind === "error" && baseline.error === capacity.error) return;
2635
2683
  refreshBaselineCapacityRef.current = null;
2636
- setRecovery({ kind: "reconnecting", attempt: recovery.attempt });
2684
+ setRecovery({ kind: "reconnecting", attempt: recovery.attempt, ...recovery.reason ? { reason: recovery.reason } : {} });
2637
2685
  }, [capacity, recovery]);
2638
2686
  const onConnectionStateChange = useCallback(
2639
2687
  (state) => {
2640
- if (!active || userEndedRef.current) return;
2688
+ if (grantId === null || grantIdRef.current !== grantId) return;
2689
+ if (!active || userEndedRef.current || readinessFailureRef.current) return;
2641
2690
  if (state === "connected") {
2642
2691
  onConnected();
2643
2692
  return;
@@ -2651,14 +2700,78 @@ function useSessionLifecycle(input) {
2651
2700
  }
2652
2701
  }
2653
2702
  },
2654
- [active, onConnected]
2703
+ [active, onConnected, grantId]
2655
2704
  );
2705
+ useEffect(() => {
2706
+ if (!active || userEnded || readinessFailed || !connected || !agentPresent || !grantState.grant) return;
2707
+ readyGrantRef.current = grantState.grant.session_id;
2708
+ readinessRef.current = null;
2709
+ agentWaitRef.current = null;
2710
+ attemptRef.current = 0;
2711
+ setAttempt(0);
2712
+ }, [active, userEnded, readinessFailed, connected, agentPresent, grantState.grant]);
2713
+ const failReadiness = useCallback((code) => {
2714
+ if (userEndedRef.current || readinessFailureRef.current) return;
2715
+ readinessFailureRef.current = code;
2716
+ clearTimer();
2717
+ connectedRef.current = false;
2718
+ manualReconnectPendingRef.current = false;
2719
+ refreshBaselineCapacityRef.current = null;
2720
+ const ended = { kind: "ended", reason: "error", code };
2721
+ recoveryRef.current = ended;
2722
+ setRecovery(ended);
2723
+ setConnected(false);
2724
+ setAgentPresentState(false);
2725
+ releaseRef.current("disconnected");
2726
+ setReadinessFailed(true);
2727
+ leaveRoomRef.current?.();
2728
+ }, [clearTimer]);
2729
+ useEffect(() => {
2730
+ if (!active || userEnded || readinessFailed) return;
2731
+ if (recovery.kind === "ended" || recovery.kind === "failed") return;
2732
+ if (grantState.grant && readyGrantRef.current === grantState.grant.session_id) return;
2733
+ if (!readinessRef.current && grantState.grant) {
2734
+ readinessRef.current = { startedAt: Date.now(), sawTransport: connected };
2735
+ }
2736
+ const budget = readinessRef.current;
2737
+ if (!budget) return;
2738
+ const timer = window.setTimeout(() => {
2739
+ if (readinessRef.current !== budget) return;
2740
+ failReadiness(budget.sawTransport ? "agent_timeout" : "connection_timeout");
2741
+ }, Math.max(0, budget.startedAt + readyTimeoutMs - Date.now()));
2742
+ return () => window.clearTimeout(timer);
2743
+ }, [active, userEnded, readinessFailed, connected, agentPresent, grantState.grant, recovery.kind, readyTimeoutMs, failReadiness]);
2744
+ useEffect(() => {
2745
+ const sessionId = grantState.grant?.session_id;
2746
+ if (!active || userEnded || readinessFailed || !sessionId || readyGrantRef.current === sessionId || agentPresent) return;
2747
+ if (recovery.kind === "reconnecting" || recovery.kind === "failed" || recovery.kind === "ended") return;
2748
+ if (agentWaitRef.current?.sessionId !== sessionId) {
2749
+ if (!connected) return;
2750
+ agentWaitRef.current = { sessionId, startedAt: Date.now() };
2751
+ }
2752
+ const wait = agentWaitRef.current;
2753
+ if (connectWatchdogMs <= 0) return;
2754
+ const timer = window.setTimeout(() => {
2755
+ if (agentWaitRef.current !== wait || readinessFailureRef.current || userEndedRef.current) return;
2756
+ retiredGrantRef.current = sessionId;
2757
+ connectedRef.current = false;
2758
+ setConnected(false);
2759
+ setAgentPresentState(false);
2760
+ const next = { kind: "reconnecting", attempt: attemptRef.current, reason: "agent_timeout" };
2761
+ recoveryRef.current = next;
2762
+ setRecovery(next);
2763
+ releaseRef.current("disconnected");
2764
+ leaveRoomRef.current?.();
2765
+ }, Math.max(0, wait.startedAt + connectWatchdogMs - Date.now()));
2766
+ return () => window.clearTimeout(timer);
2767
+ }, [active, userEnded, readinessFailed, connected, agentPresent, grantState.grant, recovery.kind, connectWatchdogMs]);
2656
2768
  useEffect(() => {
2657
2769
  if (!active || connected || connectWatchdogMs <= 0) return;
2658
2770
  if (grantState.status !== "ready" || !grantState.grant) return;
2659
2771
  if (recovery.kind === "failed" || recovery.kind === "ended") return;
2660
2772
  if (recovery.kind === "in-place-reconnecting") return;
2661
2773
  const timer = window.setTimeout(() => {
2774
+ if (readinessFailureRef.current || userEndedRef.current) return;
2662
2775
  releaseRef.current("disconnected");
2663
2776
  setRecovery({ kind: "reconnecting", attempt: attemptRef.current });
2664
2777
  }, connectWatchdogMs);
@@ -2668,6 +2781,10 @@ function useSessionLifecycle(input) {
2668
2781
  if (!active || !needsFreshGrant(recovery)) return;
2669
2782
  const step2 = retryStep(attemptRef.current, reconnectPolicyRef.current);
2670
2783
  if (step2.kind === "give-up") {
2784
+ if (readinessRef.current) {
2785
+ failReadiness(readinessRef.current.sawTransport ? "agent_timeout" : "connection_timeout");
2786
+ return;
2787
+ }
2671
2788
  manualReconnectPendingRef.current = false;
2672
2789
  refreshBaselineCapacityRef.current = null;
2673
2790
  releaseRef.current("disconnected");
@@ -2676,15 +2793,16 @@ function useSessionLifecycle(input) {
2676
2793
  }
2677
2794
  timerRef.current = window.setTimeout(() => {
2678
2795
  timerRef.current = null;
2796
+ if (readinessFailureRef.current || userEndedRef.current) return;
2679
2797
  attemptRef.current = step2.attempt;
2680
2798
  setAttempt(step2.attempt);
2681
2799
  refreshBaselineCapacityRef.current = capacityRef.current;
2682
2800
  releaseRef.current("superseded");
2683
- setRecovery({ kind: "refreshing", attempt: step2.attempt });
2801
+ setRecovery({ kind: "refreshing", attempt: step2.attempt, ...recovery.reason ? { reason: recovery.reason } : {} });
2684
2802
  refreshRef.current();
2685
2803
  }, step2.delayMs);
2686
2804
  return clearTimer;
2687
- }, [recovery.kind, active, attempt, clearTimer]);
2805
+ }, [recovery.kind, active, attempt, clearTimer, failReadiness]);
2688
2806
  const end = useCallback(() => {
2689
2807
  if (!active || userEndedRef.current || phaseRef.current.kind === "ended") return;
2690
2808
  userEndedRef.current = true;
@@ -2701,6 +2819,13 @@ function useSessionLifecycle(input) {
2701
2819
  }, [active, clearTimer]);
2702
2820
  const reconnect = useCallback(() => {
2703
2821
  if (!active) return;
2822
+ if (readinessFailureRef.current) {
2823
+ readinessFailureRef.current = null;
2824
+ setReadinessFailed(false);
2825
+ reset();
2826
+ manualReconnectPendingRef.current = true;
2827
+ return;
2828
+ }
2704
2829
  if (userEndedRef.current) {
2705
2830
  userEndedRef.current = false;
2706
2831
  setUserEnded(false);
@@ -2711,6 +2836,12 @@ function useSessionLifecycle(input) {
2711
2836
  if (manualReconnectPendingRef.current || recovery.kind === "in-place-reconnecting") return;
2712
2837
  manualReconnectPendingRef.current = true;
2713
2838
  clearTimer();
2839
+ readinessRef.current = null;
2840
+ agentWaitRef.current = null;
2841
+ readyGrantRef.current = null;
2842
+ connectedRef.current = false;
2843
+ setConnected(false);
2844
+ setAgentPresentState(false);
2714
2845
  attemptRef.current = 0;
2715
2846
  setAttempt(0);
2716
2847
  refreshBaselineCapacityRef.current = capacityRef.current;
@@ -2830,6 +2961,7 @@ function SessionLifecycleRoomBridge({
2830
2961
  const assistant = useVoiceAssistant();
2831
2962
  const transcriptions = useTranscriptions();
2832
2963
  const room = useRoomContext();
2964
+ const roomMatchesGrant = lifecycle.grant === void 0 || lifecycle.grant !== null && room.name === lifecycle.grant.room_name;
2833
2965
  useCallMedia(room, {
2834
2966
  setMicrophoneFacts,
2835
2967
  setAudioPlayback,
@@ -2983,11 +3115,11 @@ function SessionLifecycleRoomBridge({
2983
3115
  detailsEnabled ? video?.publication : void 0
2984
3116
  ]);
2985
3117
  useEffect(() => {
2986
- onConnectionStateChange(connectionState);
2987
- }, [connectionState, onConnectionStateChange]);
3118
+ if (roomMatchesGrant) onConnectionStateChange(connectionState);
3119
+ }, [connectionState, onConnectionStateChange, roomMatchesGrant]);
2988
3120
  useEffect(() => {
2989
- setAgentPresent(agentPresent);
2990
- }, [agentPresent, setAgentPresent]);
3121
+ if (roomMatchesGrant) setAgentPresent(agentPresent);
3122
+ }, [agentPresent, setAgentPresent, roomMatchesGrant]);
2991
3123
  useEffect(() => {
2992
3124
  const active = isCallActivity({
2993
3125
  assistantState,
@@ -3695,4 +3827,4 @@ function createProxyClient(options) {
3695
3827
  };
3696
3828
  }
3697
3829
 
3698
- export { AdaptivePlayoutController, 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, RECONNECT_BACKOFF_MS, RealtimeAvatarLiveKitRoom, SessionLifecycleRoomBridge, capacityErrorFromBusy, capacityStateFromGrant, createProxyClient, isNativeLiveTrackSubscribed, knownBehaviorStates, mapTurnState, readInboundRtp, sessionBehaviorSchema, sessionClipSchema, splitCallTranscript, useAvatarAdaptivePlayoutDelay, useAvatarCamera, useAvatarPlayoutDelay, useAvatarQualityGovernor, useCallTranscript, useLiveKitAvatarGrant, useLiveTrackProducing, useMicLease, useRealtimeAvatarAudioSession, useRealtimeSession, useReleaseMicLeaseOnTrackEnded, useSessionLifecycle };
3830
+ export { AdaptivePlayoutController, 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_READY_TIMEOUT_SECONDS, DEFAULT_TURN_TIMEOUT_SECONDS, MAX_RECONNECT_ATTEMPTS, MAX_SESSION_INSTRUCTIONS_CHARS, RECONNECT_BACKOFF_MS, RealtimeAvatarLiveKitRoom, SessionLifecycleRoomBridge, capacityErrorFromBusy, capacityStateFromGrant, createProxyClient, isNativeLiveTrackSubscribed, knownBehaviorStates, mapTurnState, readInboundRtp, sessionBehaviorSchema, sessionClipSchema, splitCallTranscript, useAvatarAdaptivePlayoutDelay, useAvatarCamera, useAvatarPlayoutDelay, useAvatarQualityGovernor, useCallTranscript, useLiveKitAvatarGrant, useLiveTrackProducing, useMicLease, useRealtimeAvatarAudioSession, useRealtimeSession, useReleaseMicLeaseOnTrackEnded, useSessionLifecycle };
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-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';
2
+ import { ak as SessionLifecycleRoomBridgeProps, h as AvatarSessionClient, A as AvatarVideoFit, aS as CallMicrophone, aT as CallAudioPlayback, aU as CallMicrophoneProblem } from './proxy-client-DW_EOvmE.js';
3
+ export { a as AdaptivePlayoutController, b as AdaptivePlayoutDecision, c as AdaptivePlayoutOptions, d as AdaptivePlayoutSample, e as ApproachingEndEvent, f as ApproachingEndReason, g as AvatarConnectionDetails, aV as AvatarVideoSurface, aW 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_READY_TIMEOUT_SECONDS, u as DEFAULT_TURN_TIMEOUT_SECONDS, v as DeclaredInputSource, E as EndReason, w as EndedEvent, x as ExtendResult, F as FishTtsModel, y as FreezeReadingFn, G as Governor, z as GovernorAction, H as GovernorConfig, I as GovernorSignal, J as GovernorState, K as GraceWindowClosedEvent, M as GraceWindowOpenEvent, N as GraceWindowState, O as IdleWarningEvent, P as InboundRtpCursor, Q as InboundRtpReading, R as KnownBehaviorState, S as LLMProvider, T as LLMSelection, U as LiveKitAvatarGrantState, V as LiveKitAvatarGrantStatus, W as LiveKitCapacityState, X as LiveKitConnectionStatus, Y as LiveKitSessionRequest, Z as LiveKitSessionStartResult, aX as LivePlaybackKeeper, _ as MAX_RECONNECT_ATTEMPTS, $ as MAX_SESSION_INSTRUCTIONS_CHARS, aY as MIC_LEASE_ENDED_TIMEOUT_MS, aZ as MicLease, a_ as NETWORK_QUALITY_POLICY, a$ as NetworkQualityStatus, b0 as PlayableVideoElement, a0 as ProxyClientOptions, a1 as QualityCap, a2 as RECONNECT_BACKOFF_MS, b1 as RealtimeAvatarCapacityError, b2 as RealtimeAvatarLiveKitRoom, b3 as RealtimeAvatarLiveKitRoomProps, a3 as RealtimeAvatarRequestOptions, a4 as RealtimeSessionApi, a5 as RealtimeSessionMedia, a6 as RealtimeSessionRoomSinks, a7 as ReconnectPolicy, a8 as ReconnectingEvent, a9 as RecoveryState, aa as RetryStep, ab as SendTurnOptions, ac as SessionBehavior, ad as SessionClip, ae as SessionClocks, af as SessionEndReason, ag as SessionLifecycleApi, ah as SessionLifecyclePhase, ai as SessionLifecyclePhaseKind, aj as SessionLifecycleRoomBridge, al as SessionReadinessFailure, am as SurfaceLayers, an as TranscriptSender, ao as TranscriptSenderOptions, ap as TurnState, aq as TurnTimeoutEvent, ar as UseAvatarQualityGovernorInput, as as UseLiveKitAvatarGrantInput, at as UseRealtimeSessionInput, au as UseSessionLifecycleInput, av as VoiceSpec, aw as VoiceSpecInput, ax as capacityErrorFromBusy, ay as capacityStateFromGrant, az as createProxyClient, aB as knownBehaviorStates, aC as mapTurnState, aD as readInboundRtp, aE as sessionBehaviorSchema, aF as sessionClipSchema, b4 as shouldReplayPendingTurn, aG as splitCallTranscript, aH as useAvatarAdaptivePlayoutDelay, aI as useAvatarCamera, aJ as useAvatarPlayoutDelay, aK as useAvatarQualityGovernor, aL as useCallTranscript, aM as useLiveKitAvatarGrant, aO as useMicLease, aP as useRealtimeSession, aQ as useReleaseMicLeaseOnTrackEnded, aR as useSessionLifecycle } from './proxy-client-DW_EOvmE.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';