feat(deepseek): upload images via Files API with file_id references - #1113
feat(deepseek): upload images via Files API with file_id references#11133316891527 wants to merge 7 commits into
Conversation
… content-addressed dedup
…aching with no active chat
CATMIAOZHI
left a comment
There was a problem hiding this comment.
BLOCK:3 项 P2,详见行内评论。
审计提交:5a2f284e142874e2b4d5ea5e1fdffdfc622d98ba,目标分支 dev。已先请求 CATMIAOZHI review,再完成独立工作树全 diff、实际调用链和独立 agent 复核;git diff --check 通过。
验证范围:上游仓库该 HEAD 的 check-runs 为 0,审计前无 review 线程,已有普通评论也已核查。当前 PR workflow 仅匹配 development,本 PR 的目标为 dev;构建/单测 push workflow 匹配 main。已核对工作流实际任务及 Actions Variables(GITEE_OWNER、GITEE_REPO)。已核实作者 fork 的 Android Build 对应本次 HEAD 且成功;该运行只有构建步骤,没有 JVM 单测执行步骤,因此不将其视为单测通过。遵守目标仓库 AGENTS.md,本次未执行本地编译、测试、Lint 或真机验证,未修改源码。
|
|
||
| /** 给请求附加认证头与自定义头(排除会破坏 multipart 边界的 Content-Type 覆写) */ | ||
| private suspend fun applyAuthAndCustomHeaders(builder: Request.Builder) { | ||
| val apiKey = apiKeyProvider.getApiKey().trim() |
There was a problem hiding this comment.
[P2] 为媒体上传与聊天请求固定同一个 API key
MultiApiKeyProvider 每次 getApiKey() 都推进轮询索引,最终 OpenAIProvider.createRequest 又取一次 key。两个可用 key 的空缓存首图流程会变成 list=A、upload=B、chat=A;DeepSeek 官方文档 明确文件归属 API key,所以聊天请求无法引用另一 key 上传的文件。缓存仅按图片 ID 保存,后续换 key 也会继续复用错误归属。请让列表、上传、聊天及缓存共用一次请求选定的 key,重试换 key 时重新准备对应媒体。
| .build() | ||
| val builder = Request.Builder().url(filesEndpoint).post(body) | ||
| applyAuthAndCustomHeaders(builder) | ||
| withContext(Dispatchers.IO) { httpClient.newCall(builder.build()).execute() }.use { response -> |
There was a problem hiding this comment.
[P2] 将文件请求接入停止生成的取消链
这里创建的 Call 没有进入 OpenAIProvider.activeCall,也没有协程取消到 Call.cancel() 的连接。上传或列表请求很慢时,点击停止只会取消聊天 activeCall 和发送 Job,而阻塞 execute() 仍要等网络返回;MessageProcessingDelegate 的停止路径随后 join 发送 Job,导致停止和 loading 收尾一起等待。请将文件 Call 接入取消机制,并保留 CancellationException 的传播;第 118 行的列表请求也需处理。
| @@ -963,12 +963,7 @@ open class OpenAIProvider( | |||
|
|
|||
| if ((allowUserRichContent || allowResponsesToolImages) && supportsVision) { | |||
| imageLinks.forEach { link -> | |||
There was a problem hiding this comment.
[P2] 工具返回图片也需要经过新的文件引用构建入口
这里只替换 buildContentField 的图片路径。DeepSeek Chat Completions 在原生工具调用返回截图时,仍经 DeepseekProvider 的 TOOL_RESULT 分支调用 appendReadableImageMessageIfNeeded;该方法继续硬编码 image_url + Base64,不调用 buildImageContentPart。这些图片会先被 prepareMedia 上传,但聊天请求仍发送完整内嵌图片,无法获得本 PR 的文件复用及规避内嵌大小限制的效果。请将该实际工具图片发送路径也接入同一 hook;Responses 的工具图片走适配器,不是此处漏掉的路径。
变更说明 / Description
背景与动机 / Context and motivation
issue #1105 希望解决 DeepSeek 发送图片时以 Base64 内嵌易超出 API 限制的问题。经讨论收敛范围:本PR仅接入 DeepSeek 官方 Files API,不引入第三方图床(后续可能会有其他人跟进这个需求,但不在本人考虑和处理范围内),不增加独立配置开关(发送图片时默认自动使用,失败静默回退 Base64)。
改动范围 / Changes
不包含:第三方图床接入、Files API 管理界面、自动过期/清理策略(已预留删除端点能力)。
兼容性与风险 / Compatibility and risks
关联 Issue / Related issue
Resolves #1105(范围收敛为 DeepSeek Files API,第三方图床不在本 PR)
验证方式 / Verification
证据 / Evidence
检查清单 / Checklist