From a8ef4079bd9093b643ef2ac80d59446fc8f1d739 Mon Sep 17 00:00:00 2001 From: Arik Sfaradi Date: Tue, 30 Dec 2025 10:43:44 +0200 Subject: [PATCH 1/3] fix current version (#252) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 6df1288b..7b052999 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@d-id/client-sdk", "private": false, - "version": "1.1.20", + "version": "1.1.21", "type": "module", "description": "d-id client sdk", "repository": { From c66ba35670083f5d4e6dcf4224bdbdb135bd8b00 Mon Sep 17 00:00:00 2001 From: netanelben-hamo Date: Tue, 30 Dec 2025 16:47:08 +0200 Subject: [PATCH 2/3] abort stream connection when create chat failed (#251) * abort stream connection when create chat failed * fix tests * add tests * fix pr comments * remove abort checks, fetch abort automatically * fix pr comment, replace set timeout with promise.resolve --- src/api/streams/streamApi.ts | 32 +++-- .../agent-manager/connect-to-manager.test.ts | 133 ++++++++++++++++- .../agent-manager/connect-to-manager.ts | 134 +++++++++++------- src/services/agent-manager/index.ts | 13 +- src/services/chat/index.ts | 21 +-- .../streaming-manager/advanced.test.ts | 7 +- .../streaming-manager/business-flows.test.ts | 5 +- .../streaming-manager/edge-cases.test.ts | 31 +++- .../streaming-manager/factory.test.ts | 14 +- src/services/streaming-manager/factory.ts | 5 +- .../streaming-manager/webrtc-core.test.ts | 15 +- .../streaming-manager/webrtc-manager.ts | 12 +- src/types/stream/stream.ts | 16 ++- 13 files changed, 325 insertions(+), 113 deletions(-) diff --git a/src/api/streams/streamApi.ts b/src/api/streams/streamApi.ts index 0ff77646..ac244e7a 100644 --- a/src/api/streams/streamApi.ts +++ b/src/api/streams/streamApi.ts @@ -20,20 +20,28 @@ export function createStreamApi( const client = createClient(auth, `${host}/agents/${agentId}`, onError); return { - createStream(options: CreateStreamOptions) { - return client.post('/streams', options); + createStream(options: CreateStreamOptions, signal?: AbortSignal) { + return client.post('/streams', options, { signal }); }, - startConnection(streamId: string, answer: RTCSessionDescriptionInit, sessionId?: string) { - return client.post(`/streams/${streamId}/sdp`, { - session_id: sessionId, - answer, - }); + startConnection(streamId: string, answer: RTCSessionDescriptionInit, sessionId?: string, signal?: AbortSignal) { + return client.post( + `/streams/${streamId}/sdp`, + { + session_id: sessionId, + answer, + }, + { signal } + ); }, - addIceCandidate(streamId: string, candidate: IceCandidate, sessionId: string) { - return client.post(`/streams/${streamId}/ice`, { - session_id: sessionId, - ...candidate, - }); + addIceCandidate(streamId: string, candidate: IceCandidate, sessionId: string, signal?: AbortSignal) { + return client.post( + `/streams/${streamId}/ice`, + { + session_id: sessionId, + ...candidate, + }, + { signal } + ); }, sendStreamRequest(streamId: string, sessionId: string, payload: SendClipStreamPayload | SendTalkStreamPayload) { return client.post(`/streams/${streamId}`, { diff --git a/src/services/agent-manager/connect-to-manager.test.ts b/src/services/agent-manager/connect-to-manager.test.ts index 6cf2763b..bc94124d 100644 --- a/src/services/agent-manager/connect-to-manager.test.ts +++ b/src/services/agent-manager/connect-to-manager.test.ts @@ -37,10 +37,15 @@ describe('connect-to-manager', () => { let mockAnalytics: Analytics; let mockStreamingManager: any; let mockChat: any; + let mockAbortController: AbortController; + let mockAbortSignal: AbortSignal; beforeEach(() => { jest.clearAllMocks(); + mockAbortController = new AbortController(); + mockAbortSignal = mockAbortController.signal; + mockAgent = { id: 'agent-123', name: 'Test Agent', @@ -165,7 +170,8 @@ describe('connect-to-manager', () => { onVideoStateChange: expect.any(Function), onAgentActivityStateChange: expect.any(Function), }), - }) + }), + mockAbortSignal ); }); @@ -393,7 +399,8 @@ describe('connect-to-manager', () => { }, expect.not.objectContaining({ chatId: expect.anything(), - }) + }), + mockAbortSignal ); }); @@ -414,7 +421,8 @@ describe('connect-to-manager', () => { }, expect.not.objectContaining({ chatId: expect.anything(), - }) + }), + mockAbortSignal ); }); @@ -437,7 +445,8 @@ describe('connect-to-manager', () => { }), expect.not.objectContaining({ chatId: expect.anything(), - }) + }), + mockAbortSignal ); }); }); @@ -518,7 +527,7 @@ describe('connect-to-manager', () => { }, }; - await initializeStreamAndChat(expressiveAgent, mockOptions, mockAgentsApi, mockAnalytics); + const result = await initializeStreamAndChat(expressiveAgent, mockOptions, mockAgentsApi, mockAnalytics); expect(createStreamingManager).toHaveBeenCalledWith( expressiveAgent, @@ -528,8 +537,19 @@ describe('connect-to-manager', () => { }, expect.not.objectContaining({ chatId: expect.anything(), - }) + }), + undefined ); + + // Verify Streams V2 path creates chat with correct chatId format + expect(result.chat).toBeDefined(); + expect(result.chat?.id).toMatch(/^cht_/); + expect(result.chat?.id).toContain(mockStreamingManager.sessionId); + expect(result.chat?.chat_mode).toBe(ChatMode.Functional); + expect(result.chat?.agent_id).toBe(expressiveAgent.id); + + // Verify createChat is NOT called for V2 agents (chat is created internally) + expect(createChat).not.toHaveBeenCalled(); }); it('should use CreateStreamOptions for non-expressive agents', async () => { @@ -544,8 +564,107 @@ describe('connect-to-manager', () => { }), expect.not.objectContaining({ chatId: expect.anything(), - }) + }), + mockAbortSignal + ); + }); + }); + + describe('Error Handling with AbortController', () => { + it('should abort and disconnect streaming manager when error occurs during initialization', async () => { + const error = new Error('Connection failed'); + let streamingManagerRef: any; + + (createStreamingManager as jest.Mock).mockImplementationOnce((agent, streamOptions, options, signal) => { + streamingManagerRef = { + ...mockStreamingManager, + disconnect: jest.fn().mockResolvedValue(undefined), + }; + return new Promise((resolve, reject) => { + Promise.resolve().then(() => { + if (options.callbacks.onConnectionStateChange) { + options.callbacks.onConnectionStateChange(ConnectionState.Connecting); + } + reject(error); + }); + }); + }); + + (createChat as jest.Mock).mockResolvedValueOnce({ + chat: mockChat, + chatMode: ChatMode.Functional, + }); + + await expect(initializeStreamAndChat(mockAgent, mockOptions, mockAgentsApi, mockAnalytics)).rejects.toThrow( + 'Connection failed' + ); + }); + + it('should handle error when streaming manager is created but chat creation fails', async () => { + const chatError = new Error('Chat creation failed'); + const disconnectSpy = jest.fn().mockResolvedValue(undefined); + const streamingManagerWithDisconnect = { + ...mockStreamingManager, + disconnect: disconnectSpy, + }; + + // Make streaming manager succeed immediately to set streamingManagerRef + (createStreamingManager as jest.Mock).mockImplementationOnce((agent, streamOptions, options) => { + // Trigger connection state change to Connected in next microtask + Promise.resolve().then(() => { + if (options.callbacks.onConnectionStateChange) { + options.callbacks.onConnectionStateChange(ConnectionState.Connected); + } + }); + return Promise.resolve(streamingManagerWithDisconnect); + }); + + // Make chat creation fail AFTER streaming manager resolves + // The .then() callback on connectToManagerPromise sets streamingManagerRef, + // so we need connectToManager to resolve before Promise.all rejects + (createChat as jest.Mock).mockImplementationOnce(() => { + return new Promise((resolve, reject) => { + Promise.resolve().then(() => { + reject(chatError); + }); + }); + }); + + await expect(initializeStreamAndChat(mockAgent, mockOptions, mockAgentsApi, mockAnalytics)).rejects.toThrow( + 'Chat creation failed' ); + + expect(disconnectSpy).toHaveBeenCalled(); + }); + }); + + describe('Connection State Handling', () => { + it('should resolve when connection state changes to Connected before manager is ready', async () => { + let onConnectionStateChange: ((state: ConnectionState) => void) | undefined; + let managerResolved = false; + + (createStreamingManager as jest.Mock).mockImplementationOnce((agent, streamOptions, options) => { + onConnectionStateChange = options.callbacks.onConnectionStateChange; + + return new Promise(resolve => { + // Trigger connection state change to Connected BEFORE manager is created + // This should set shouldResolveOnComplete = true + if (onConnectionStateChange) { + onConnectionStateChange(ConnectionState.Connected); + } + + // Resolve the manager in the next microtask + Promise.resolve().then(() => { + managerResolved = true; + resolve(mockStreamingManager); + }); + }); + }); + + const result = await initializeStreamAndChat(mockAgent, mockOptions, mockAgentsApi, mockAnalytics); + + expect(managerResolved).toBe(true); + expect(result.streamingManager).toBe(mockStreamingManager); }); }); }); diff --git a/src/services/agent-manager/connect-to-manager.ts b/src/services/agent-manager/connect-to-manager.ts index a9ee16e0..2e443452 100644 --- a/src/services/agent-manager/connect-to-manager.ts +++ b/src/services/agent-manager/connect-to-manager.ts @@ -168,7 +168,8 @@ type ConnectToManagerOptions = AgentManagerOptions & { function connectToManager( agent: Agent, options: ConnectToManagerOptions, - analytics: Analytics + analytics: Analytics, + signal?: AbortSignal ): Promise> { latencyTimestampTracker.reset(); @@ -177,53 +178,58 @@ function connectToManager( let streamingManager: StreamingManager; let shouldResolveOnComplete = false; - streamingManager = await createStreamingManager(agent, getAgentStreamOptions(agent, options), { - ...options, - analytics, - callbacks: { - ...options.callbacks, - onConnectionStateChange: state => { - options.callbacks.onConnectionStateChange?.(state); - - if (state === ConnectionState.Connected) { - // If manager is ready, resolve immediately - // Otherwise, mark to resolve after manager is created - if (streamingManager) { - resolve(streamingManager); + streamingManager = await createStreamingManager( + agent, + getAgentStreamOptions(agent, options), + { + ...options, + analytics, + callbacks: { + ...options.callbacks, + onConnectionStateChange: state => { + options.callbacks.onConnectionStateChange?.(state); + + if (state === ConnectionState.Connected) { + // If manager is ready, resolve immediately + // Otherwise, mark to resolve after manager is created + if (streamingManager) { + resolve(streamingManager); + } else { + shouldResolveOnComplete = true; + } + } + }, + onVideoStateChange: (state: StreamingState, statsReport?: any) => { + options.callbacks.onVideoStateChange?.(state); + + trackVideoStateChangeAnalytics( + state, + agent, + statsReport, + analytics, + streamingManager.streamType + ); + }, + onAgentActivityStateChange: (state: AgentActivityState) => { + options.callbacks.onAgentActivityStateChange?.(state); + + if (state === AgentActivityState.Talking) { + interruptTimestampTracker.update(); } else { - shouldResolveOnComplete = true; + interruptTimestampTracker.reset(); } - } - }, - onVideoStateChange: (state: StreamingState, statsReport?: any) => { - options.callbacks.onVideoStateChange?.(state); - - trackVideoStateChangeAnalytics( - state, - agent, - statsReport, - analytics, - streamingManager.streamType - ); - }, - onAgentActivityStateChange: (state: AgentActivityState) => { - options.callbacks.onAgentActivityStateChange?.(state); - - if (state === AgentActivityState.Talking) { - interruptTimestampTracker.update(); - } else { - interruptTimestampTracker.reset(); - } - - trackAgentActivityAnalytics( - state === AgentActivityState.Talking ? StreamingState.Start : StreamingState.Stop, - agent, - analytics, - streamingManager.streamType - ); + + trackAgentActivityAnalytics( + state === AgentActivityState.Talking ? StreamingState.Start : StreamingState.Stop, + agent, + analytics, + streamingManager.streamType + ); + }, }, }, - }); + signal + ); if (shouldResolveOnComplete) { resolve(streamingManager); @@ -263,17 +269,35 @@ export async function initializeStreamAndChat( }; return { chatResult, streamingManager }; } else { - const createChatPromise = createChat( - agent, - agentsApi, - analytics, - options.mode, - options.persistentChat, - chat - ); - const connectToManagerPromise = connectToManager(agent, options, analytics); - const [chatResult, streamingManager] = await Promise.all([createChatPromise, connectToManagerPromise]); - return { chatResult, streamingManager }; + const abortController = new AbortController(); + const signal = abortController.signal; + let streamingManagerRef: StreamingManager | undefined; + + try { + const createChatPromise = createChat( + agent, + agentsApi, + analytics, + options.mode, + options.persistentChat, + chat + ); + const connectToManagerPromise = connectToManager(agent, options, analytics, signal).then(manager => { + streamingManagerRef = manager; + return manager; + }); + + const [chatResult, streamingManager] = await Promise.all([createChatPromise, connectToManagerPromise]); + return { chatResult, streamingManager }; + } catch (error) { + abortController.abort(); + + if (streamingManagerRef) { + await streamingManagerRef.disconnect().catch(() => {}); + } + + throw error; + } } }; diff --git a/src/services/agent-manager/index.ts b/src/services/agent-manager/index.ts index c4c2090c..8fbd1989 100644 --- a/src/services/agent-manager/index.ts +++ b/src/services/agent-manager/index.ts @@ -122,8 +122,8 @@ export async function createAgentManager(agent: string, options: AgentManagerOpt ); const initPromise = retryOperation( - () => { - return initializeStreamAndChat( + () => + initializeStreamAndChat( agentEntity, { ...options, @@ -132,14 +132,15 @@ export async function createAgentManager(agent: string, options: AgentManagerOpt agentsApi, analytics, items.chat - ); - }, + ), { limit: 3, timeout: CONNECTION_RETRY_TIMEOUT_MS, timeoutErrorMessage: 'Timeout initializing the stream', - // Retry on all errors except for connection errors and rate limit errors, these are already handled in client level. - shouldRetryFn: (error: any) => error?.message !== 'Could not connect' && error.status !== 429, + shouldRetryFn: (error: any) => + error?.message !== 'Could not connect' && + error.status !== 429 && + error?.message !== 'InsufficientCreditsError', delayMs: 1000, } ).catch(e => { diff --git a/src/services/chat/index.ts b/src/services/chat/index.ts index 82f75687..94a192e1 100644 --- a/src/services/chat/index.ts +++ b/src/services/chat/index.ts @@ -29,16 +29,19 @@ export async function createChat( return { chat, chatMode: chat?.chat_mode ?? chatMode }; } catch (error: any) { - try { - const parsedError = JSON.parse(error.message); - - if (parsedError?.kind === 'InsufficientCreditsError') { - throw new Error('InsufficientCreditsError'); - } - } catch (e) { - console.error('Error parsing the error message:', e); + const errorKind = getErrorKind(error); + if (errorKind === 'InsufficientCreditsError') { + throw new Error('InsufficientCreditsError'); } - throw new Error('Cannot create new chat'); } } + +const getErrorKind = (error: Error) => { + try { + const parsedError = JSON.parse(error.message); + return parsedError?.kind; + } catch (e) { + return 'UnknownError'; + } +}; diff --git a/src/services/streaming-manager/advanced.test.ts b/src/services/streaming-manager/advanced.test.ts index dd783c28..a4db8e9a 100644 --- a/src/services/streaming-manager/advanced.test.ts +++ b/src/services/streaming-manager/advanced.test.ts @@ -451,7 +451,12 @@ describe('Streaming Manager Advanced', () => { mockPC.onicecandidate(mockEvent); - expect(mockApi.addIceCandidate).toHaveBeenCalledWith('streamId', { candidate: null }, 'sessionId'); + expect(mockApi.addIceCandidate).toHaveBeenCalledWith( + 'streamId', + { candidate: null }, + 'sessionId', + undefined + ); }); it('should handle agent activity state changes for fluent streams', async () => { diff --git a/src/services/streaming-manager/business-flows.test.ts b/src/services/streaming-manager/business-flows.test.ts index 2d283da8..0caf2f31 100644 --- a/src/services/streaming-manager/business-flows.test.ts +++ b/src/services/streaming-manager/business-flows.test.ts @@ -37,11 +37,12 @@ describe('Streaming Manager Business Flows', () => { const manager = await createStreamingManager(agentId, agent, options); // Verify connection API calls were made in correct order - expect(mockApi.createStream).toHaveBeenCalledWith(agent); + expect(mockApi.createStream).toHaveBeenCalledWith(agent, undefined); expect(mockApi.startConnection).toHaveBeenCalledWith( 'streamId', expect.objectContaining({ type: 'answer' }), - 'sessionId' + 'sessionId', + undefined ); // Verify stream creation callback diff --git a/src/services/streaming-manager/edge-cases.test.ts b/src/services/streaming-manager/edge-cases.test.ts index 82d2bde3..633cb8f1 100644 --- a/src/services/streaming-manager/edge-cases.test.ts +++ b/src/services/streaming-manager/edge-cases.test.ts @@ -147,11 +147,17 @@ describe('Streaming Manager Edge Cases', () => { sdpMid: fullCandidate.sdpMid, sdpMLineIndex: fullCandidate.sdpMLineIndex, }, - 'sessionId' + 'sessionId', + undefined ); mockPC.onicecandidate({ candidate: null }); - expect(mockApi.addIceCandidate).toHaveBeenCalledWith('streamId', { candidate: null }, 'sessionId'); + expect(mockApi.addIceCandidate).toHaveBeenCalledWith( + 'streamId', + { candidate: null }, + 'sessionId', + undefined + ); }); it('should test ICE candidate branches comprehensively', async () => { @@ -159,13 +165,28 @@ describe('Streaming Manager Edge Cases', () => { const mockPC = (window.RTCPeerConnection as any).mock.results[0].value; mockPC.onicecandidate({ candidate: { candidate: 'test', sdpMid: null, sdpMLineIndex: 0 } }); - expect(mockApi.addIceCandidate).toHaveBeenCalledWith('streamId', { candidate: null }, 'sessionId'); + expect(mockApi.addIceCandidate).toHaveBeenCalledWith( + 'streamId', + { candidate: null }, + 'sessionId', + undefined + ); mockPC.onicecandidate({ candidate: { candidate: 'test', sdpMid: '0', sdpMLineIndex: null } }); - expect(mockApi.addIceCandidate).toHaveBeenCalledWith('streamId', { candidate: null }, 'sessionId'); + expect(mockApi.addIceCandidate).toHaveBeenCalledWith( + 'streamId', + { candidate: null }, + 'sessionId', + undefined + ); mockPC.onicecandidate({ candidate: { candidate: 'test', sdpMid: null, sdpMLineIndex: null } }); - expect(mockApi.addIceCandidate).toHaveBeenCalledWith('streamId', { candidate: null }, 'sessionId'); + expect(mockApi.addIceCandidate).toHaveBeenCalledWith( + 'streamId', + { candidate: null }, + 'sessionId', + undefined + ); }); it('should test error handling in ICE candidate processing', async () => { diff --git a/src/services/streaming-manager/factory.test.ts b/src/services/streaming-manager/factory.test.ts index 2dbb2244..e9c557af 100644 --- a/src/services/streaming-manager/factory.test.ts +++ b/src/services/streaming-manager/factory.test.ts @@ -46,7 +46,12 @@ describe('createStreamingManager', () => { await createStreamingManager(agent, { version: StreamApiVersion.V1, ...mockStreamOptions }, mockOptions); - expect(mockCreateWebRTCStreamingManager).toHaveBeenCalledWith(agent.id, mockStreamOptions, mockOptions); + expect(mockCreateWebRTCStreamingManager).toHaveBeenCalledWith( + agent.id, + mockStreamOptions, + mockOptions, + undefined + ); expect(mockCreateLiveKitStreamingManager).not.toHaveBeenCalled(); }); @@ -65,7 +70,12 @@ describe('createStreamingManager', () => { await createStreamingManager(agent, { version: StreamApiVersion.V1, ...mockStreamOptions }, mockOptions); - expect(mockCreateWebRTCStreamingManager).toHaveBeenCalledWith(agent.id, mockStreamOptions, mockOptions); + expect(mockCreateWebRTCStreamingManager).toHaveBeenCalledWith( + agent.id, + mockStreamOptions, + mockOptions, + undefined + ); expect(mockCreateLiveKitStreamingManager).not.toHaveBeenCalled(); }); diff --git a/src/services/streaming-manager/factory.ts b/src/services/streaming-manager/factory.ts index e3a282ee..207b3954 100644 --- a/src/services/streaming-manager/factory.ts +++ b/src/services/streaming-manager/factory.ts @@ -20,14 +20,15 @@ export type ExtendedStreamOptions = export async function createStreamingManager( agent: Agent, streamOptions: ExtendedStreamOptions, - options: StreamingManagerOptions + options: StreamingManagerOptions, + signal?: AbortSignal ): Promise> { const agentId = agent.id; switch (streamOptions.version) { case StreamApiVersion.V1: { const { version, ...createStreamOptions } = streamOptions; - return createWebRTCStreamingManager(agentId, createStreamOptions, options); + return createWebRTCStreamingManager(agentId, createStreamOptions, options, signal); } case StreamApiVersion.V2: { diff --git a/src/services/streaming-manager/webrtc-core.test.ts b/src/services/streaming-manager/webrtc-core.test.ts index 0704d5c5..5e5044ba 100644 --- a/src/services/streaming-manager/webrtc-core.test.ts +++ b/src/services/streaming-manager/webrtc-core.test.ts @@ -36,7 +36,7 @@ describe('Streaming Manager Core', () => { it('should create streaming manager and set up peer connection', async () => { const manager = await createStreamingManager(agentId, agentStreamOptions, options); - expect(mockApi.createStream).toHaveBeenCalledWith(agentStreamOptions); + expect(mockApi.createStream).toHaveBeenCalledWith(agentStreamOptions, undefined); expect(manager.streamId).toBe('streamId'); expect(manager.sessionId).toBe('sessionId'); expect(options.callbacks.onStreamCreated).toHaveBeenCalledWith( @@ -100,7 +100,8 @@ describe('Streaming Manager Core', () => { expect(mockApi.addIceCandidate).toHaveBeenCalledWith( 'streamId', expect.objectContaining({ candidate: 'cand' }), - 'sessionId' + 'sessionId', + undefined ); }); @@ -111,7 +112,12 @@ describe('Streaming Manager Core', () => { mockPC.onicecandidate(mockEvent); - expect(mockApi.addIceCandidate).toHaveBeenCalledWith('streamId', { candidate: null }, 'sessionId'); + expect(mockApi.addIceCandidate).toHaveBeenCalledWith( + 'streamId', + { candidate: null }, + 'sessionId', + undefined + ); }); it('should handle errors in ICE candidate handling', async () => { @@ -301,7 +307,8 @@ describe('Streaming Manager Core', () => { expect(mockApi.startConnection).toHaveBeenCalledWith( 'streamId', { type: 'answer', sdp: 'mock-sdp' }, - 'sessionId' + 'sessionId', + undefined ); }); diff --git a/src/services/streaming-manager/webrtc-manager.ts b/src/services/streaming-manager/webrtc-manager.ts index e0afde1b..d8344c82 100644 --- a/src/services/streaming-manager/webrtc-manager.ts +++ b/src/services/streaming-manager/webrtc-manager.ts @@ -133,7 +133,8 @@ function handleStreamState({ export async function createWebRTCStreamingManager( agentId: string, streamOptions: T, - { debug = false, callbacks, auth, baseURL = didApiUrl, analytics }: StreamingManagerOptions + { debug = false, callbacks, auth, baseURL = didApiUrl, analytics }: StreamingManagerOptions, + signal?: AbortSignal ): Promise> { const log = createStreamingLogger(debug, 'WebRTCStreamingManager'); const parseDataChannelMessage = createParseDataChannelMessage(log); @@ -159,7 +160,7 @@ export async function createWebRTCStreamingManager = T extends TalkStreamOptions : never; export interface RtcApi { - createStream(options: CreateStreamOptions): Promise; - startConnection(streamId: string, answer: RTCSessionDescriptionInit, sessionId?: string): Promise; - addIceCandidate(streamId: string, candidate: IceCandidate, sessionId: string): Promise; + createStream(options: CreateStreamOptions, signal?: AbortSignal): Promise; + startConnection( + streamId: string, + answer: RTCSessionDescriptionInit, + sessionId?: string, + signal?: AbortSignal + ): Promise; + addIceCandidate( + streamId: string, + candidate: IceCandidate, + sessionId: string, + signal?: AbortSignal + ): Promise; sendStreamRequest( streamId: string, sessionId: string, From 8648d918f792c18159f8ef337fadcffeaa72d68b Mon Sep 17 00:00:00 2001 From: netanelben-hamo Date: Wed, 31 Dec 2025 15:12:21 +0200 Subject: [PATCH 3/3] upgrade sdk version (#255) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 7b052999..5885f5e2 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@d-id/client-sdk", "private": false, - "version": "1.1.21", + "version": "1.1.22", "type": "module", "description": "d-id client sdk", "repository": {