diff --git a/README.en.md b/README.en.md
index 55e2ffe5b..a509f36c9 100644
--- a/README.en.md
+++ b/README.en.md
@@ -303,6 +303,7 @@ docker run --name new-api -d --restart always \
| `SQL_DSN` | Database connection string | - |
| `REDIS_CONN_STRING` | Redis connection string | - |
| `STREAMING_TIMEOUT` | Streaming timeout (seconds) | `300` |
+| `STREAM_SCANNER_MAX_BUFFER_MB` | Max per-line buffer (MB) for the stream scanner; increase when upstream sends huge image/base64 payloads | `64` |
| `AZURE_DEFAULT_API_VERSION` | Azure API version | `2025-04-01-preview` |
| `ERROR_LOG_ENABLED` | Error log switch | `false` |
diff --git a/README.fr.md b/README.fr.md
index a941c50db..ec4ac5f8a 100644
--- a/README.fr.md
+++ b/README.fr.md
@@ -299,6 +299,7 @@ docker run --name new-api -d --restart always \
| `SQL_DSN` | Chaine de connexion à la base de données | - |
| `REDIS_CONN_STRING` | Chaine de connexion Redis | - |
| `STREAMING_TIMEOUT` | Délai d'expiration du streaming (secondes) | `300` |
+| `STREAM_SCANNER_MAX_BUFFER_MB` | Taille max du buffer par ligne (Mo) pour le scanner SSE ; à augmenter quand les sorties image/base64 sont très volumineuses (ex. images 4K) | `64` |
| `AZURE_DEFAULT_API_VERSION` | Version de l'API Azure | `2025-04-01-preview` |
| `ERROR_LOG_ENABLED` | Interrupteur du journal d'erreurs | `false` |
@@ -438,4 +439,4 @@ Si ce projet vous est utile, bienvenue à nous donner une ⭐️ Étoile!
Construit avec ❤️ par QuantumNous
-
\ No newline at end of file
+
diff --git a/README.ja.md b/README.ja.md
index 928e190f5..cbd4fdc16 100644
--- a/README.ja.md
+++ b/README.ja.md
@@ -308,6 +308,7 @@ docker run --name new-api -d --restart always \
| `SQL_DSN** | データベース接続文字列 | - |
| `REDIS_CONN_STRING` | Redis接続文字列 | - |
| `STREAMING_TIMEOUT` | ストリーミング応答のタイムアウト時間(秒) | `300` |
+| `STREAM_SCANNER_MAX_BUFFER_MB` | ストリームスキャナの1行あたりバッファ上限(MB)。4K画像など巨大なbase64 `data:` ペイロードを扱う場合は値を増加させてください | `64` |
| `AZURE_DEFAULT_API_VERSION` | Azure APIバージョン | `2025-04-01-preview` |
| `ERROR_LOG_ENABLED` | エラーログスイッチ | `false` |
diff --git a/README.md b/README.md
index e0759506c..86ba5852e 100644
--- a/README.md
+++ b/README.md
@@ -297,15 +297,16 @@ docker run --name new-api -d --restart always \
常用环境变量配置
-| 变量名 | 说明 | 默认值 |
-|--------|------|--------|
-| `SESSION_SECRET` | 会话密钥(多机部署必须) | - |
-| `CRYPTO_SECRET` | 加密密钥(Redis 必须) | - |
-| `SQL_DSN` | 数据库连接字符串 | - |
-| `REDIS_CONN_STRING` | Redis 连接字符串 | - |
-| `STREAMING_TIMEOUT` | 流式超时时间(秒) | `300` |
-| `AZURE_DEFAULT_API_VERSION` | Azure API 版本 | `2025-04-01-preview` |
-| `ERROR_LOG_ENABLED` | 错误日志开关 | `false` |
+| 变量名 | 说明 | 默认值 |
+|--------|--------------------------------------------------------------|--------|
+| `SESSION_SECRET` | 会话密钥(多机部署必须) | - |
+| `CRYPTO_SECRET` | 加密密钥(Redis 必须) | - |
+| `SQL_DSN` | 数据库连接字符串 | - |
+| `REDIS_CONN_STRING` | Redis 连接字符串 | - |
+| `STREAMING_TIMEOUT` | 流式超时时间(秒) | `300` |
+| `STREAM_SCANNER_MAX_BUFFER_MB` | 流式扫描器单行最大缓冲(MB),图像生成等超大 `data:` 片段(如 4K 图片 base64)需适当调大 | `64` |
+| `AZURE_DEFAULT_API_VERSION` | Azure API 版本 | `2025-04-01-preview` |
+| `ERROR_LOG_ENABLED` | 错误日志开关 | `false` |
📖 **完整配置:** [环境变量文档](https://docs.newapi.pro/installation/environment-variables)
diff --git a/common/init.go b/common/init.go
index 687af6e76..986804774 100644
--- a/common/init.go
+++ b/common/init.go
@@ -114,6 +114,7 @@ func initConstantEnv() {
constant.StreamingTimeout = GetEnvOrDefault("STREAMING_TIMEOUT", 300)
constant.DifyDebug = GetEnvOrDefaultBool("DIFY_DEBUG", true)
constant.MaxFileDownloadMB = GetEnvOrDefault("MAX_FILE_DOWNLOAD_MB", 20)
+ constant.StreamScannerMaxBufferMB = GetEnvOrDefault("STREAM_SCANNER_MAX_BUFFER_MB", 64)
// ForceStreamOption 覆盖请求参数,强制返回usage信息
constant.ForceStreamOption = GetEnvOrDefaultBool("FORCE_STREAM_OPTION", true)
constant.CountToken = GetEnvOrDefaultBool("CountToken", true)
diff --git a/constant/env.go b/constant/env.go
index ade835c01..94c2cfcd4 100644
--- a/constant/env.go
+++ b/constant/env.go
@@ -3,6 +3,7 @@ package constant
var StreamingTimeout int
var DifyDebug bool
var MaxFileDownloadMB int
+var StreamScannerMaxBufferMB int
var ForceStreamOption bool
var CountToken bool
var GetMediaToken bool
diff --git a/relay/helper/stream_scanner.go b/relay/helper/stream_scanner.go
index 9044a1650..8653d4bb5 100644
--- a/relay/helper/stream_scanner.go
+++ b/relay/helper/stream_scanner.go
@@ -22,11 +22,18 @@ import (
)
const (
- InitialScannerBufferSize = 64 << 10 // 64KB (64*1024)
- MaxScannerBufferSize = 10 << 20 // 10MB (10*1024*1024)
- DefaultPingInterval = 10 * time.Second
+ InitialScannerBufferSize = 64 << 10 // 64KB (64*1024)
+ DefaultMaxScannerBufferSize = 64 << 20 // 64MB (64*1024*1024) default SSE buffer size
+ DefaultPingInterval = 10 * time.Second
)
+func getScannerBufferSize() int {
+ if constant.StreamScannerMaxBufferMB > 0 {
+ return constant.StreamScannerMaxBufferMB << 20
+ }
+ return DefaultMaxScannerBufferSize
+}
+
func StreamScannerHandler(c *gin.Context, resp *http.Response, info *relaycommon.RelayInfo, dataHandler func(data string) bool) {
if resp == nil || dataHandler == nil {
@@ -95,7 +102,7 @@ func StreamScannerHandler(c *gin.Context, resp *http.Response, info *relaycommon
close(stopChan)
}()
- scanner.Buffer(make([]byte, InitialScannerBufferSize), MaxScannerBufferSize)
+ scanner.Buffer(make([]byte, InitialScannerBufferSize), getScannerBufferSize())
scanner.Split(bufio.ScanLines)
SetEventStreamHeaders(c)