Skip to content

同步#1789

Open
shuanbao0 wants to merge 9 commits intoWei-Shaw:mainfrom
shuanbao0:main
Open

同步#1789
shuanbao0 wants to merge 9 commits intoWei-Shaw:mainfrom
shuanbao0:main

Conversation

@shuanbao0
Copy link
Copy Markdown

No description provided.

shuanbao and others added 8 commits April 11, 2026 20:42
仅在 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。
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 22, 2026

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:

I have read the CLA Document and I hereby sign the CLA

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.
@shuanbao
@shuanbao0
shuanbao, shuanbao0 seem not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account.
You can retrigger this bot by commenting recheck in this Pull Request. Posted by the CLA Assistant Lite bot.

# 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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant