





























@@ -12,6 +12,7 @@ import {
1212normalizeBaseUrl,
1313resolveProviderHttpRequestConfig,
1414} from "openclaw/plugin-sdk/provider-http";
15+import { readResponseWithLimit } from "openclaw/plugin-sdk/response-limit-runtime";
1516import {
1617normalizeSecretInputString,
1718resolveSecretInputString,
@@ -39,6 +40,8 @@ const DEFAULT_PROMPT_INPUT_NAME = "text";
3940const DEFAULT_INPUT_IMAGE_INPUT_NAME = "image";
4041const DEFAULT_POLL_INTERVAL_MS = 1_500;
4142const DEFAULT_TIMEOUT_MS = 5 * 60_000;
43+const DEFAULT_GENERATED_IMAGE_MAX_BYTES = 6 * 1024 * 1024;
44+const DEFAULT_GENERATED_MEDIA_MAX_BYTES = 16 * 1024 * 1024;
42454346export const DEFAULT_COMFY_MODEL = "workflow";
4447@@ -113,6 +116,19 @@ export function setComfyFetchGuardForTesting(impl: typeof fetchWithSsrFGuard | n
113116comfyFetchGuard = impl ?? fetchWithSsrFGuard;
114117}
115118119+function resolveComfyGeneratedOutputMaxBytes(params: {
120+cfg: OpenClawConfig;
121+capability: ComfyCapability;
122+}): number {
123+const configured = params.cfg.agents?.defaults?.mediaMaxMb;
124+if (typeof configured === "number" && Number.isFinite(configured) && configured > 0) {
125+return Math.floor(configured * 1024 * 1024);
126+}
127+return params.capability === "image"
128+ ? DEFAULT_GENERATED_IMAGE_MAX_BYTES
129+ : DEFAULT_GENERATED_MEDIA_MAX_BYTES;
130+}
131+116132function readConfigBoolean(config: ComfyProviderConfig, key: string): boolean | undefined {
117133return asBoolean(config[key]);
118134}
@@ -505,6 +521,7 @@ async function downloadOutputFile(params: {
505521file: ComfyOutputFile;
506522mode: ComfyMode;
507523capability: ComfyCapability;
524+maxBytes: number;
508525}): Promise<{ buffer: Buffer; mimeType: string }> {
509526const fileName =
510527normalizeOptionalString(params.file.filename) || normalizeOptionalString(params.file.name);
@@ -557,7 +574,15 @@ async function downloadOutputFile(params: {
557574normalizeOptionalString(redirected.response.headers.get("content-type")) ||
558575"application/octet-stream";
559576return {
560-buffer: Buffer.from(await redirected.response.arrayBuffer()),
577+buffer: await readResponseWithLimit(redirected.response, params.maxBytes, {
578+chunkTimeoutMs: params.timeoutMs,
579+onOverflow: ({ maxBytes }) =>
580+new Error(`Comfy ${params.capability} output download exceeds ${maxBytes} bytes`),
581+onIdleTimeout: ({ chunkTimeoutMs }) =>
582+new Error(
583+`Comfy ${params.capability} output download stalled after ${chunkTimeoutMs}ms`,
584+),
585+}),
561586 mimeType,
562587};
563588} finally {
@@ -570,7 +595,13 @@ async function downloadOutputFile(params: {
570595normalizeOptionalString(firstResponse.response.headers.get("content-type")) ||
571596"application/octet-stream";
572597return {
573-buffer: Buffer.from(await firstResponse.response.arrayBuffer()),
598+buffer: await readResponseWithLimit(firstResponse.response, params.maxBytes, {
599+chunkTimeoutMs: params.timeoutMs,
600+onOverflow: ({ maxBytes }) =>
601+new Error(`Comfy ${params.capability} output download exceeds ${maxBytes} bytes`),
602+onIdleTimeout: ({ chunkTimeoutMs }) =>
603+new Error(`Comfy ${params.capability} output download stalled after ${chunkTimeoutMs}ms`),
604+}),
574605 mimeType,
575606};
576607} finally {
@@ -794,6 +825,10 @@ export async function runComfyWorkflow(params: {
794825}
795826796827const assets: ComfyGeneratedAsset[] = [];
828+const maxOutputBytes = resolveComfyGeneratedOutputMaxBytes({
829+cfg: params.cfg,
830+capability: params.capability,
831+});
797832let assetIndex = 0;
798833for (const output of outputFiles) {
799834const downloaded = await downloadOutputFile({
@@ -805,6 +840,7 @@ export async function runComfyWorkflow(params: {
805840file: output.file,
806841 mode,
807842capability: params.capability,
843+maxBytes: maxOutputBytes,
808844});
809845assetIndex += 1;
810846const originalName =
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。