@@ -120,6 +120,7 @@ const OMITTED_QA_EXTENSION_PREFIXES = [
|
120 | 120 | ]; |
121 | 121 | export const CROSS_OS_DASHBOARD_SMOKE_TIMEOUT_MS = 120_000; |
122 | 122 | export const CROSS_OS_DASHBOARD_FETCH_TIMEOUT_MS = 10_000; |
| 123 | +export const CROSS_OS_FETCH_BODY_MAX_CHARS = 1024 * 1024; |
123 | 124 | export const CROSS_OS_GATEWAY_STATUS_RPC_TIMEOUT_MS = 30_000; |
124 | 125 | export const CROSS_OS_GATEWAY_STATUS_COMMAND_TIMEOUT_MS = |
125 | 126 | CROSS_OS_GATEWAY_STATUS_RPC_TIMEOUT_MS + 45_000; |
@@ -2462,6 +2463,45 @@ async function configureDiscordSmoke(params) {
|
2462 | 2463 | }); |
2463 | 2464 | } |
2464 | 2465 | |
| 2466 | +export async function readBoundedCrossOsResponseText( |
| 2467 | +response: Response, |
| 2468 | +maxChars = CROSS_OS_FETCH_BODY_MAX_CHARS, |
| 2469 | +): Promise<string> { |
| 2470 | +if (!response.body) { |
| 2471 | +return ""; |
| 2472 | +} |
| 2473 | + |
| 2474 | +const reader = response.body.getReader(); |
| 2475 | +const decoder = new TextDecoder(); |
| 2476 | +let text = ""; |
| 2477 | +let truncated = false; |
| 2478 | + |
| 2479 | +try { |
| 2480 | +while (text.length <= maxChars) { |
| 2481 | +const { done, value } = await reader.read(); |
| 2482 | +if (done) { |
| 2483 | +text += decoder.decode(); |
| 2484 | +break; |
| 2485 | +} |
| 2486 | + |
| 2487 | +text += decoder.decode(value, { stream: true }); |
| 2488 | +if (text.length > maxChars) { |
| 2489 | +text = text.slice(0, maxChars); |
| 2490 | +truncated = true; |
| 2491 | +break; |
| 2492 | +} |
| 2493 | +} |
| 2494 | +} finally { |
| 2495 | +if (truncated) { |
| 2496 | +await reader.cancel().catch(() => undefined); |
| 2497 | +} else { |
| 2498 | +reader.releaseLock(); |
| 2499 | +} |
| 2500 | +} |
| 2501 | + |
| 2502 | +return truncated ? `${text}\n[truncated]` : text; |
| 2503 | +} |
| 2504 | + |
2465 | 2505 | async function waitForDiscordMessage(params) { |
2466 | 2506 | const deadline = Date.now() + 3 * 60 * 1000; |
2467 | 2507 | while (Date.now() < deadline) { |
@@ -2473,7 +2513,7 @@ async function waitForDiscordMessage(params) {
|
2473 | 2513 | }, |
2474 | 2514 | }, |
2475 | 2515 | ); |
2476 | | -const text = await response.text(); |
| 2516 | +const text = await readBoundedCrossOsResponseText(response); |
2477 | 2517 | if (!response.ok) { |
2478 | 2518 | await sleep(2_000); |
2479 | 2519 | continue; |
@@ -2501,7 +2541,7 @@ async function postDiscordMessage(params) {
|
2501 | 2541 | }), |
2502 | 2542 | }, |
2503 | 2543 | ); |
2504 | | -const text = await response.text(); |
| 2544 | +const text = await readBoundedCrossOsResponseText(response); |
2505 | 2545 | if (!response.ok) { |
2506 | 2546 | throw new Error(`Failed to post Discord smoke message: ${text}`); |
2507 | 2547 | } |
@@ -3292,7 +3332,7 @@ async function runDashboardSmoke(params) {
|
3292 | 3332 | const response = await fetch(dashboardUrl, { |
3293 | 3333 | signal: AbortSignal.timeout(CROSS_OS_DASHBOARD_FETCH_TIMEOUT_MS), |
3294 | 3334 | }); |
3295 | | -const html = await response.text(); |
| 3335 | +const html = await readBoundedCrossOsResponseText(response); |
3296 | 3336 | if ( |
3297 | 3337 | response.ok && |
3298 | 3338 | html.includes("<title>OpenClaw Control</title>") && |
|