ITADN

Agent state management issues in `useAgent` hook

#1227Closedfrankfarzan 创建于 2025-10-27
F
frankfarzancommented
### Select which package(s) are affected \@livekit/components-react ### Describe the bug Hi @1egoman, I'm playing around with Agent SDK changes (from #1207) and observed some issues with state tracking/reporting in `useAgent` (Overall I like the changes though). ## Summary The `useAgent` hook has two bugs that cause incorrect state reporting when agents disconnect or are missing: 1. **Agent disconnections mid-conversation don't trigger `failed` state** - Agents that disconnect after successful connection don't set failure reasons 2. **`listening` state can occur with no agent participant** - State shows `'listening'` when `agent.internal.agentParticipant` is `null` --- ## Bug 1: Missing failure state on agent disconnection ### Problem When an agent successfully connects initially but then disconnects mid-conversation, the state doesn't transition to `failed` and no failure reasons are provided. ### Expected vs Actual **Expected:** - `agent.state` should be `'failed'` - `agent.failureReasons` should be set **Actual:** - `agent.state` remains as `'listening'` - No failure reasons are set ### Root Cause It seems the failure detection in `useAgentTimeoutIdStore` (lines 192-204) only works during initial connection timeout. Once the agent successfully connects, the timeout completes and there's no mechanism to detect subsequent disconnections. **File**: `components-js/packages/react/src/hooks/useAgent.ts` - Lines 192-204: Timeout logic - Lines 436-446: Timeout lifecycle ### Reproduction ```typescript // Agent process is started. await session.start(); // Agent connects and works fine // ... // Kill the agent process // Expected: state = 'failed', failureReasons = ['Agent disconnected'] // Actual: state = 'connecting' (or previous), failureReasons = null ``` --- ## Bug 2: Inconsistent `listening` state ### Problem `agent.state` can be `'listening'` while `agent.internal.agentParticipant` is `null`, indicating the agent is listening when no agent actually exists. ### Expected vs Actual **Expected:** - State reflects actual agent presence - `'listening'` state should only occur when an agent participant exists **Actual:** ```typescript agent.state === "listening"; agent.internal.agentParticipant === null; // Inconsistent! ``` ### Root Cause It seems the state calculation (lines 394-425) sets state to `'listening'` based solely on `localMicTrack`: ```typescript if (localMicTrack) { state = "listening"; bufferingSpeachLocally = true; } ``` This happens when the local microphone is published (buffering audio) but no agent has joined the room yet. **File**: `components-js/packages/react/src/hooks/useAgent.ts` - Lines 408-411: State calculation - Line 453: Agent participant in internal state ### Reproduction See above. ### Logs ```shell ``` ### System Info ```shell System: OS: macOS 15.5 CPU: (10) arm64 Apple M4 Memory: 65.66 MB / 16.00 GB Shell: 5.9 - /bin/zsh Binaries: Node: 24.2.0 - /opt/homebrew/bin/node npm: 11.4.2 - /opt/homebrew/bin/npm pnpm: 10.18.3 - /opt/homebrew/bin/pnpm Watchman: 2025.05.26.00 - /opt/homebrew/bin/watchman Browsers: Chrome: 141.0.7390.123 Firefox: 143.0.1 Safari: 18.5 npmPackages: @livekit/components-core: file:vendor/livekit-components-core-0.12.10.tgz => 0.12.10 @livekit/components-react: file:vendor/livekit-components-react-2.9.15.tgz => 2.9.15 @livekit/components-styles: ^1.1.6 => 1.1.6 Using packed packages from f118da6e678c4a91be91c4dfc9b3b61eb7f64e2a (#1207) ``` ### Severity blocking an upgrade ### Additional Information _No response_
关闭于 2025-11-17 7 条评论