Skip to content

Commit 667d556

Browse files
committed
feat: add / remove events from agents sdk abstractions
1 parent 1a27a6c commit 667d556

File tree

3 files changed

+44
-11
lines changed

3 files changed

+44
-11
lines changed

packages/react/src/hooks/useAgent.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,15 +47,13 @@ export type AgentState = 'disconnected' | 'connecting' | 'failed' | AgentSdkStat
4747
export enum AgentEvent {
4848
CameraChanged = 'cameraChanged',
4949
MicrophoneChanged = 'microphoneChanged',
50-
AttributesChanged = 'attributesChanged',
5150
StateChanged = 'stateChanged',
5251
}
5352

5453
/** @public */
5554
export type AgentCallbacks = {
5655
[AgentEvent.CameraChanged]: (newTrack: TrackReference | null) => void;
5756
[AgentEvent.MicrophoneChanged]: (newTrack: TrackReference | null) => void;
58-
[AgentEvent.AttributesChanged]: (newAttributes: Record<string, string>) => void;
5957
[AgentEvent.StateChanged]: (newAgentState: AgentState) => void;
6058
};
6159

@@ -317,7 +315,6 @@ export function useAgent(session?: SessionStub): UseAgentReturn {
317315

318316
const handleAttributesChanged = (attributes: UseAgentReturn['attributes']) => {
319317
setAgentParticipantAttributes(attributes);
320-
emitter.emit(AgentEvent.AttributesChanged, attributes);
321318
};
322319

323320
agentParticipant.on(ParticipantEvent.AttributesChanged, handleAttributesChanged);

packages/react/src/hooks/useSession.ts

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,24 @@ import { useLocalParticipant } from './useLocalParticipant';
2121
/** @public */
2222
export enum SessionEvent {
2323
ConnectionStateChanged = 'connectionStateChanged',
24-
MediaDevicesError = 'MediaDevicesError',
24+
/**
25+
* Emits when an error is encountered while attempting to create a track.
26+
* Use MediaDeviceFailure.getFailure(error) to get the reason of failure.
27+
* args: (error: Error, kind: MediaDeviceKind)
28+
*/
29+
MediaDevicesError = 'mediaDevicesError',
30+
/**
31+
* Emits when an error is received while decrypting frame received frame information.
32+
* args: (error: Error)
33+
*/
34+
EncryptionError = 'encryptionError',
2535
}
2636

2737
/** @public */
2838
export type SessionCallbacks = {
2939
[SessionEvent.ConnectionStateChanged]: (newAgentConnectionState: ConnectionState) => void;
3040
[SessionEvent.MediaDevicesError]: (error: Error) => void;
41+
[SessionEvent.EncryptionError]: (error: Error) => void;
3142
};
3243

3344
/** @public */
@@ -215,6 +226,17 @@ export function useSession(
215226
};
216227
}, [room, emitter]);
217228

229+
useEffect(() => {
230+
const handleEncryptionError = async (error: Error) => {
231+
emitter.emit(SessionEvent.EncryptionError, error);
232+
};
233+
234+
room.on(RoomEvent.EncryptionError, handleEncryptionError);
235+
return () => {
236+
room.off(RoomEvent.EncryptionError, handleEncryptionError);
237+
};
238+
}, [room, emitter]);
239+
218240
const { localParticipant } = useLocalParticipant({ room });
219241
const cameraPublication = localParticipant.getTrackPublication(Track.Source.Camera);
220242
const localCamera = useMemo(() => {

packages/react/src/hooks/useSessionMessages.ts

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
import { useMemo } from 'react';
2-
// import type TypedEventEmitter from 'typed-emitter';
1+
import { useEffect, useMemo, useRef } from 'react';
2+
import type TypedEventEmitter from 'typed-emitter';
33
import { SendTextOptions } from 'livekit-client';
4-
// import { EventEmitter } from "events";
4+
import { EventEmitter } from "events";
55
import {
66
ReceivedMessage,
77
ReceivedChatMessage,
@@ -25,10 +25,9 @@ export type UseSessionMessagesReturn = {
2525

2626
send: (message: string, options?: SendTextOptions) => Promise<ReceivedChatMessage>;
2727

28-
// FIXME: does there need to be a way to subscribe to individual messages?
29-
// internal: {
30-
// emitter: TypedEventEmitter<MessagesCallbacks>;
31-
// };
28+
internal: {
29+
emitter: TypedEventEmitter<MessagesCallbacks>;
30+
};
3231
};
3332

3433
/** @public */
@@ -46,6 +45,8 @@ export type MessagesCallbacks = {
4645
export function useSessionMessages(session?: UseSessionReturn): UseSessionMessagesReturn {
4746
const { room } = useEnsureSession(session);
4847

48+
const emitter = useMemo(() => new EventEmitter() as TypedEventEmitter<MessagesCallbacks>, []);
49+
4950
const agent = useAgent(session);
5051

5152
const transcriptions: Array<TextStreamData> = useTranscriptions({ room });
@@ -105,11 +106,24 @@ export function useSessionMessages(session?: UseSessionReturn): UseSessionMessag
105106
return merged.sort((a, b) => a.timestamp - b.timestamp);
106107
}, [transcriptionMessages, chat.chatMessages]);
107108

109+
const previouslyReceivedMessageIdsRef = useRef(new Set());
110+
useEffect(() => {
111+
for (const message of receivedMessages) {
112+
if (previouslyReceivedMessageIdsRef.current.has(message.id)) {
113+
continue;
114+
}
115+
116+
previouslyReceivedMessageIdsRef.current.add(message.id);
117+
emitter.emit(MessagesEvent.MessageReceived, message);
118+
}
119+
}, [receivedMessages]);
120+
108121
return useMemo(
109122
() => ({
110123
messages: receivedMessages,
111124
send: chat.send,
112125
isSending: chat.isSending,
126+
internal: { emitter },
113127
}),
114128
[receivedMessages, chat.send, chat.isSending],
115129
);

0 commit comments

Comments
 (0)