@@ -100,60 +100,47 @@ export class CopilotSession {
100100 * Events are still delivered to handlers registered via {@link on} while waiting.
101101 *
102102 * @param options - The message options including the prompt and optional attachments
103- * @param timeout - Optional timeout in milliseconds. If not provided, waits indefinitely.
103+ * @param timeout - Timeout in milliseconds (default: 60000)
104104 * @returns A promise that resolves with the final assistant message when the session becomes idle,
105105 * or undefined if no assistant message was received
106106 * @throws Error if the timeout is reached before the session becomes idle
107107 * @throws Error if the session has been destroyed or the connection fails
108108 *
109109 * @example
110110 * ```typescript
111- * // Send and wait for completion with a 5-minute timeout
112- * const response = await session.sendAndWait(
113- * { prompt: "What is 2+2?" },
114- * 300_000
115- * );
111+ * // Send and wait for completion with default 60s timeout
112+ * const response = await session.sendAndWait({ prompt: "What is 2+2?" });
116113 * console.log(response?.data.content); // "4"
117114 * ```
118115 */
119116 async sendAndWait ( options : MessageOptions , timeout ?: number ) : Promise < SessionEvent | undefined > {
120- // Track whether we've started the send - only count idle events after this point
121- let sendStarted = false ;
117+ const effectiveTimeout = timeout ?? 60_000 ;
118+
122119 let resolveIdle : ( ) => void ;
123120 const idlePromise = new Promise < void > ( ( resolve ) => {
124121 resolveIdle = resolve ;
125122 } ) ;
126123
127- // Track the last assistant message received
128124 let lastAssistantMessage : SessionEvent | undefined ;
129125
130- // Register listener BEFORE sending, but only resolve for idle events
131- // that arrive after we've initiated the send (to ignore stale events)
132126 const unsubscribe = this . on ( ( event ) => {
133- if ( sendStarted ) {
134- if ( event . type === "assistant.message" ) {
135- lastAssistantMessage = event ;
136- } else if ( event . type === "session.idle" ) {
137- resolveIdle ( ) ;
138- }
127+ if ( event . type === "assistant.message" ) {
128+ lastAssistantMessage = event ;
129+ } else if ( event . type === "session.idle" ) {
130+ resolveIdle ( ) ;
139131 }
140132 } ) ;
141133
142134 try {
143- // Mark send as started and initiate - these are synchronous so no events
144- // can sneak in between setting the flag and starting the send
145- sendStarted = true ;
146135 await this . send ( options ) ;
147136
148- // Wait for idle with optional timeout
149- if ( timeout !== undefined ) {
150- const timeoutPromise = new Promise < never > ( ( _ , reject ) => {
151- setTimeout ( ( ) => reject ( new Error ( `Timeout after ${ timeout } ms waiting for session.idle` ) ) , timeout ) ;
152- } ) ;
153- await Promise . race ( [ idlePromise , timeoutPromise ] ) ;
154- } else {
155- await idlePromise ;
156- }
137+ const timeoutPromise = new Promise < never > ( ( _ , reject ) => {
138+ setTimeout (
139+ ( ) => reject ( new Error ( `Timeout after ${ effectiveTimeout } ms waiting for session.idle` ) ) ,
140+ effectiveTimeout
141+ ) ;
142+ } ) ;
143+ await Promise . race ( [ idlePromise , timeoutPromise ] ) ;
157144
158145 return lastAssistantMessage ;
159146 } finally {
0 commit comments