Skip to content

refactor(provider): 统一生成重试为首包超时与流空闲超时#462

Merged
phantom5099 merged 11 commits into1024XEngineer:mainfrom
phantom5099:main
Apr 26, 2026
Merged

refactor(provider): 统一生成重试为首包超时与流空闲超时#462
phantom5099 merged 11 commits into1024XEngineer:mainfrom
phantom5099:main

Conversation

@phantom5099
Copy link
Copy Markdown
Collaborator

背景

当前生成链路的重试与超时语义在不同 provider 之间并不一致:

  • OpenAI-compatible / Anthropic 主要依赖 SDK 自带 retry
  • Gemini 维护 provider 内部重试逻辑
  • 首包等待与长流读取被单一 timeout 粗暴绑定

这会导致首包前失败恢复不稳定、长流容易被误杀,以及不同 provider 在同类错误上的表现漂移。

本次改动

统一 provider 级生成尝试语义

  • 引入 provider 公共 attempt runner,统一管理首包超时、流空闲超时和重试边界。
  • 将“流已开始”的判定统一收敛到 provider 公共层,只认 text deltatool call starttool call delta
  • message_done 收敛为完成态,避免完成后仍落入 start timeout / idle timeout 分支。
  • 统一约束为“首包前可重试、首包后不重试”,避免重复输出和重复 tool call。

新增 provider 级生成控制配置

  • 新增以下 provider 配置项:
    • generate_max_retries
    • generate_start_timeout_sec
    • generate_idle_timeout_sec
  • 配置缺省时仍按默认值运行,旧配置缺少新字段时可以直接启动。
  • runtime 层统一消费归一化后的生成控制参数,不把厂商差异上抬到上层链路。

收敛 OpenAI-compatible 内部边界

  • 生成请求在进入统一 retry runner 前冻结,避免重试时重复构造 payload。
  • 显式关闭 SDK 内建 retry,避免与外层 retry 叠加。
  • 将 OpenAI-compatible 的 HTTP client 结构收敛为生成链路和 discovery 链路两套明确 client。
  • 保持第三方 chat 端口适配、weak SSE fallback、compatible parser 现有语义不变,只在其外层收敛统一的生成尝试控制。

配置校验与 custom provider 行为收紧

  • 生成控制字段进入正式校验,非法值不再被静默吞掉。
  • custom provider 的保存/加载路径复用同一套校验语义,不再形成独立规则分支。
  • 未显式设置的默认生成控制字段不主动写回 YAML,避免无意义配置噪音。

其他修正

  • 收回 gateway launcher 的绝对路径判断,避免在 Windows 上放宽到依赖当前 drive 的路径解释。
  • 补齐 provider/config/gateway launcher 相关回归测试,覆盖新的重试、超时、配置和边界语义。

测试与验证

已确认通过:

go test ./internal/provider/... ./internal/config/... ./internal/gateway/launcher/...

已知问题

  • TUI 最小窗口判断与提示文案仍不一致:实际阈值已经调整,但提示文案没有同步更新。
  • 当前工作区 PR 范围偏宽,除了 provider/config/gateway 主线外,还混入了主线外文件改动,提交前建议进一步收敛。

风险与后续

  • 首包后失败仍然不会自动重试,这是本次保留的行为边界,用于避免重复文本输出、重复 tool call 和重复副作用。
  • 第三方 chat 端口适配层本次没有重构,只是在外层统一生成尝试控制;若后续需要继续收敛,应单独拆出后续工作。

@chatgpt-codex-connector
Copy link
Copy Markdown

Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits.
Credits must be used to enable repository wide code reviews.

Copy link
Copy Markdown

@fennoai fennoai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Completed 4-pass review (code quality, performance, security, documentation). I found 2 noteworthy issues after deduplication.


// validateOptionalNonNegativeGenerateControl 校验可选的整型生成控制字段,拒绝会被运行时静默吞掉的负数输入。
func validateOptionalNonNegativeGenerateControl(field string, value int) error {
if value < 0 {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

generate_max_retries currently only rejects negative values, so very large positive values are accepted and later used directly by the retry loop (for attempt := 0; attempt <= maxRetries; attempt++). This can create extremely long-running runs (effectively a local DoS via misconfiguration). Consider enforcing a sane upper bound during config validation (and documenting that bound).

Comment thread docs/config-management-detail-design.md Outdated

当前只接受明确受支持的字段;未知字段会直接报错,不做“旧格式自动迁移”。
`provider.yaml` 只支持平铺字段:`name/driver/base_url/api_key_env/model_source/chat_endpoint_path/discovery_endpoint_path/models`。
`provider.yaml` 只支持平铺字段:`name/driver/base_url/api_key_env/model_source/chat_endpoint_path/discovery_endpoint_path/generate_max_retries/generate_start_timeout_sec/generate_idle_timeout_sec/models`。
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The supported provider.yaml field list is now edited but still omits chat_api_mode, while code accepts it (customProviderFile.ChatAPIMode). This line should include chat_api_mode to keep docs aligned with actual accepted fields.

@phantom5099
Copy link
Copy Markdown
Collaborator Author

/code 修复编译报错ok neo-code/internal/provider/anthropic 0.008s coverage: 65.1% of statements

neo-code/internal/provider/gemini [neo-code/internal/provider/gemini.test]

Error: internal/provider/gemini/provider_test.go:604:6: undefined: isRetryableGenerateError
Error: internal/provider/gemini/provider_test.go:607:6: undefined: isRetryableGenerateError
Error: internal/provider/gemini/provider_test.go:610:7: undefined: isRetryableGenerateError
Error: internal/provider/gemini/provider_test.go:629:13: undefined: generateRetryBackoff
Error: internal/provider/gemini/provider_test.go:634:11: undefined: generateRetryBackoff
Error: internal/provider/gemini/provider_test.go:638:13: undefined: generateRetryMaxWait
Error: internal/provider/gemini/provider_test.go:639:68: undefined: generateRetryMaxWait
Error: internal/provider/gemini/provider_test.go:643:12: undefined: waitForRetry
Error: internal/provider/gemini/provider_test.go:648:12: undefined: waitForRetry
Error: internal/provider/gemini/provider_test.go:651:12: undefined: waitForRetry
Error: internal/provider/gemini/provider_test.go:651:12: too many errors
ok neo-code/internal/provider/builtin 0.007s coverage: 72.7% of statements
ok neo-code/internal/provider/catalog 0.182s coverage: 90.7% of statements
ok neo-code/internal/provider/conformance 0.023s coverage: [no statements]
FAIL neo-code/internal/provider/gemini [build failed]
并提高测试覆盖率,修复review的问题

@fennoai
Copy link
Copy Markdown

fennoai Bot commented Apr 25, 2026

处理结果

已按触发评论完成修复并推送到当前 PR 分支 phantom5099:main(commit: 526ed66)。

  1. 修复 gemini 编译报错
  • 删除了 internal/provider/gemini/provider_test.go 中对已迁移/移除私有符号的测试引用:
    • isRetryableGenerateError
    • generateRetryBackoff
    • generateRetryMaxWait
    • waitForRetry
  • 保留并继续覆盖现有可用的错误归一化/超时判定逻辑测试。
  1. 修复 review 问题
  • generate_max_retries 增加上限约束(<= 20):
    • internal/provider/constants.go 新增 MaxGenerateMaxRetries = 20
    • NormalizeGenerateMaxRetries 对超上限值做裁剪
    • internal/config/provider.go 校验 generate_max_retries 超上限时报错
    • internal/config/provider_test.go 补充超上限校验用例
    • internal/provider/constants_test.go 新增归一化/裁剪测试
  • 文档同步 chat_api_mode 字段遗漏与重试上限说明:
    • docs/config-management-detail-design.md
    • docs/guides/adding-providers.md
    • docs/guides/configuration.md
  1. 验证
  • go test ./internal/provider/... ./internal/config/... ./internal/gateway/launcher/...
  • go test -cover ./internal/provider/gemini ./internal/config
    • internal/provider/gemini: 69.5%
    • internal/config: 91.7%

未完成项:无。

View job run

Generated with [codeagent](https://github.com/qbox/codeagent)
Co-authored-by: phantom5099 <245659304+phantom5099@users.noreply.github.com>
@phantom5099
Copy link
Copy Markdown
Collaborator Author

@xgopilot 批判性review整个PR,分析所有潜在风险点,找出所有漏洞,确保每个地方的修改不是退步的,检查方案上的设计是否合理,且不能碎片化,更不能妥协式兼容或兜底旧代码,不许输出正向表扬

@fennoai
Copy link
Copy Markdown

fennoai Bot commented Apr 25, 2026

审查结论(仅问题)

  1. 高风险:取消语义可能被吞掉,导致已取消请求被判定为成功

    • 位置:internal/provider/generate_attempt.go:137internal/provider/generate_attempt.go:142internal/provider/generate_attempt.go:216
    • 问题:runOncephase == generateAttemptPhaseCompleted 时直接返回成功,优先级高于 ctx.Err() 检查。phase 的更新又发生在事件转发前(先 updateGenerateAttemptPhase,后 emitStreamEvent)。这意味着当上层已取消但底层仍吐出 message_done 时,取消错误可被“完成态短路”吞掉。
    • 影响:运行态可能把“用户/系统已取消”的一次生成误判为成功完成,产生状态错判与终止语义漂移。
    • 建议:取消状态应优先于 completed 短路;至少需要同时确认 message_done 已成功转发并且上游未取消。
  2. 中风险:generate_max_retries 无法显式关闭重试,配置语义存在陷阱

    • 位置:internal/provider/constants.go:29internal/provider/constants.go:31internal/config/provider.go:134
    • 问题:NormalizeGenerateMaxRetries<=0 统一回退到默认 5,而 Validate 又允许 0。结果是显式配置 generate_max_retries: 0 仍会变成 5(总共最多 6 次尝试)。
    • 影响:运维侧无法通过配置实现“禁用重试”;在故障窗口会放大等待时间和请求成本,不符合“控制参数可控”的直觉语义。
    • 建议:区分“未设置”和“显式 0”(如指针字段或独立 unset 标记),让 0 真正表示不重试。
  3. 中风险:runtime 级旧重试逻辑残留,方案边界出现碎片化

    • 位置:internal/runtime/runtime.go:27internal/runtime/run_lifecycle.go:208internal/runtime/run_lifecycle.go:218
    • 问题:PR 已把重试下沉到 provider 公共 runner,但 runtime 侧仍保留 defaultProviderRetryMax / providerRetryBackoff / isRetryableProviderError 等旧符号(当前未被主链路使用)。
    • 影响:代码语义分叉,后续维护时容易误接回旧分支,造成重试策略再次双轨漂移。
    • 建议:彻底删除 runtime 侧遗留重试符号或显式标注弃用并加守护测试,避免回归。
  4. 中风险:重试观测能力被移除且无替代事件,排障可见性下降

    • 位置:internal/runtime/events.goprovider_retry 删除)、internal/runtime/run.go:186internal/tui/core/app/update.go:1597
    • 问题:事件 provider_retry 被移除后,provider 层重试过程对 runtime/tui 不再可见,且当前没有新增等价的 attempt 观测事件。
    • 影响:线上定位“首包前重试风暴”“重试次数异常”会显著困难,尤其在多 provider 并存时。
    • 建议:增加统一的 provider-attempt 观测事件(至少包含 attempt 序号、错误分类、等待时长)。

范围说明

  • 本次按 origin/main...HEAD 对 PR 全量变更做了批判性审查(含 provider/config/runtime/gateway/tui/docs)。
  • 仅给出风险与退步点;未实施任何代码修改。

View job run

@1024XEngineer 1024XEngineer deleted a comment from fennoai Bot Apr 25, 2026
@phantom5099
Copy link
Copy Markdown
Collaborator Author

审查结论(仅问题)

  1. 高风险:取消语义可能被吞掉,导致已取消请求被判定为成功

    • 位置:internal/provider/generate_attempt.go:137internal/provider/generate_attempt.go:142internal/provider/generate_attempt.go:216
    • 问题:runOncephase == generateAttemptPhaseCompleted 时直接返回成功,优先级高于 ctx.Err() 检查。phase 的更新又发生在事件转发前(先 updateGenerateAttemptPhase,后 emitStreamEvent)。这意味着当上层已取消但底层仍吐出 message_done 时,取消错误可被“完成态短路”吞掉。
    • 影响:运行态可能把“用户/系统已取消”的一次生成误判为成功完成,产生状态错判与终止语义漂移。
    • 建议:取消状态应优先于 completed 短路;至少需要同时确认 message_done 已成功转发并且上游未取消。
  2. 中风险:generate_max_retries 无法显式关闭重试,配置语义存在陷阱

    • 位置:internal/provider/constants.go:29internal/provider/constants.go:31internal/config/provider.go:134
    • 问题:NormalizeGenerateMaxRetries<=0 统一回退到默认 5,而 Validate 又允许 0。结果是显式配置 generate_max_retries: 0 仍会变成 5(总共最多 6 次尝试)。
    • 影响:运维侧无法通过配置实现“禁用重试”;在故障窗口会放大等待时间和请求成本,不符合“控制参数可控”的直觉语义。
    • 建议:区分“未设置”和“显式 0”(如指针字段或独立 unset 标记),让 0 真正表示不重试。
  3. 中风险:runtime 级旧重试逻辑残留,方案边界出现碎片化

    • 位置:internal/runtime/runtime.go:27internal/runtime/run_lifecycle.go:208internal/runtime/run_lifecycle.go:218
    • 问题:PR 已把重试下沉到 provider 公共 runner,但 runtime 侧仍保留 defaultProviderRetryMax / providerRetryBackoff / isRetryableProviderError 等旧符号(当前未被主链路使用)。
    • 影响:代码语义分叉,后续维护时容易误接回旧分支,造成重试策略再次双轨漂移。
    • 建议:彻底删除 runtime 侧遗留重试符号或显式标注弃用并加守护测试,避免回归。
  4. 中风险:重试观测能力被移除且无替代事件,排障可见性下降

    • 位置:internal/runtime/events.goprovider_retry 删除)、internal/runtime/run.go:186internal/tui/core/app/update.go:1597
    • 问题:事件 provider_retry 被移除后,provider 层重试过程对 runtime/tui 不再可见,且当前没有新增等价的 attempt 观测事件。
    • 影响:线上定位“首包前重试风暴”“重试次数异常”会显著困难,尤其在多 provider 并存时。
    • 建议:增加统一的 provider-attempt 观测事件(至少包含 attempt 序号、错误分类、等待时长)。

范围说明

  • 本次按 origin/main...HEAD 对 PR 全量变更做了批判性审查(含 provider/config/runtime/gateway/tui/docs)。
  • 仅给出风险与退步点;未实施任何代码修改。

View job run

@xgopilot 只修复第二个第三个,其中第二个改成<0即可

@fennoai
Copy link
Copy Markdown

fennoai Bot commented Apr 25, 2026

完成情况

已按你的要求仅修复第 2、3 项,并已推送到当前 PR 分支(phantom5099:main):7226ec1

本次修改

  1. 第 2 项(generate_max_retries 语义)
  • internal/provider/constants.go
    • NormalizeGenerateMaxRetries<= 0 回退默认改为 < 0 回退默认。
    • 现在显式配置 generate_max_retries: 0 会保留为 0(即禁用额外重试)。
  • internal/provider/constants_test.go
    • 同步测试断言:0 不再回退默认。
  • internal/config/provider_test.go
    • 同步运行时配置映射断言到新语义(默认值场景下 GenerateMaxRetries0)。
  • 受语义变化影响,补充了重试相关用例入参,显式设置需要重试的测试值:
    • internal/provider/gemini/provider_test.go
    • internal/provider/openaicompat/openaicompat_test.go
  1. 第 3 项(清理 runtime 旧重试残留)
  • internal/runtime/runtime.go
    • 删除未使用的 runtime 级重试常量:defaultProviderRetryMaxproviderRetryBaseWaitproviderRetryMaxWait
  • internal/runtime/run_lifecycle.go
    • 删除未使用的旧重试辅助函数:isRetryableProviderErrorproviderRetryBackoff
    • 清理对应无用 import。

验证

已通过:

  • go test ./internal/provider/... ./internal/runtime/... ./internal/config/...

未处理项

按你的要求,未处理第 1 项和第 4 项。

View job run

…ftovers

Generated with [codeagent](https://github.com/qbox/codeagent)
Co-authored-by: phantom5099 <245659304+phantom5099@users.noreply.github.com>
@pionxe
Copy link
Copy Markdown
Collaborator

pionxe commented Apr 25, 2026

@xgopilot 请你分析该pr是否与 #461 有出入?或者说有实现不一致?

@fennoai
Copy link
Copy Markdown

fennoai Bot commented Apr 25, 2026

结论

有出入,且存在实现不一致。#461 不是 PR,而是一个实现 Issue;当前 #462 主体方向大体沿着 #461 落地,但至少有 3 处关键偏差。

不一致点

  1. generate_max_retries 语义与 refactor(provider): 统一生成重试为“60 秒首包窗口 + 300 秒流空闲超时”,收敛三家 provider 生成语义 #461 明确约束不一致。
    refactor(provider): 统一生成重试为“60 秒首包窗口 + 300 秒流空闲超时”,收敛三家 provider 生成语义 #461 写的是“<= 0 回填默认 5,且本期不支持 0 显式关闭重试”。当前代码已改为“仅 < 0 回填,0 保留为 0”。
  • internal/provider/constants.go:31-39< 0 才回填)
  • internal/provider/constants_test.go:13zero keeps explicit value
  • internal/config/provider_test.go:785(默认映射场景下期望 GenerateMaxRetries: 0
  1. 生成控制字段对负数的处理与 refactor(provider): 统一生成重试为“60 秒首包窗口 + 300 秒流空闲超时”,收敛三家 provider 生成语义 #461 不一致。
    refactor(provider): 统一生成重试为“60 秒首包窗口 + 300 秒流空闲超时”,收敛三家 provider 生成语义 #461 约束是 <= 0 归一化到默认值;当前实现对负数直接校验失败(不再走归一化)。
  1. 文档与实现已出现“自相矛盾”。
    文档仍写 <= 0 回退默认,但代码对 generate_max_retries=0 与负数的行为已变更。
  • 文档:docs/guides/configuration.md:183-185docs/guides/adding-providers.md:113
  • 代码:internal/provider/constants.go:31-39internal/config/provider.go:125-151

范围偏移(非主语义,但与 #461 任务边界有出入)

补充

View job run

@phantom5099
Copy link
Copy Markdown
Collaborator Author

@xgopilot 提高测试覆盖率

@fennoai
Copy link
Copy Markdown

fennoai Bot commented Apr 26, 2026

处理结果

已按“提高测试覆盖率”完成补测并推送到当前 PR 分支。

  • 提交:1e48b59
  • 变更文件:
    • internal/provider/generate_attempt_test.go
    • internal/provider/constants_test.go

覆盖提升点

新增测试覆盖了此前薄弱分支:

  • internal/provider/generate_attempt.go
    • RunGenerateWithRetry: 0.0% -> 100.0%
    • waitForRetry: 0.0% -> 85.7%
    • stopTimer/resetTimer: 均提升到 100.0%
    • 补齐了重试等待错误、重试耗尽、阶段流转、有效 payload 判定等分支
  • internal/provider/constants.go
    • NormalizeGenerateStartTimeout: 66.7% -> 100.0%
    • NormalizeGenerateIdleTimeout: 66.7% -> 100.0%

验证

已通过:

  • go test ./internal/provider/...
  • go test -coverprofile=/tmp/cover2.out ./internal/provider/... ./internal/config/... ./internal/runtime/... ./internal/gateway/launcher/...

推送信息

未做内容:本次未修改业务逻辑,仅补测试覆盖。

View job run

xgopilot and others added 2 commits April 26, 2026 08:33
…verage

Generated with [codeagent](https://github.com/qbox/codeagent)
Co-authored-by: phantom5099 <245659304+phantom5099@users.noreply.github.com>
test(provider): improve coverage for generate attempt helpers
@pionxe
Copy link
Copy Markdown
Collaborator

pionxe commented Apr 26, 2026

@xgopilot

  1. 请你详细解析新增的 provider 配置项,具体含义以及为了做什么?
  2. 请你分析是真的解决了首包前失败恢复不稳定、长流容易被误杀等问题吗?

@fennoai
Copy link
Copy Markdown

fennoai Bot commented Apr 26, 2026

结论先说

  1. 这次新增/收敛后的生成控制参数,核心是把“重试边界 + 首包超时 + 流空闲超时”统一到 provider 公共层执行,不再各家 provider 各搞一套。
  2. 你提到的两个问题,主干上是被实质修复了
  • 首包前失败恢复不稳定:通过统一 attempt runner + 统一可重试判定,已显著收敛。
  • 长流容易被误杀:通过把“首包等待”和“流空闲”拆分为两套计时器并按阶段切换,已显著改善。
  1. 但仍有边界风险:完成态/取消态竞争(已在前序 review 提过)仍可能带来语义漂移,不影响你问的两条主问题结论,但属于残留风险。

1) 新增配置项逐项解析(含“为了做什么”)

配置项 位置 含义 主要目的
generate_max_retries provider.yaml(provider 级) 额外重试次数(不含首次) 控制“首包前失败”的恢复次数与上限
generate_start_timeout_sec config.yaml 顶层(全局) 从发起生成到收到首个有效 payload 的最长等待 防止首包卡死,触发可控失败/重试
generate_idle_timeout_sec provider.yaml(provider 级) 首包后连续无有效 payload 的最大空闲窗口 防止流中途挂死,避免无穷等待

关键代码证据:

  • RuntimeConfig 接入字段:internal/provider/contracts.go:19-34
  • config -> runtime 映射:internal/config/provider.go:274-289
  • 解析选中 provider 时注入 start timeout:internal/config/provider.go:58-64

补充语义细节:

  • generate_max_retries 现在是 <0 回退默认值 5,0 保留为 0(即禁用额外重试)internal/provider/constants.go:31-40,测试 internal/provider/constants_test.go:16-20
  • 上限限制为 <=20internal/provider/constants.go:17-18internal/config/provider.go:133-141
  • generate_idle_timeout_sec / generate_start_timeout_sec 对非正值做默认回退:internal/provider/constants.go:42-56
  • generate_start_timeout_sec 不允许写进 custom provider.yaml(会被严格拒绝):internal/config/loader_test.go:1426-1450

注意一点实现与文档差异:

  • 文档里还有“generate_max_retries <=0 回退 5”描述(如 docs/guides/configuration.md:183),但当前代码已经是“<0 回退,0 保留”。以代码为准。

2) 是否真的解决了两个问题?

A. 首包前失败恢复不稳定

判断:是,核心问题已解决(且是结构性收敛,不是补丁式)。

依据:

  • 三家 provider 统一走公共 runner:
    • OpenAI-compatible:internal/provider/openaicompat/provider.go:191-205
    • Gemini:internal/provider/gemini/provider.go:97-102
    • Anthropic:internal/provider/anthropic/provider.go:79-84
  • runner 明确“仅首包前可重试;首包后不重试”:internal/provider/generate_attempt.go:94-105:162-167
  • “流已开始”定义统一为 text_delta/tool_call_start/tool_call_deltainternal/provider/generate_attempt.go:280-287
  • OpenAI SDK 内建 retry 被关闭,避免双重重试策略叠加:internal/provider/openaicompat/generate_sdk.go:433-437
  • 回归测试覆盖首包前重试与首包后不重试:internal/provider/generate_attempt_test.go:13-85

B. 长流容易被误杀

判断:是,主要误杀路径已被切开并治理。

依据:

  • startTimeoutidleTimeout 两套独立计时器:internal/provider/generate_attempt.go:180-211
  • 进入 streaming 后停止首包计时并开启/重置 idle 计时:internal/provider/generate_attempt.go:217-224
  • 收到 message_done 后进入完成态并停止计时器:internal/provider/generate_attempt.go:226-231:264-267
  • 验证“idle timeout 触发后不再重试”:internal/provider/generate_attempt_test.go:124-155
  • 验证“message_done 后不会再触发 start timeout”:internal/provider/generate_attempt_test.go:158-185

残留边界(不是你这两问的主结论,但建议关注)

  • 完成态与取消态竞争仍可能吞取消(phase==completed 优先返回成功):internal/provider/generate_attempt.go:137-143
  • 因为“有效 payload”只认三类事件,若某 provider 长时间只产出其他事件类型,仍可能命中 start/idle 超时(这是当前设计取舍)。

本次执行范围

  • 仅做代码与测试语义分析,没有修改代码。

View job run

@phantom5099 phantom5099 merged commit bb1152b into 1024XEngineer:main Apr 26, 2026
3 checks passed
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.

3 participants