问题描述
在 AI 资料里点击“更新到当前进度”时,后端配置的图片模型请求已经成功,Sub2API 日志也显示 image generation 成功,但 Reader 前端地图页仍然降级显示为关系图。随后手动点击“重绘地图”又可能成功显示 AI 地图。
复现环境
- Reader-Rust 通过 Docker 运行
- 使用后端 AI 模型配置
- 文本模型与图片模型均走
/reader3/aiProxy
- 图片模型服务为 OpenAI 兼容接口,经 Sub2API 转发
复现步骤
- 配置后端 AI 文本模型和图片模型。
- 打开一本书的 AI 资料。
- 点击“更新到当前进度”。
- 观察 Sub2API 日志,图片生成请求成功。
- 回到 Reader AI 资料地图页,地图没有显示图片,而是显示关系图 fallback。
- 再点“重绘地图”,有时可以正常显示图片地图。
实际结果
首次生成图片成功后,前端仍保存为 fallback:
{
"mapDirty": true,
"map": {
"fallback": "relationship-graph"
}
}
本地排查时 Reader 日志里出现过类似错误:
only http/https proxy targets are supported
期望结果
只要图片模型已经成功返回有效图片结果,AI 资料地图页就应该显示 AI 地图,而不是降级为关系图。
初步根因
frontend/src/utils/aiBookGeneration.ts 中 uploadGeneratedMap() 对图片模型返回结果处理不够兼容。
图片模型可能返回:
b64_json
- 普通
http(s) 图片 URL
data:image/...;base64,... URL
当前逻辑会把非 b64_json 的 imageUrl 交给 fetchImageBlob();如果开启后端代理,会继续走 /reader3/aiProxyImage。但后端 aiProxyImage 只接受 http/https,遇到 data:image/... 会拒绝,导致前端 catch 后降级成关系图。
这解释了为什么:
- Sub2API 里 image generation 已成功;
- Reader 前端仍降级;
- 手动重绘时如果第二次返回
b64_json 或普通 URL,则又成功。
修复建议
建议在前端处理图片结果时:
- 如果返回
b64_json:保持现有逻辑,直接转 Blob 上传。
- 如果返回
data:image/...:不要走 /reader3/aiProxyImage,直接解析 data URL 为 Blob 后上传。
- 如果返回普通
http(s) URL:可以走代理下载并上传;如果下载/上传失败,可以考虑保留上游 URL,避免直接降级为关系图。
- 增加回归测试覆盖:
data:image/... 不应走 /reader3/aiProxyImage;
- 上游
http(s) 图片 URL 下载失败时,不应直接触发关系图降级。
本地验证
我本地按上述方向修复后:
npm run test -- src/utils/aiBookGeneration.test.ts 通过
npm run build 通过
- Docker 本地容器重建后可正常启动
相关本地改动思路集中在:
frontend/src/utils/aiBookGeneration.ts
frontend/src/utils/aiBookGeneration.test.ts
问题描述
在 AI 资料里点击“更新到当前进度”时,后端配置的图片模型请求已经成功,Sub2API 日志也显示 image generation 成功,但 Reader 前端地图页仍然降级显示为关系图。随后手动点击“重绘地图”又可能成功显示 AI 地图。
复现环境
/reader3/aiProxy复现步骤
实际结果
首次生成图片成功后,前端仍保存为 fallback:
{ "mapDirty": true, "map": { "fallback": "relationship-graph" } }本地排查时 Reader 日志里出现过类似错误:
期望结果
只要图片模型已经成功返回有效图片结果,AI 资料地图页就应该显示 AI 地图,而不是降级为关系图。
初步根因
frontend/src/utils/aiBookGeneration.ts中uploadGeneratedMap()对图片模型返回结果处理不够兼容。图片模型可能返回:
b64_jsonhttp(s)图片 URLdata:image/...;base64,...URL当前逻辑会把非
b64_json的imageUrl交给fetchImageBlob();如果开启后端代理,会继续走/reader3/aiProxyImage。但后端aiProxyImage只接受http/https,遇到data:image/...会拒绝,导致前端 catch 后降级成关系图。这解释了为什么:
b64_json或普通 URL,则又成功。修复建议
建议在前端处理图片结果时:
b64_json:保持现有逻辑,直接转 Blob 上传。data:image/...:不要走/reader3/aiProxyImage,直接解析 data URL 为 Blob 后上传。http(s)URL:可以走代理下载并上传;如果下载/上传失败,可以考虑保留上游 URL,避免直接降级为关系图。data:image/...不应走/reader3/aiProxyImage;http(s)图片 URL 下载失败时,不应直接触发关系图降级。本地验证
我本地按上述方向修复后:
npm run test -- src/utils/aiBookGeneration.test.ts通过npm run build通过相关本地改动思路集中在: