@@ -34,7 +34,9 @@ import type { ToolPolicy } from "../../src/utils/tools/toolPolicy";
3434
3535// Test constants
3636const TEST_TIMEOUT_LOCAL_MS = 25000 ; // Includes init wait time
37- const TEST_TIMEOUT_SSH_MS = 45000 ; // SSH has more overhead (network, rsync, etc.)
37+ const TEST_TIMEOUT_SSH_MS = 60000 ; // SSH has more overhead (network, rsync, etc.)
38+ const STREAM_TIMEOUT_LOCAL_MS = 15000 ; // Stream timeout for local runtime
39+ const STREAM_TIMEOUT_SSH_MS = 25000 ; // SSH needs longer due to network latency
3840const HAIKU_MODEL = "anthropic:claude-haiku-4-5" ;
3941const INIT_HOOK_WAIT_MS = 1500 ; // Wait for async init hook completion (local runtime)
4042const SSH_INIT_WAIT_MS = 7000 ; // SSH init includes sync + checkout + hook, takes longer
@@ -166,7 +168,8 @@ async function createWorkspaceHelper(
166168async function sendMessageAndWait (
167169 env : TestEnvironment ,
168170 workspaceId : string ,
169- message : string
171+ message : string ,
172+ streamTimeout ?: number
170173) : Promise < WorkspaceChatMessage [ ] > {
171174 // Clear previous events
172175 env . sentEvents . length = 0 ;
@@ -187,7 +190,7 @@ async function sendMessageAndWait(
187190 }
188191
189192 // Wait for stream completion
190- return await waitForStreamCompletion ( env . sentEvents , workspaceId ) ;
193+ return await waitForStreamCompletion ( env . sentEvents , workspaceId , streamTimeout ) ;
191194}
192195
193196// ============================================================================
@@ -196,6 +199,10 @@ async function sendMessageAndWait(
196199
197200describeIntegration ( "Runtime File Editing Tools" , ( ) => {
198201 beforeAll ( async ( ) => {
202+ // Preload AI SDK providers to avoid race conditions in concurrent tests
203+ const { preloadAISDKProviders } = await import ( "../../src/services/aiService" ) ;
204+ await preloadAISDKProviders ( ) ;
205+
199206 // Check if Docker is available (required for SSH tests)
200207 if ( ! ( await isDockerAvailable ( ) ) ) {
201208 throw new Error (
@@ -262,10 +269,12 @@ describeIntegration("Runtime File Editing Tools", () => {
262269 try {
263270 // Ask AI to create a test file
264271 const testFileName = "test_read.txt" ;
272+ const streamTimeout = type === "ssh" ? STREAM_TIMEOUT_SSH_MS : STREAM_TIMEOUT_LOCAL_MS ;
265273 const createEvents = await sendMessageAndWait (
266274 env ,
267275 workspaceId ,
268- `Create a file called ${ testFileName } with the content: "Hello from cmux file tools!"`
276+ `Create a file called ${ testFileName } with the content: "Hello from cmux file tools!"` ,
277+ streamTimeout
269278 ) ;
270279
271280 // Verify file was created successfully
@@ -279,7 +288,8 @@ describeIntegration("Runtime File Editing Tools", () => {
279288 const readEvents = await sendMessageAndWait (
280289 env ,
281290 workspaceId ,
282- `Read the file ${ testFileName } and tell me what it contains.`
291+ `Read the file ${ testFileName } and tell me what it contains.` ,
292+ streamTimeout
283293 ) ;
284294
285295 // Verify stream completed successfully
@@ -336,10 +346,12 @@ describeIntegration("Runtime File Editing Tools", () => {
336346 try {
337347 // Ask AI to create a test file
338348 const testFileName = "test_replace.txt" ;
349+ const streamTimeout = type === "ssh" ? STREAM_TIMEOUT_SSH_MS : STREAM_TIMEOUT_LOCAL_MS ;
339350 const createEvents = await sendMessageAndWait (
340351 env ,
341352 workspaceId ,
342- `Create a file called ${ testFileName } with the content: "The quick brown fox jumps over the lazy dog."`
353+ `Create a file called ${ testFileName } with the content: "The quick brown fox jumps over the lazy dog."` ,
354+ streamTimeout
343355 ) ;
344356
345357 // Verify file was created successfully
@@ -353,7 +365,8 @@ describeIntegration("Runtime File Editing Tools", () => {
353365 const replaceEvents = await sendMessageAndWait (
354366 env ,
355367 workspaceId ,
356- `In ${ testFileName } , replace "brown fox" with "red panda".`
368+ `In ${ testFileName } , replace "brown fox" with "red panda".` ,
369+ streamTimeout
357370 ) ;
358371
359372 // Verify stream completed successfully
@@ -416,10 +429,12 @@ describeIntegration("Runtime File Editing Tools", () => {
416429 try {
417430 // Ask AI to create a test file
418431 const testFileName = "test_insert.txt" ;
432+ const streamTimeout = type === "ssh" ? STREAM_TIMEOUT_SSH_MS : STREAM_TIMEOUT_LOCAL_MS ;
419433 const createEvents = await sendMessageAndWait (
420434 env ,
421435 workspaceId ,
422- `Create a file called ${ testFileName } with two lines: "Line 1" and "Line 3".`
436+ `Create a file called ${ testFileName } with two lines: "Line 1" and "Line 3".` ,
437+ streamTimeout
423438 ) ;
424439
425440 // Verify file was created successfully
@@ -433,7 +448,8 @@ describeIntegration("Runtime File Editing Tools", () => {
433448 const insertEvents = await sendMessageAndWait (
434449 env ,
435450 workspaceId ,
436- `In ${ testFileName } , insert "Line 2" between Line 1 and Line 3.`
451+ `In ${ testFileName } , insert "Line 2" between Line 1 and Line 3.` ,
452+ streamTimeout
437453 ) ;
438454
439455 // Verify stream completed successfully
0 commit comments