feat: switch CloudRewrite from Cerebras to Azure OpenAI gpt-5.4-mini#24
Conversation
…4-mini
Replace Cerebras API with Azure OpenAI for ASR post-processing rewrite.
- Remove model probe logic (preferredModels, modelProbeTask, probeAvailableModel, ModelListResponse) — Azure uses fixed deployment names
- Change endpoint to Azure format: {endpoint}/openai/deployments/{name}/chat/completions?api-version=2024-10-21
- Change auth header from `Authorization: Bearer` to `api-key`
- Remove `model` field from request body (deployment name is in the URL)
- Update generate-secrets.sh to handle AZURE_OPENAI_API_KEY and AZURE_OPENAI_ENDPOINT
- Update tests (CloudRewriteServiceTests, ASRPipelineBenchmarkTests) for new API
- Update AnalyticsService to reference new GeneratedSecrets property
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
👀 Code Review — Linus 式审查
总评:干净利落的重构。 删了 70 多行 model probe 逻辑,换成 Azure 固定 deployment 的直连——这才是正确的做法。复杂性就该在不需要的时候杀掉,而不是留着"以防万一"。
不过有几个问题需要关注:
发现的问题
1. completionsURL 构造失败时抛了错误的 Error(Bug,中等严重)
rewrite() 方法里,当 completionsURL 返回 nil 时,抛的是 CloudRewriteError.invalidResponse。这个语义完全不对——URL 构造失败不是 "invalid response",这是一个配置错误。日志里会记录 invalid_response,排查问题的人会去查 API 返回值而不是检查 endpoint 配置。应该加一个 .invalidConfiguration 或类似的 case。
2. Benchmark 测试里 cloudRewriteAvailable 被硬编码为 true(Bug,低严重)
cloudRewriteService = CloudRewriteService()
cloudRewriteAvailable = true // ← 无条件 true之前的逻辑会检查 API key 是否存在来决定可用性。现在无条件标记为 true,但实际上 CloudRewriteService() 初始化不保证 endpoint 和 API key 都配置了。如果 CI 环境没有 Azure 凭证,benchmark 测试里会执行 cloud rewrite 测试但每次都 passthrough——这不是 crash,但测试结果会误导(标记为已执行 cloud rewrite,实际没有做任何 rewrite)。
3. AnalyticsService 中 UserDefaults key "cloudRewriteAPIKey" 未更新(遗留问题,低严重)
hasCloudRewriteAPIKey 仍然检查 UserDefaults 的 "cloudRewriteAPIKey" key,但后端已经切换到 Azure。如果用户之前在设置里配了 Cerebras key,这个检查会返回 true,但 CloudRewriteService 根本不会用这个 key。虽然这只影响 analytics 上报的一个 boolean,不影响功能,但属于技术债。
评分
| 维度 | 分值 | 说明 |
|---|---|---|
| 正确性 | 2.5/3 | invalidResponse 语义错误;benchmark cloudRewriteAvailable 硬编码 |
| 简洁性 | 2/2 | 删除了大量不需要的 model probe 代码,干净 |
| 可读性 | 2/2 | 命名清晰,completionsURL 计算属性一目了然 |
| 可维护性 | 1.5/2 | AnalyticsService 残留旧 UserDefaults key |
| 安全性 | 1/1 | XOR 混淆正确扩展到了 endpoint,api-key header 用法符合 Azure 规范 |
总分:9/10 ✅ APPROVE
代码整体质量很好。核心重构逻辑正确,API 迁移干净利落,测试也跟着更新了。上面标注的问题建议后续修复,不阻塞合并。
gpt-5.4-mini does not support the legacy max_tokens parameter, returning HTTP 400. Switch to max_completion_tokens as required by newer Azure OpenAI models. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1. Add `invalidConfiguration` error case to CloudRewriteError for when completionsURL fails to construct (was misusing `invalidResponse`) 2. Fix hardcoded `cloudRewriteAvailable = true` in benchmark tests — now checks for actual Azure credentials before marking available 3. Update AnalyticsService.hasCloudRewriteAPIKey to check AZURE_OPENAI_API_KEY env var instead of old UserDefaults key Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
👀 Code Review — 第二轮
上一轮提了三个问题,这次全部修好了,干净利落:
- ✅
invalidResponse语义错误 → 改为invalidConfiguration,正确 - ✅
cloudRewriteAvailable硬编码 → 现在正确检查 env var +GeneratedSecrets - ✅
AnalyticsService残留旧UserDefaultskey → 已迁移到新的 Azure 检查逻辑
代码审查完毕,没有新的阻塞问题。重构后整体代码量减少 33 行净减(删了 161 行 model probe 的废话,加了 128 行更简洁的实现),这才是正确的方向——复杂性不该留着"以防万一"。
评分
| 维度 | 分值 | 说明 |
|---|---|---|
| 正确性 | 3/3 | 上轮问题全部修复,边界条件处理正确(空 endpoint、空 API key 均有 guard) |
| 简洁性 | 2/2 | 删除 model probe 逻辑,generate-secrets.sh 用函数提取重复逻辑 |
| 可读性 | 2/2 | 命名清晰,completionsURL 计算属性一目了然 |
| 可维护性 | 2/2 | AnalyticsService 同步更新,旧 Cerebras 引用清理干净 |
| 安全性 | 1/1 | XOR 混淆正确扩展到 endpoint,api-key header 符合 Azure 规范 |
总分:10/10 ✅ APPROVE
Talk is cheap. Show me the code. 你这次 show 的 code 没问题。
Summary
gpt-5.4-mini)Authorization: Bearertoapi-keyheader (Azure OpenAI convention)generate-secrets.shto XOR-obfuscate bothAZURE_OPENAI_API_KEYandAZURE_OPENAI_ENDPOINTfrom.envTest plan
xcodebuild -scheme Typeless -configuration Debug build)CloudRewriteServiceTests)🤖 Generated with Claude Code