feat: 实现伪流式传输功能

本次提交引入了伪流式传输(Fake Streaming)功能,旨在为不支持原生流式响应的语言模型或特定场景提供类似流式的用户体验。

主要变更包括:

- **配置更新**:
    - 在 `.env.example` 和 `app/config/config.py` 中添加了新的配置项 `FAKE_STREAM_ENABLED` 和 `FAKE_STREAM_EMPTY_DATA_INTERVAL_SECONDS`,用于控制伪流式功能的启用和心跳包发送间隔。
    - 更新了 `README.md` 以包含新的伪流式配置说明。

- **核心服务逻辑**:
    - 在 `app/service/chat/openai_chat_service.py` 中:
        - 新增 `_fake_stream_logic_impl` 方法,用于处理伪流式调用的核心逻辑。当启用伪流式时,该方法会调用非流式接口,并在等待期间定期发送空数据块以维持连接。
        - 修改 `_handle_stream_completion` 方法,使其能够根据 `FAKE_STREAM_ENABLED` 配置在真实流式和伪流式逻辑之间切换。
        - 改进了流式处理中的重试逻辑、API密钥切换机制以及错误日志记录,使其更加健壮。特别是在伪流式场景下,确保了即使在非流式调用中也能正确处理和记录错误。

- **前端配置界面**:
    - 在 `app/static/js/config_editor.js` 中添加了处理和填充伪流式配置项的逻辑。
    - 在 `app/templates/config_editor.html` 中为伪流式配置添加了相应的表单控件,允许用户在配置编辑器中启用/禁用伪流式并设置空数据发送间隔。

该功能通过在后端模拟流式输出,即使底层模型不支持流式传输,也能向客户端提供持续的数据流,从而改善了用户体验,特别是在处理可能耗时较长的请求时。
This commit is contained in:
snaily
2025-05-08 23:37:35 +08:00
parent b6a54190ed
commit a7d548a849
6 changed files with 372 additions and 79 deletions
+51
View File
@@ -630,6 +630,15 @@ async function initConfig() {
}
// --- 结束:处理自动删除请求日志配置的默认值 ---
// --- 新增:处理假流式配置的默认值 ---
if (typeof config.FAKE_STREAM_ENABLED === "undefined") {
config.FAKE_STREAM_ENABLED = false;
}
if (typeof config.FAKE_STREAM_EMPTY_DATA_INTERVAL_SECONDS === "undefined") {
config.FAKE_STREAM_EMPTY_DATA_INTERVAL_SECONDS = 5;
}
// --- 结束:处理假流式配置的默认值 ---
populateForm(config);
// After populateForm, initialize masking for all populated sensitive fields
if (configForm) {
@@ -664,6 +673,10 @@ async function initConfig() {
AUTO_DELETE_ERROR_LOGS_DAYS: 7, // 新增默认值
AUTO_DELETE_REQUEST_LOGS_ENABLED: false, // 新增默认值
AUTO_DELETE_REQUEST_LOGS_DAYS: 30, // 新增默认值
// --- 新增:处理假流式配置的默认值 ---
FAKE_STREAM_ENABLED: false,
FAKE_STREAM_EMPTY_DATA_INTERVAL_SECONDS: 5,
// --- 结束:处理假流式配置的默认值 ---
};
populateForm(defaultConfig);
@@ -866,6 +879,26 @@ function populateForm(config) {
});
}
// --- 结束:处理自动删除请求日志的字段 ---
// --- 新增:处理假流式配置的字段 ---
const fakeStreamEnabledCheckbox = document.getElementById(
"FAKE_STREAM_ENABLED"
);
const fakeStreamIntervalInput = document.getElementById(
"FAKE_STREAM_EMPTY_DATA_INTERVAL_SECONDS"
);
if (fakeStreamEnabledCheckbox && fakeStreamIntervalInput) {
fakeStreamEnabledCheckbox.checked = !!config.FAKE_STREAM_ENABLED;
fakeStreamIntervalInput.value =
config.FAKE_STREAM_EMPTY_DATA_INTERVAL_SECONDS || 5;
// 根据复选框状态设置输入框的禁用状态 (如果需要)
// fakeStreamIntervalInput.disabled = !fakeStreamEnabledCheckbox.checked;
// fakeStreamEnabledCheckbox.addEventListener("change", function () {
// fakeStreamIntervalInput.disabled = !this.checked;
// });
}
// --- 结束:处理假流式配置的字段 ---
}
/**
@@ -1461,6 +1494,24 @@ function collectFormData() {
}
// --- 结束:收集自动删除请求日志的配置 ---
// --- 新增:收集假流式配置 ---
const fakeStreamEnabledCheckbox = document.getElementById(
"FAKE_STREAM_ENABLED"
);
if (fakeStreamEnabledCheckbox) {
formData["FAKE_STREAM_ENABLED"] = fakeStreamEnabledCheckbox.checked;
}
const fakeStreamIntervalInput = document.getElementById(
"FAKE_STREAM_EMPTY_DATA_INTERVAL_SECONDS"
);
if (fakeStreamIntervalInput) {
formData["FAKE_STREAM_EMPTY_DATA_INTERVAL_SECONDS"] = parseInt(
fakeStreamIntervalInput.value,
10
);
}
// --- 结束:收集假流式配置 ---
return formData;
}