Conversation
仅在 fork 仓库 shuanbao0/sub2api 使用,不会影响上游。触发方式限定为
workflow_dispatch(手动),从 GitHub Actions 页面点击 Run workflow 即可。
构建流程复用根 Dockerfile 的多阶段构建(node → golang → alpine),
镜像推送到阿里云个人版 ACR(crpi-5mbh0qm9ti5c2olw 实例),命名为
shuanbaoai/sub2api,tag 为 latest + ${github.sha} + 可选的 tag_suffix。
依赖的 secrets:ACR_USER / ACR_PASS,需在 fork 仓库的
Settings → Secrets and variables → Actions 中配置。
原代码 \`apiResponse as Record<string, unknown>\` 在严格 TS 检查下失败, 因为 ApiResponse<unknown> 没有索引签名,不能与 Record 类型充分重叠。 改用标准的 \`as unknown as Record\` 双重断言模式绕过。 此错误在 Docker 构建前端 (vue-tsc -b) 时暴露,阻塞 fork 的 ACR 镜像构建。
原来 VERSION build-arg 传的是完整 40 位 SHA,UI 显示成
v6aa146ba0f189da763918d633d8add2d730d45f4 太长,没法用。
改成读取 backend/cmd/server/VERSION 文件里的 semver(当前 0.1.110),
追加 -shuanbao.\${short_sha},最终显示 v0.1.110-shuanbao.6aa146b
(标准版本 + fork 身份 + 可追溯 commit)。
镜像 tag 相应调整为:
- :latest
- :\${short_sha} (7 位 short SHA,便于部署机按 SHA 定位)
- :\${full_version} (完整版本号,便于回滚到具体 release)
- :\${tag_suffix} (可选,workflow_dispatch 输入)
Cursor 走 /v1/chat/completions 发的 body 里会带 prompt_cache_retention
(OpenAI Responses API 新增参数,控制 prompt 缓存 TTL),但 ChatGPT 内部
Codex endpoint 还不支持,会直接返回:
Unsupported parameter: prompt_cache_retention
在 applyCodexOAuthTransform 的现有 strip 列表里追加这一项,和
max_output_tokens / temperature / top_p 等已剥参数同样处理。
新增回归测试 TestApplyCodexOAuthTransform_StripsPromptCacheRetention
防止未来被误删。
背景:applyCodexOAuthTransform 里的 strip 只对 OAuth 账号生效,若
账号是 API Key 类型走 ForwardAsChatCompletions 的 isResponsesShape
分支时,Cursor 发的 prompt_cache_retention / safety_identifier 会
原样透传给 Codex 上游,触发:
Unsupported parameter: prompt_cache_retention
根因分析:
- 正常 Chat Completions 路径从 ChatCompletionsRequest 结构体重新
marshal,未知字段被自动丢弃,不受影响
- isResponsesShape 分支为了保留 Cursor 的 input 数组,走的是 raw body
透传(sjson 只改 model),所以需要显式 strip 通用不支持字段
- 覆盖所有账号类型(OAuth + API Key),不依赖 applyCodexOAuthTransform
修复:在 isResponsesShape 分支的 sjson.SetBytes(model) 之后,循环
sjson.DeleteBytes 剥掉 cursorResponsesUnsupportedFields 列表中的字段。
列表与 openai_gateway_service.go:2034 的 Forward 路径语义对齐。
新增测试 TestCursorMixedShape_StripsUnsupportedFields 覆盖该路径。
Cursor 云端发的 body 里除了 prompt_cache_retention / safety_identifier,
还带 metadata(自定义请求元数据),Codex 上游同样不支持,报
Unsupported parameter: metadata
追加到 cursorResponsesUnsupportedFields 列表。
同时加一条 debug 级别诊断日志,只在 isResponsesShape 分支命中时打印
最终上游 body 的前 2KB。目的是未来再出现同类"未知不支持字段"问题时,
直接从 docker logs 一次性看到完整 body,避免反复 tcpdump 打地鼠。
debug level,不影响生产环境(默认 info)。
新增剥离字段:
- stream_options (Cursor 带 {"include_usage":true},Codex 上游不支持)
诊断日志升级:
原诊断日志只打印前 2KB body,对 80KB+ 的 Cursor 请求只能看到 system
prompt 开头,看不到真正的参数字段(stream_options/metadata 这些都在
body 尾部)。改成调用新增的 collectTopLevelKeys(),一次性打印所有
顶层 JSON key,便于一轮触发就能看到 Cursor 发了哪些字段,快速找全
所有不支持参数,避免反复 build/deploy 打地鼠。
测试 TestCollectTopLevelKeys 覆盖新 helper。
|
Thank you for your contribution! Before we can merge this PR, we need you all to sign our Contributor License Agreement (CLA). To sign, please reply with the following comment:
You only need to sign once — it will be valid for all your future contributions to this project. I have read the CLA Document and I hereby sign the CLA 0 out of 2 committers have signed the CLA. |
# Conflicts: # backend/internal/service/openai_codex_transform.go # backend/internal/service/openai_codex_transform_test.go # backend/internal/service/openai_cursor_warmup_pipeline_test.go # backend/internal/service/openai_gateway_chat_completions.go
No description provided.