pref(provider): Config/Provider 代码质量修复 — 冗余清理与结构重构#150
Merged
Conversation
Codecov Report❌ Patch coverage is 📢 Thoughts on this report? Let us know! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
变更说明
本 PR 对
internal/config和internal/provider包执行了代码质量修复,涵盖错误定义去重、死代码清除、OpenAI 流式解析函数结构重构、网络错误检测加固四个方面。主要改动
1. 消除跨包错误重复(config 层)
文件:
internal/config/selection.goErrDriverNotFound错误变量(与provider.ErrDriverNotFound语义重叠)ErrDriverUnsupported = errors.New("provider driver not supported by current runtime")SelectProvider()和其内部Update回调中的错误返回,从泛化的「未找到」改为语义精确的「驱动不被支持」文件:
internal/config/selection_test.goTestSelectionServiceSelectProviderRejectsUnsupportedDriver断言更新:ErrDriverNotFound→ErrDriverUnsupported设计理由: config 包不应持有 provider 领域的错误定义。当驱动类型不在注册表中时,应表达的是「当前运行时环境不支持该驱动」而非「找不到驱动」。
2. 清除死代码(config 层)
文件:
internal/config/model.goContainsModelID(models []string, model string) bool3. OpenAI consumeStream 结构重构(provider/openai 层)
文件:
internal/provider/openai/openai.go这是本次改动量最大的部分。原始
consumeStream是一个约 120 行的单体函数,包含嵌套闭包和深层 if 分支。重构后提取为以下独立函数:processChunk(闭包)finishStream(闭包)message_done事件 + 组装ChatResponseextractStreamUsage(usage, raw)mergeToolCallDelta(ctx, events, toolCalls, delta)flushDataLines(dataLines, reset, processChunk)finalizeResponse(content, toolCalls, finishReason, usage)关键改进:
finishStream闭包mergeToolCallDelta、flushDataLines、finalizeResponse、extractStreamUsage均为独立函数,可单独编写单元测试附带 bug 修正:
chunkDelta.ToolCallsJSON tag 从错误的"tools"修正为协议要求的"tool_calls"。此 tag 错误会导致 SSE 流中 tool call delta 反序列化失败,tool call 功能完全不可用。4. isNetworkError 双策略重写(transport 层)
文件:
internal/provider/transport/retry.go设计理由: Go 标准库网络操作返回的底层错误通常是
*net.OpError,通过errors.As做类型断言是最可靠的检测方式。消息匹配作为 fallback 兼容被fmt.Errorf包装过的错误场景。变更清单
internal/config/selection.gointernal/config/model.gointernal/config/selection_test.gointernal/provider/openai/openai.gointernal/provider/transport/retry.go测试验证
go build ./...编译通过go test ./internal/config/ ./internal/provider/ ./internal/tui/ -count=1全部通过TestProviderChatConsumesSSE— tool call 事件序列正确(start → delta → message_done)TestSelectionServiceSelectProviderRejectsUnsupportedDriver—ErrDriverUnsupported断言正确isNetworkError双策略覆盖网络超时场景预期收益
consumeStream从单体函数拆分为职责明确的子函数,后续修改 tool call 或 usage 解析逻辑时不再需要在 120 行函数中定位目标代码段chunkDelta.ToolCallsJSON tag 修正确保 tool call streaming 功能正常工作isNetworkError类型断言优先策略减少漏判,重试中间件在网络抖动场景下表现更稳定mergeToolCallDelta、finalizeResponse等)可独立编写单元测试,无需构造完整的 SSE 流模拟风险与回退
Provider.Chat、RetryTransport.RoundTrip、SelectionService.SelectProvider)签名不变errors.Is(err, config.ErrDriverNotFound)做精确匹配需同步改为ErrDriverUnsupported——经搜索确认仅影响测试文件