Skip to content

fix: support model-level priority service tier pricing#1117

Open
dofastted wants to merge 2 commits into
ding113:devfrom
dofastted:fix/openai-priority-pricing
Open

fix: support model-level priority service tier pricing#1117
dofastted wants to merge 2 commits into
ding113:devfrom
dofastted:fix/openai-priority-pricing

Conversation

@dofastted
Copy link
Copy Markdown
Contributor

@dofastted dofastted commented Apr 27, 2026

Summary

This PR adds support for model-level priority service tier pricing, allowing different models to define their own priority tier rates in a structured service_tier_pricing object. The implementation prefers these model-specific priority rates over legacy *_priority top-level fields.

Problem

Previously, the system only supported flat priority tier pricing through top-level fields like input_cost_per_token_priority. This approach had limitations:

  • Could not define model-specific priority rates per tier
  • Long-context pricing for priority tier was not properly scoped
  • No structured way to define complete pricing profiles per service tier

Solution

  1. New service_tier_pricing data structure (src/types/model-price.ts)

    • Added ServiceTierPricing interface with full pricing fields
    • Added service_tier_pricing?: Record<string, ServiceTierPricing> to ModelPriceData
  2. Priority-aware cost calculation (src/lib/utils/cost-calculation.ts)

    • New helper functions: getServiceTierPricing(), resolvePriorityAwareRate()
    • Updated resolveLongContextPricing() and matchLongContextPricing() to accept service tier parameter
    • Priority rate resolution order: service_tier_pricing.priority → legacy *_priority fields → base rates
  3. Integration (src/app/v1/_lib/proxy/response-handler.ts)

    • Passed priority tier flag into long-context pricing matching
    • Ensured billing uses correct rates for priority service tier requests
  4. Field support (src/lib/utils/model-price-fields.ts)

    • Added validation support for service_tier_pricing.* paths
  5. Provider scoring (src/lib/utils/pricing-resolution.ts)

    • Added service_tier_pricing to detail scoring for provider selection

Changes

Core Changes

  • src/types/model-price.ts - Added ServiceTierPricing interface and field
  • src/lib/utils/cost-calculation.ts - Priority-aware pricing resolution (164 additions, 51 deletions)
  • src/app/v1/_lib/proxy/response-handler.ts - Integrate priority tier in billing flow

Supporting Changes

  • src/lib/utils/model-price-fields.ts - Field validation for service tier pricing
  • src/lib/utils/pricing-resolution.ts - Provider detail scoring

Test Coverage

  • tests/unit/lib/cost-calculation-priority.test.ts - Priority tier pricing tests
  • tests/unit/lib/cost-calculation-breakdown.test.ts - Breakdown calculation tests
  • tests/unit/lib/model-price-fields.test.ts - Field validation tests
  • tests/unit/lib/price-data-price-like-fields.test.ts - Price data validation tests
  • tests/unit/lib/utils/pricing-resolution.test.ts - Provider resolution tests
  • tests/integration/billing-model-source.test.ts - Integration billing tests

Testing

Automated Tests

All tests pass:

pnpm vitest run \
  tests/unit/lib/cost-calculation-priority.test.ts \
  tests/unit/lib/cost-calculation-breakdown.test.ts \
  tests/unit/lib/model-price-fields.test.ts \
  tests/unit/lib/price-data-price-like-fields.test.ts \
  tests/unit/lib/utils/pricing-resolution.test.ts \
  tests/integration/billing-model-source.test.ts

Test Coverage Includes

  • Model-specific priority tier rates take precedence over legacy fields
  • Different models can define different priority tier prices
  • Priority tier pricing scoped correctly (only applies when priorityServiceTierApplied=true)
  • Long-context pricing works with priority service tier
  • Cache costs use priority tier rates when applicable

Example Price Data

{
  "input_cost_per_token": 0.000005,
  "output_cost_per_token": 0.00003,
  "input_cost_per_token_priority": 0.00001,
  "service_tier_pricing": {
    "priority": {
      "input_cost_per_token": 0.0000125,
      "output_cost_per_token": 0.000075,
      "cache_read_input_token_cost": 0.00000125,
      "long_context_pricing": {
        "threshold_tokens": 272000,
        "input_multiplier": 2.0
      }
    }
  }
}

Breaking Changes

None - this is backward compatible. Legacy *_priority fields continue to work as fallbacks.

Checklist

  • Code follows project conventions
  • Unit tests added for new functionality
  • Integration tests updated
  • Type definitions updated
  • Field validation rules updated

Enhanced description preserving original author verification steps

Greptile Summary

This PR introduces a structured service_tier_pricing object on ModelPriceData that allows models to define their own priority tier rates, with the resolution order service_tier_pricing.priority → legacy *_priority top-level fields → base rates. The implementation is well-tested and backward-compatible.

  • src/proxy.ts contains unrelated redirect logic (/system-status/{defaultLocale}/status) not mentioned in the PR description — it should be moved to a separate PR to keep the change set coherent.

Confidence Score: 5/5

Safe to merge; no P0/P1 findings in the pricing logic itself.

All pricing-path changes are backward-compatible, resolution order is correct, and the integration test validates the end-to-end billing math. The only findings are a P2 style note about an unrelated proxy redirect bundled into this PR, and the previously-flagged SUPPORTED_LONG_CONTEXT_KEYS omission in model-price-fields.ts.

src/proxy.ts — contains unrelated /system-status redirect that belongs in a separate PR.

Important Files Changed

Filename Overview
src/lib/utils/cost-calculation.ts Core of the PR: adds getServiceTierPricing, getPriorityServiceTierPricing, resolvePriorityAwareRate helpers and threads them through resolveLongContextPricing, calculateRequestCost, and calculateRequestCostBreakdown. Resolution order (service_tier → legacy _priority → base) is correct and backward-compatible.
src/types/model-price.ts Adds ServiceTierPricing interface with all required pricing fields plus long_context_pricing and a catch-all index signature; cleanly extends ModelPriceData with the new service_tier_pricing field.
src/lib/utils/model-price-fields.ts Adds SUPPORTED_SERVICE_TIER_KEYS (spreading SUPPORTED_TOP_LEVEL_BILLING_KEYS + 'long_context_pricing') and updates classifyField/isCoreField. Nested long_context_pricing multiplier keys are unintentionally classified as 'unsupported' because SUPPORTED_LONG_CONTEXT_KEYS is not spread in — flagged in a previous thread.
src/app/v1/_lib/proxy/response-handler.ts Five callsites of matchLongContextPricing updated to pass priorityServiceTierApplied ? 'priority' : null; all function scopes correctly receive priorityServiceTierApplied as a parameter.
src/proxy.ts Adds /system-status → /{defaultLocale}/status redirect logic that is entirely unrelated to the priority pricing feature; should be in a separate PR.
src/lib/utils/pricing-resolution.ts One-line addition of 'service_tier_pricing' to DETAIL_SCORE_OBJECT_FIELDS, allowing providers with richer service tier data to score higher in resolution.
tests/unit/lib/cost-calculation-priority.test.ts Good coverage: service_tier_pricing.priority precedence, non-priority scoping, per-model isolation, and long_context_pricing with multipliers all tested.
tests/integration/billing-model-source.test.ts Integration test verifies end-to-end that gpt-5.5 with service_tier_pricing.priority produces the correct billed cost (87.5) over legacy priority fields.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[Request with priorityServiceTierApplied] --> B{service_tier_pricing.priority\nexists on model?}
    B -- Yes --> C[Use service_tier_pricing.priority rates]
    B -- No --> D{Legacy *_priority\nfield exists?}
    D -- Yes --> E[Use legacy *_priority rate]
    D -- No --> F[Use base rate]
    C --> G[resolvePriorityAwareRate]
    E --> G
    F --> G
    G --> H{long_context_pricing\nin service tier?}
    H -- Yes --> I[matchLongContextPricing\nwith service tier LCP]
    H -- No --> J{long_context_pricing\nat top level?}
    J -- Yes --> K[matchLongContextPricing\nwith top-level LCP + priority base rates]
    J -- No --> L[No long-context multiplier]
    I --> M[calculateRequestCost / calculateRequestCostBreakdown]
    K --> M
    L --> M
Loading
Prompt To Fix All With AI
This is a comment left during a code review.
Path: src/proxy.ts
Line: 517-538

Comment:
**Unrelated `/system-status` alias included in pricing PR**

This block redirects `/system-status``/{defaultLocale}/status` (and handles locale-prefixed variants). It has no connection to model-level priority service tier pricing and is absent from the PR description. If it was meant to be a separate change, keeping it here risks obscuring the review scope and complicates revert/bisect if either change has issues.

How can I resolve this? If you propose a fix, please make it concise.

Reviews (2): Last reviewed commit: "fix: preserve public system status alias" | Re-trigger Greptile

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 27, 2026

📝 Walkthrough

Walkthrough

将服务层级定价(service_tier_pricing)引入定价解析与成本计算链路,更新长上下文定价匹配以接受可选服务层级参数,传播该参数至代理响应处理中的所有相关调用,并新增/更新相应类型与测试覆盖。

Changes

Cohort / File(s) Summary
代理响应处理
src/app/v1/_lib/proxy/response-handler.ts
所有 matchLongContextPricing 调用改为传入基于 priorityServiceTierApplied 的服务层级参数,确保成本计算、流/非流最终化、统计与 Redis/速率限制追踪使用正确的层级定价。
成本计算核心逻辑
src/lib/utils/cost-calculation.ts
新增对 service_tier_pricing 的优先解析;resolveLongContextPricing/matchLongContextPricing 签名改为接受可选 serviceTier 参数;在选择 long-context、cache/input/output 费率时优先使用层级特定字段并回退至遗留/基础字段。
定价类型与字段
src/types/model-price.ts, src/lib/utils/model-price-fields.ts
新增 ServiceTierPricing 类型并在 ModelPriceData 中加入可选 service_tier_pricing 字段;model-price-fields 添加 SUPPORTED_SERVICE_TIER_KEYS 并将 service_tier_pricing.* 识别为受支持字段,调整核心字段判定以包含该前缀。
定价分辨率逻辑
src/lib/utils/pricing-resolution.ts
getDetailScore 中纳入 service_tier_pricing 的评分项,使包含该字段的记录在详细回退选择中获得额外得分。
测试 —— 单元与集成
tests/unit/lib/cost-calculation-breakdown.test.ts, tests/unit/lib/cost-calculation-priority.test.ts, tests/unit/lib/model-price-fields.test.ts, tests/unit/lib/price-data-price-like-fields.test.ts, tests/unit/lib/utils/pricing-resolution.test.ts, tests/integration/billing-model-source.test.ts
新增并扩展测试以覆盖:service_tier_pricing.priority 对 input/output/cache/long-context 定价的优先级与适用条件;字段分类识别;定价解析对 service_tier_pricing 的携带;以及集成层面对 Codex 优先级计费的验证。

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 23.53% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed 标题准确总结了PR的主要变更,即添加对模型级别优先级服务层定价的支持。
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description check ✅ Passed PR描述清晰地解释了问题、解决方案和实现细节,与变更集完全相关。

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions Bot added bug Something isn't working area:core size/M Medium PR (< 500 lines) labels Apr 27, 2026
Copy link
Copy Markdown
Contributor

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

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

Code Review Summary

This PR implements model-level priority service tier pricing support with a clean fallback chain architecture. The changes add a new service_tier_pricing structure that takes precedence over legacy *_priority fields, enabling more flexible pricing configurations per model.

PR Size: M

  • Lines changed: 557 (494 additions, 63 deletions)
  • Files changed: 11 (5 source files, 6 test files)
  • Assessment: Well-scoped feature addition with comprehensive test coverage. No splitting needed.

Issues Found

Category Critical High Medium Low
Logic/Bugs 0 0 0 0
Security 0 0 0 0
Error Handling 0 0 0 0
Types 0 0 0 0
Comments/Docs 0 0 0 0
Tests 0 0 0 0
Simplification 0 0 0 0

Key Implementation Details Verified

  1. Pricing Resolution Chain (src/lib/utils/cost-calculation.ts:125-136)

    • Correct fallback order: serviceTierRate ?? legacyPriorityRate ?? baseRate
    • Properly handles service_tier_pricing.priority.long_context_pricing override
  2. Field Classification (src/lib/utils/model-price-fields.ts:457-484)

    • New SUPPORTED_SERVICE_TIER_KEYS correctly includes billing keys + nested long_context_pricing
    • isCoreField updated to recognize service_tier_pricing.* paths
  3. Detail Score Calculation (src/lib/utils/pricing-resolution.ts:497)

    • service_tier_pricing added to DETAIL_SCORE_OBJECT_FIELDS for proper provider selection
  4. Test Coverage

    • Priority tier precedence: 6 new unit tests covering service tier vs legacy priority fields
    • Long-context priority matching: 1 new test for nested service_tier_pricing.priority.long_context_pricing
    • Field classification: 1 new test verifying service_tier_pricing.priority.* as "supported"
    • Integration: 1 new test for Codex fast path with service tier pricing

Review Coverage

  • Logic and correctness - Clean, proper fallback chains implemented
  • Security (OWASP Top 10) - Clean, no injection risks or data exposure
  • Error handling - Proper null/undefined checks with type guards
  • Type safety - New ServiceTierPricing interface properly defined with index signature
  • Documentation accuracy - Comments match implementation behavior
  • Test coverage - 9 new tests across unit and integration layers
  • Code clarity - Functions are focused, names are descriptive

CLAUDE.md Compliance

  • No emoji in code (Rule 1)
  • Test coverage exceeds 80% threshold (Rule 2)
  • No user-facing strings requiring i18n (internal pricing logic only) (Rule 3)

Automated review by Claude AI

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a new service_tier_pricing structure to handle model-specific pricing for different service tiers, specifically focusing on the 'priority' tier. The cost calculation logic in cost-calculation.ts has been updated to prioritize these new tier-specific rates over legacy priority fields for input, output, cache, and long-context costs. Additionally, the proxy response handler and pricing resolution utilities were updated to support this new data structure, supported by comprehensive integration and unit tests. I have no feedback to provide as there were no review comments to assess.

Comment on lines +62 to +65
const SUPPORTED_SERVICE_TIER_KEYS = new Set([
...SUPPORTED_TOP_LEVEL_BILLING_KEYS,
"long_context_pricing",
]);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Nested long_context_pricing multiplier fields misclassified as "unsupported"

SUPPORTED_SERVICE_TIER_KEYS spreads SUPPORTED_TOP_LEVEL_BILLING_KEYS but not SUPPORTED_LONG_CONTEXT_KEYS. As a result, when pushEntries recurses into service_tier_pricing.priority.long_context_pricing.*, keys like input_multiplier, output_multiplier, cache_creation_input_multiplier, and cache_read_input_multiplier are not in the set. Because those keys also match isPriceLikeFieldPath, classifyField returns "unsupported" for them rather than "supported". Keys that happen to be in both sets (e.g., input_cost_per_token) are classified correctly, so only the multiplier-style keys are affected.

Suggested change
const SUPPORTED_SERVICE_TIER_KEYS = new Set([
...SUPPORTED_TOP_LEVEL_BILLING_KEYS,
"long_context_pricing",
]);
const SUPPORTED_SERVICE_TIER_KEYS = new Set([
...SUPPORTED_TOP_LEVEL_BILLING_KEYS,
...SUPPORTED_LONG_CONTEXT_KEYS,
"long_context_pricing",
]);
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/lib/utils/model-price-fields.ts
Line: 62-65

Comment:
**Nested `long_context_pricing` multiplier fields misclassified as `"unsupported"`**

`SUPPORTED_SERVICE_TIER_KEYS` spreads `SUPPORTED_TOP_LEVEL_BILLING_KEYS` but not `SUPPORTED_LONG_CONTEXT_KEYS`. As a result, when `pushEntries` recurses into `service_tier_pricing.priority.long_context_pricing.*`, keys like `input_multiplier`, `output_multiplier`, `cache_creation_input_multiplier`, and `cache_read_input_multiplier` are not in the set. Because those keys also match `isPriceLikeFieldPath`, `classifyField` returns `"unsupported"` for them rather than `"supported"`. Keys that happen to be in both sets (e.g., `input_cost_per_token`) are classified correctly, so only the multiplier-style keys are affected.

```suggestion
const SUPPORTED_SERVICE_TIER_KEYS = new Set([
  ...SUPPORTED_TOP_LEVEL_BILLING_KEYS,
  ...SUPPORTED_LONG_CONTEXT_KEYS,
  "long_context_pricing",
]);
```

How can I resolve this? If you propose a fix, please make it concise.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: fa3531da8a

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +558 to 560
priorityTierPricing?.cache_creation_input_token_cost_above_272k_tokens ??
priorityTierPricing?.cache_creation_input_token_cost_above_200k_tokens ??
priceData.cache_creation_input_token_cost_above_272k_tokens ??
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Apply tier cache threshold rates when tier base pricing exists

These tier-specific cache_creation_*_above_* rates are collected, but the same function later gates threshold cache billing on hasRealCacheCreationBase/hasRealCacheReadBase, which still only checks top-level priceData.cache_* fields. When a model defines cache base + above-threshold pricing only under service_tier_pricing.priority, priority requests over the threshold are billed with non-threshold cache rates instead of the configured tier threshold rates.

Useful? React with 👍 / 👎.

): ResolvedLongContextPricing | null {
const pricing = priceData.long_context_pricing;
const serviceTierPricing = getServiceTierPricing(priceData, serviceTier);
const pricing = serviceTierPricing?.long_context_pricing ?? priceData.long_context_pricing;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Fall back to top-level long-context config when tier is partial

Selecting serviceTierPricing?.long_context_pricing unconditionally means a partial tier override (for example, overriding multipliers but not threshold_tokens) suppresses the valid top-level long_context_pricing: normalizeThresholdTokens fails and the function returns null, so priority requests stop matching long-context pricing. This should merge/fallback required fields from top-level long-context settings.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/lib/utils/cost-calculation.ts (1)

176-224: ⚠️ Potential issue | 🟡 Minor

增加测试覆盖缺失的长上下文定价服务等级回退场景

代码确实在 Line 181 实现了回退逻辑:当 service_tier_pricing.priority 缺少 long_context_pricing 时,会回退到顶层 priceData.long_context_pricing。同时,Lines 192-224 计算的 baseInputCost/baseOutputCost/baseCacheReadCost 已是 tier 感知的(优先级价格)。这意味着优先级服务等级的基础单价会与顶层长上下文乘数组合

类型定义表明 ServiceTierPricing.long_context_pricing 是可选的(可选字段 + ?? 运算符),说明这个回退设计看似刻意为之。但当前测试套件中缺少明确的测试用例来文档化这个场景:配置 service_tier_pricing.priority 包含基础价格但不包含 long_context_pricing,同时顶层有 long_context_pricing

建议:增加一个测试用例,明确验证当优先级 tier 缺少 long_context_pricing 时,长上下文请求应使用 tier 基础价 × 顶层乘数,以确保这个行为符合预期。

suggested test
test("uses top-level long-context pricing with priority base rates when tier lacks long_context_pricing", () => {
  const usage = { input_tokens: 101, output_tokens: 2 };
  const priceData = makePriceData({
    service_tier_pricing: {
      priority: {
        input_cost_per_token: 4,
        output_cost_per_token: 40,
        // 注意:priority tier 未定义 long_context_pricing
      },
    },
    long_context_pricing: {
      threshold_tokens: 100,
      input_multiplier: 2,
      output_multiplier: 2,
    },
  });
  const cost = calculateRequestCost(usage, priceData, {
    priorityServiceTierApplied: true,
  });
  // 应验证使用了优先级基础价 (4, 40) × 顶层乘数 (2, 2)
  expect(Number(cost.toString())).toBe(172); // 4*2*101 + 40*2*2
});
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/utils/cost-calculation.ts` around lines 176 - 224, Add a unit test
that verifies resolveLongContextPricing (and ultimately calculateRequestCost)
falls back to the top-level long_context_pricing when ServiceTierPricing (e.g.,
service_tier_pricing.priority) lacks long_context_pricing, and that the resolved
long-context costs use the tier-aware base rates (from priority
input_cost_per_token/output_cost_per_token via
resolvePriorityAwareRate/getServiceTierPricing) multiplied by the top-level
multipliers; create a test (similar to the suggested "uses top-level
long-context pricing with priority base rates when tier lacks
long_context_pricing") using makePriceData with priority base rates present but
no long_context_pricing and top-level long_context_pricing present, then assert
the computed cost from calculateRequestCost matches the expected baseRate *
multiplier math.
🧹 Nitpick comments (6)
src/lib/utils/model-price-fields.ts (1)

62-66: SUPPORTED_SERVICE_TIER_KEYS 中的 "long_context_pricing" 实际不可达,且嵌套乘数字段无法被分类为 supported。

pushEntries 在遇到对象值时直接递归而不 push 对应 entry,因此 classifyField 永远不会以 key === "long_context_pricing" 被调用,集合中的该字符串等同于死代码。同时,递归进入 service_tier_pricing.<tier>.long_context_pricing.* 后,键名会变为 input_multiplier / output_multiplier 等,但 SUPPORTED_SERVICE_TIER_KEYS 仅扩展自 SUPPORTED_TOP_LEVEL_BILLING_KEYS(不含这些 multiplier 键),导致这些嵌套字段会被降级为 unsupported

非阻塞,仅影响字段展示分类。如果后续允许 tier 内嵌长上下文乘数,建议把 SUPPORTED_LONG_CONTEXT_KEYS 也合并进来或在 classifyField 中显式处理 service_tier_pricing.*.long_context_pricing.* 路径;否则可移除 "long_context_pricing" 以减少误导。

♻️ 可选改法
 const SUPPORTED_SERVICE_TIER_KEYS = new Set([
   ...SUPPORTED_TOP_LEVEL_BILLING_KEYS,
-  "long_context_pricing",
+  ...SUPPORTED_LONG_CONTEXT_KEYS,
 ]);

Also applies to: 129-143

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/utils/model-price-fields.ts` around lines 62 - 66,
SUPPORTED_SERVICE_TIER_KEYS currently includes "long_context_pricing" which is
never reached because pushEntries recurses on object values without pushing an
entry and classifyField never sees a top-level key === "long_context_pricing";
additionally nested multiplier keys (input_multiplier/output_multiplier) aren’t
in the set so they fall back to unsupported. Fix by either removing the
misleading "long_context_pricing" from SUPPORTED_SERVICE_TIER_KEYS, or merge
SUPPORTED_LONG_CONTEXT_KEYS into SUPPORTED_SERVICE_TIER_KEYS so nested
long_context fields are recognized, or alter classifyField to explicitly treat
the path service_tier_pricing.*.long_context_pricing.* as supported (also apply
the same change where the duplicated logic appears around the other block at the
129-143 area); update pushEntries/classifyField accordingly so nested multiplier
keys are classified correctly.
src/lib/utils/cost-calculation.ts (2)

43-43: ServiceTierName 当前是字面量类型,后续扩展时记得同步 fallback 链。

type ServiceTierName = "priority" 目前与 service_tier_pricing schema 中已定义的 tier 一一对应,可读性好。但 getServiceTierPricing 和所有调用站点都基于这个字面量做控制流(例如 Line 191 serviceTier === "priority" 直接转成 priorityServiceTierApplied 布尔)。

后续若 schema 新增非 priority tier(如 "flex" / "auto"),需要同时:

  1. 扩展该 union;
  2. 重新审视 priorityServiceTierApplied 这个二值化布尔的语义(它隐式假设了"非 priority 即非分层");
  3. 确认 resolvePriorityAwareRate 的 legacy *_priority 字段仅对 priority tier 生效。

当前 PR 不需要立刻处理,标记一下避免后续扩展时漏改。

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/utils/cost-calculation.ts` at line 43, ServiceTierName is currently a
string literal type ("priority") which ties control flow in
getServiceTierPricing and call sites (e.g. the priorityServiceTierApplied
boolean and resolvePriorityAwareRate) to a single-tier assumption; update
ServiceTierName to a union of all possible tiers when you add new tiers, audit
and replace any binary checks like serviceTier === "priority" or
priorityServiceTierApplied with explicit tier-aware logic, and ensure
resolvePriorityAwareRate and legacy *_priority fields are only applied for the
true priority tier; in short, whenever adding a new tier, extend the
ServiceTierName union, revisit uses of priorityServiceTierApplied, and make
resolvePriorityAwareRate explicitly conditional on the priority tier rather than
implicitly assuming any non-priority is "non-tiered".

459-515: calculateRequestCostBreakdowncalculateRequestCost 之间的 tier 解析逻辑大量重复,建议后续抽取共享 helper。

Line 459-515(breakdown)与 Line 749-804(总价)中关于 inputCostPerToken / outputCostPerToken / inputCostPerRequest / cacheCreation5mCost / cacheCreation1hCost / cacheReadCost 的解析几乎逐行一致。本 PR 把每条字段都增补了 priorityTierPricing?.* ?? 前缀,意味着将来 schema 再增字段时这两处必须同步修改 —— 维护风险点。

建议(可延后)抽出一个 resolveBaseRates(priceData, options) 返回完整的 {inputCostPerToken, outputCostPerToken, inputCostPerRequest, cacheCreation5mCost, cacheCreation1hCost, cacheReadCost},两个函数共用。本 PR 内若不便重构,至少加一行注释提示两处需联动维护。

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/utils/cost-calculation.ts` around lines 459 - 515, The logic that
computes inputCostPerToken, outputCostPerToken, inputCostPerRequest,
cacheCreation5mCost, cacheCreation1hCost and cacheReadCost is duplicated between
calculateRequestCostBreakdown and calculateRequestCost; extract a shared helper
(e.g., resolveBaseRates(priceData, options)) that calls
getPriorityServiceTierPricing and resolvePriorityAwareRate and returns {
inputCostPerToken, outputCostPerToken, inputCostPerRequest, cacheCreation5mCost,
cacheCreation1hCost, cacheReadCost } preserving the exact fallback rules
(including cacheCreation1hCost falling back to cacheCreation5mCost) and then
replace the duplicated blocks in calculateRequestCostBreakdown and
calculateRequestCost with calls to resolveBaseRates; if you cannot refactor now,
add a clear TODO comment above both duplicated blocks referencing
resolveBaseRates(priceData, options) so future schema changes are kept in sync.
tests/unit/lib/cost-calculation-priority.test.ts (2)

192-218: long_context_pricing 在 service tier 下的匹配用例覆盖了关键路径。

input_tokens=101 触发 threshold_tokens=100 后,基于 tier 内 input_cost_per_token=4output_cost_per_token=40 与 multiplier=2,得到 101*8 + 2*80 = 968,与 Line 217 断言一致。同时通过 expect(match).not.toBeNull()(Line 216)显式锁定了 tier-aware 的 matchLongContextPricing 行为,这点很好。

可选补充:再加一个对照用例,断言相同 priceDataserviceTiernullmatchLongContextPricing 返回 null(因为顶层 priceData.long_context_pricing 未配置),从而锁死"tier 阈值不会泄漏到非 priority 调用"的行为。

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/unit/lib/cost-calculation-priority.test.ts` around lines 192 - 218, Add
a negative test that verifies tier-specific long_context_pricing does not leak
when no service tier is provided: using the same makePriceData(...) with
service_tier_pricing.priority.long_context_pricing set, call
matchLongContextPricing(usage, priceData, null) (or pass null for the
serviceTier argument) and assert the result is null; this ensures
matchLongContextPricing only returns the tier pricing when a matching
serviceTier (e.g., "priority") is supplied.

19-90: 新增 3 个 priority service tier 用例覆盖到位。

期望值经核对均正确:

  • Line 36 97.5 = 2*3 + 3*30 + 5*0.3(tier 覆盖 legacy)
  • Line 56 32.5 = 2*1 + 3*10 + 5*0.1(非 priority 时退回 base,即使 tier 配置存在)
  • Line 88-89 两组独立 priceData 的单价分别加和

可选改进:Line 59 用例标题为 "allows different models to define different priority tier prices",但实测代码并未参数化模型名,只是用两组不同 priceData 各跑一次。建议改名为类似 "applies provided priority pricing per priceData snapshot",避免读者误以为还覆盖了 model 维度的解析逻辑。

另外建议补一个用例:service_tier_pricing.priority 存在但只覆盖 input_cost_per_token,确认 output / cache_read 仍能回退到 *_priority legacy 字段(当前 "before legacy" 用例完全替换了三个字段,未覆盖部分覆盖场景)。

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/unit/lib/cost-calculation-priority.test.ts` around lines 19 - 90,
Rename the test titled "allows different models to define different priority
tier prices" to "applies provided priority pricing per priceData snapshot" to
avoid implying model-specific behavior, and add one new unit test for
calculateRequestCost that uses makePriceData where service_tier_pricing.priority
only sets input_cost_per_token (leave output and cache_read undefined) to assert
that input uses the priority price while output_tokens and
cache_read_input_tokens fall back to the legacy *_priority fields; reference
calculateRequestCost and makePriceData in the new test and mirror the existing
usage pattern (priorityServiceTierApplied true) to validate partial overrides.
src/app/v1/_lib/proxy/response-handler.ts (1)

1260-1264: 多处调用 matchLongContextPricing 均一致传入了 priority service tier,看起来不错。

四处调用站点(Line 1260-1264、2379-2383、3475-3479、3794-3798)均按 priorityServiceTierApplied ? "priority" : null 派发,与 cost-calculation.ts 中新签名对齐。当未启用 priority tier 时行为保持向后兼容。

可选小重构:这段三元表达式在四个地方完全重复,后续若新增更多 service tier(例如 "flex")时可考虑提取一个本地 helper(例如 resolveServiceTierName(decision)),以便集中演进。当前规模下并非必须。

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/app/v1/_lib/proxy/response-handler.ts` around lines 1260 - 1264, The
ternary expression priorityServiceTierApplied ? "priority" : null is duplicated
across multiple calls to matchLongContextPricing; extract a small helper (e.g.,
resolveServiceTierName(decision) or
resolveServiceTierName({priorityServiceTierApplied})) that centralizes this
logic and returns the appropriate tier string (e.g., "priority") or null, then
replace the inline ternaries at each call site (the calls to
matchLongContextPricing) with a call to that helper so future new tiers (like
"flex") can be added in one place.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@tests/unit/lib/utils/pricing-resolution.test.ts`:
- Around line 229-273: The test currently uses a provider with name "OpenAI" and
URL "https://api.openai.com/v1/responses" which matches pricingMap exact keys so
resolveFromPricingMap returns immediately and never exercises
resolveDetailedFallback or the DETAIL_SCORE_OBJECT_FIELDS changes; update the
test (in pricing-resolution.test.ts) to use a provider that does not match any
exact/official keys (e.g., name "AnonymousProvider" or "Unknown" and a
non-openai URL like "https://api.example.com") so resolvePricingKeyCandidates
will not produce an "exact" hit, thereby forcing resolvePricingForModelRecords
to call resolveDetailedFallback; also change the expected source in the
assertion from the default to "priority_fallback" to confirm the detailed
scoring chose the openai node with service_tier_pricing.

---

Outside diff comments:
In `@src/lib/utils/cost-calculation.ts`:
- Around line 176-224: Add a unit test that verifies resolveLongContextPricing
(and ultimately calculateRequestCost) falls back to the top-level
long_context_pricing when ServiceTierPricing (e.g.,
service_tier_pricing.priority) lacks long_context_pricing, and that the resolved
long-context costs use the tier-aware base rates (from priority
input_cost_per_token/output_cost_per_token via
resolvePriorityAwareRate/getServiceTierPricing) multiplied by the top-level
multipliers; create a test (similar to the suggested "uses top-level
long-context pricing with priority base rates when tier lacks
long_context_pricing") using makePriceData with priority base rates present but
no long_context_pricing and top-level long_context_pricing present, then assert
the computed cost from calculateRequestCost matches the expected baseRate *
multiplier math.

---

Nitpick comments:
In `@src/app/v1/_lib/proxy/response-handler.ts`:
- Around line 1260-1264: The ternary expression priorityServiceTierApplied ?
"priority" : null is duplicated across multiple calls to
matchLongContextPricing; extract a small helper (e.g.,
resolveServiceTierName(decision) or
resolveServiceTierName({priorityServiceTierApplied})) that centralizes this
logic and returns the appropriate tier string (e.g., "priority") or null, then
replace the inline ternaries at each call site (the calls to
matchLongContextPricing) with a call to that helper so future new tiers (like
"flex") can be added in one place.

In `@src/lib/utils/cost-calculation.ts`:
- Line 43: ServiceTierName is currently a string literal type ("priority") which
ties control flow in getServiceTierPricing and call sites (e.g. the
priorityServiceTierApplied boolean and resolvePriorityAwareRate) to a
single-tier assumption; update ServiceTierName to a union of all possible tiers
when you add new tiers, audit and replace any binary checks like serviceTier ===
"priority" or priorityServiceTierApplied with explicit tier-aware logic, and
ensure resolvePriorityAwareRate and legacy *_priority fields are only applied
for the true priority tier; in short, whenever adding a new tier, extend the
ServiceTierName union, revisit uses of priorityServiceTierApplied, and make
resolvePriorityAwareRate explicitly conditional on the priority tier rather than
implicitly assuming any non-priority is "non-tiered".
- Around line 459-515: The logic that computes inputCostPerToken,
outputCostPerToken, inputCostPerRequest, cacheCreation5mCost,
cacheCreation1hCost and cacheReadCost is duplicated between
calculateRequestCostBreakdown and calculateRequestCost; extract a shared helper
(e.g., resolveBaseRates(priceData, options)) that calls
getPriorityServiceTierPricing and resolvePriorityAwareRate and returns {
inputCostPerToken, outputCostPerToken, inputCostPerRequest, cacheCreation5mCost,
cacheCreation1hCost, cacheReadCost } preserving the exact fallback rules
(including cacheCreation1hCost falling back to cacheCreation5mCost) and then
replace the duplicated blocks in calculateRequestCostBreakdown and
calculateRequestCost with calls to resolveBaseRates; if you cannot refactor now,
add a clear TODO comment above both duplicated blocks referencing
resolveBaseRates(priceData, options) so future schema changes are kept in sync.

In `@src/lib/utils/model-price-fields.ts`:
- Around line 62-66: SUPPORTED_SERVICE_TIER_KEYS currently includes
"long_context_pricing" which is never reached because pushEntries recurses on
object values without pushing an entry and classifyField never sees a top-level
key === "long_context_pricing"; additionally nested multiplier keys
(input_multiplier/output_multiplier) aren’t in the set so they fall back to
unsupported. Fix by either removing the misleading "long_context_pricing" from
SUPPORTED_SERVICE_TIER_KEYS, or merge SUPPORTED_LONG_CONTEXT_KEYS into
SUPPORTED_SERVICE_TIER_KEYS so nested long_context fields are recognized, or
alter classifyField to explicitly treat the path
service_tier_pricing.*.long_context_pricing.* as supported (also apply the same
change where the duplicated logic appears around the other block at the 129-143
area); update pushEntries/classifyField accordingly so nested multiplier keys
are classified correctly.

In `@tests/unit/lib/cost-calculation-priority.test.ts`:
- Around line 192-218: Add a negative test that verifies tier-specific
long_context_pricing does not leak when no service tier is provided: using the
same makePriceData(...) with service_tier_pricing.priority.long_context_pricing
set, call matchLongContextPricing(usage, priceData, null) (or pass null for the
serviceTier argument) and assert the result is null; this ensures
matchLongContextPricing only returns the tier pricing when a matching
serviceTier (e.g., "priority") is supplied.
- Around line 19-90: Rename the test titled "allows different models to define
different priority tier prices" to "applies provided priority pricing per
priceData snapshot" to avoid implying model-specific behavior, and add one new
unit test for calculateRequestCost that uses makePriceData where
service_tier_pricing.priority only sets input_cost_per_token (leave output and
cache_read undefined) to assert that input uses the priority price while
output_tokens and cache_read_input_tokens fall back to the legacy *_priority
fields; reference calculateRequestCost and makePriceData in the new test and
mirror the existing usage pattern (priorityServiceTierApplied true) to validate
partial overrides.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 73f5d561-3f19-4739-9458-8531c96a0e56

📥 Commits

Reviewing files that changed from the base of the PR and between 0726ec4 and fa3531d.

📒 Files selected for processing (11)
  • src/app/v1/_lib/proxy/response-handler.ts
  • src/lib/utils/cost-calculation.ts
  • src/lib/utils/model-price-fields.ts
  • src/lib/utils/pricing-resolution.ts
  • src/types/model-price.ts
  • tests/integration/billing-model-source.test.ts
  • tests/unit/lib/cost-calculation-breakdown.test.ts
  • tests/unit/lib/cost-calculation-priority.test.ts
  • tests/unit/lib/model-price-fields.test.ts
  • tests/unit/lib/price-data-price-like-fields.test.ts
  • tests/unit/lib/utils/pricing-resolution.test.ts

Comment on lines +229 to +273
test("provider detail scoring counts service_tier_pricing", () => {
const cloudRecord = makeRecord("gpt-5.5", {
mode: "responses",
model_family: "gpt",
pricing: {
fallback: {
input_cost_per_token: 0.000005,
output_cost_per_token: 0.00003,
},
openai: {
input_cost_per_token: 0.000005,
output_cost_per_token: 0.00003,
service_tier_pricing: {
priority: {
input_cost_per_token: 0.0000125,
output_cost_per_token: 0.000075,
cache_read_input_token_cost: 0.00000125,
},
},
},
},
});

const resolved = resolvePricingForModelRecords({
provider: {
id: 5,
name: "OpenAI",
url: "https://api.openai.com/v1/responses",
} as never,
primaryModelName: "gpt-5.5",
fallbackModelName: null,
primaryRecord: cloudRecord,
fallbackRecord: null,
});

expect(resolved).not.toBeNull();
expect(resolved?.resolvedPricingProviderKey).toBe("openai");
expect(resolved?.priceData.service_tier_pricing).toEqual({
priority: {
input_cost_per_token: 0.0000125,
output_cost_per_token: 0.000075,
cache_read_input_token_cost: 0.00000125,
},
});
});
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

用例名为 “provider detail scoring counts service_tier_pricing”,但实际并未走到 resolveDetailedFallback 的打分路径。

provider 配置 name: "OpenAI"url: "https://api.openai.com/v1/responses" 会在 resolvePricingKeyCandidates 中匹配 name.includes("openai") / host.includes("openai.com"),从而把 "openai" 作为 exact 候选键。在 resolvePricingForModelRecords 中,resolveFromPricingMap(..., "exact") 会立刻命中 pricingMap["openai"] 并返回,根本不会进入 resolveDetailedFallback,因此本 PR 在 DETAIL_SCORE_OBJECT_FIELDS 上的改动并未被该用例真正验证——当前断言即便回退到旧的打分逻辑(不计 service_tier_pricing)也会通过。

建议构造一个无法命中任何 exact/official 键的 provider(例如匿名 provider 或与 pricing map 中两个 key 都不匹配的名称/URL),以真正触发打分分支。

🔍 验证用例改造建议
-    const resolved = resolvePricingForModelRecords({
-      provider: {
-        id: 5,
-        name: "OpenAI",
-        url: "https://api.openai.com/v1/responses",
-      } as never,
+    const resolved = resolvePricingForModelRecords({
+      provider: {
+        id: 5,
+        name: "unknown-aggregator",
+        url: "https://example.invalid/api",
+      } as never,
       primaryModelName: "gpt-5.5",
       fallbackModelName: null,
       primaryRecord: cloudRecord,
       fallbackRecord: null,
     });

并将断言中的 source 从默认改为 "priority_fallback",以确认打分路径选中带 service_tier_pricingopenai 节点。

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
test("provider detail scoring counts service_tier_pricing", () => {
const cloudRecord = makeRecord("gpt-5.5", {
mode: "responses",
model_family: "gpt",
pricing: {
fallback: {
input_cost_per_token: 0.000005,
output_cost_per_token: 0.00003,
},
openai: {
input_cost_per_token: 0.000005,
output_cost_per_token: 0.00003,
service_tier_pricing: {
priority: {
input_cost_per_token: 0.0000125,
output_cost_per_token: 0.000075,
cache_read_input_token_cost: 0.00000125,
},
},
},
},
});
const resolved = resolvePricingForModelRecords({
provider: {
id: 5,
name: "OpenAI",
url: "https://api.openai.com/v1/responses",
} as never,
primaryModelName: "gpt-5.5",
fallbackModelName: null,
primaryRecord: cloudRecord,
fallbackRecord: null,
});
expect(resolved).not.toBeNull();
expect(resolved?.resolvedPricingProviderKey).toBe("openai");
expect(resolved?.priceData.service_tier_pricing).toEqual({
priority: {
input_cost_per_token: 0.0000125,
output_cost_per_token: 0.000075,
cache_read_input_token_cost: 0.00000125,
},
});
});
test("provider detail scoring counts service_tier_pricing", () => {
const cloudRecord = makeRecord("gpt-5.5", {
mode: "responses",
model_family: "gpt",
pricing: {
fallback: {
input_cost_per_token: 0.000005,
output_cost_per_token: 0.00003,
},
openai: {
input_cost_per_token: 0.000005,
output_cost_per_token: 0.00003,
service_tier_pricing: {
priority: {
input_cost_per_token: 0.0000125,
output_cost_per_token: 0.000075,
cache_read_input_token_cost: 0.00000125,
},
},
},
},
});
const resolved = resolvePricingForModelRecords({
provider: {
id: 5,
name: "unknown-aggregator",
url: "https://example.invalid/api",
} as never,
primaryModelName: "gpt-5.5",
fallbackModelName: null,
primaryRecord: cloudRecord,
fallbackRecord: null,
});
expect(resolved).not.toBeNull();
expect(resolved?.resolvedPricingProviderKey).toBe("openai");
expect(resolved?.priceData.service_tier_pricing).toEqual({
priority: {
input_cost_per_token: 0.0000125,
output_cost_per_token: 0.000075,
cache_read_input_token_cost: 0.00000125,
},
});
});
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/unit/lib/utils/pricing-resolution.test.ts` around lines 229 - 273, The
test currently uses a provider with name "OpenAI" and URL
"https://api.openai.com/v1/responses" which matches pricingMap exact keys so
resolveFromPricingMap returns immediately and never exercises
resolveDetailedFallback or the DETAIL_SCORE_OBJECT_FIELDS changes; update the
test (in pricing-resolution.test.ts) to use a provider that does not match any
exact/official keys (e.g., name "AnonymousProvider" or "Unknown" and a
non-openai URL like "https://api.example.com") so resolvePricingKeyCandidates
will not produce an "exact" hit, thereby forcing resolvePricingForModelRecords
to call resolveDetailedFallback; also change the expected source in the
assertion from the default to "priority_fallback" to confirm the detailed
scoring chose the openai node with service_tier_pricing.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
src/proxy.ts (1)

50-54: 裸路径 /system-status 重定向丢失用户语言偏好

当用户访问无语言前缀的 /system-status 时,这里直接重定向到 /${defaultLocale}/status(即 /zh-CN/status),完全忽略了 NEXT_LOCALE cookie 与 Accept-Language 头。对比同文件下方的鉴权重定向(第 122-125 行)以及现有 /statusintlMiddleware 的处理方式,这条别名路径成为唯一不尊重用户语言偏好的入口,会让英文/日文等用户被强制跳转到中文页面。

建议参考下方 getLocaleFromValue(...localeCookieName) 的现有写法挑选目标语言。

♻️ 建议改动
   if (pathname === SYSTEM_STATUS_ALIAS_PATH) {
     const url = request.nextUrl.clone();
-    url.pathname = `/${defaultLocale}/status`;
+    const localeFromCookie = getLocaleFromValue(
+      sanitizedRequest.cookies.get(localeCookieName)?.value
+    );
+    const targetLocale = localeFromCookie ?? routing.defaultLocale;
+    url.pathname = `/${targetLocale}/status`;
     return NextResponse.redirect(url);
   }

如果不打算消费 cookie,也可以直接 url.pathname = "/status" 让下游 intlMiddleware 完成语言协商,但会多一次跳转。

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/proxy.ts` around lines 50 - 54, The redirect for the alias path handled
in the block checking pathname === SYSTEM_STATUS_ALIAS_PATH always forces
url.pathname = `/${defaultLocale}/status`, ignoring the user's NEXT_LOCALE
cookie and Accept-Language negotiation; update this logic to pick the target
locale the same way other redirects do (use getLocaleFromValue(NEXT_LOCALE
cookie) and fall back to Accept-Language/intlMiddleware) before building the
redirect URL or, alternatively, set url.pathname = "/status" and let
intlMiddleware perform locale resolution; adjust the code around
request.nextUrl.clone() / NextResponse.redirect(...) to use the resolved locale
instead of defaultLocale.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@src/proxy.ts`:
- Around line 50-54: The redirect for the alias path handled in the block
checking pathname === SYSTEM_STATUS_ALIAS_PATH always forces url.pathname =
`/${defaultLocale}/status`, ignoring the user's NEXT_LOCALE cookie and
Accept-Language negotiation; update this logic to pick the target locale the
same way other redirects do (use getLocaleFromValue(NEXT_LOCALE cookie) and fall
back to Accept-Language/intlMiddleware) before building the redirect URL or,
alternatively, set url.pathname = "/status" and let intlMiddleware perform
locale resolution; adjust the code around request.nextUrl.clone() /
NextResponse.redirect(...) to use the resolved locale instead of defaultLocale.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 0344b06b-2a12-44bb-8a92-1a8b57dc26c7

📥 Commits

Reviewing files that changed from the base of the PR and between fa3531d and 1ac63c2.

📒 Files selected for processing (1)
  • src/proxy.ts

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1ac63c2b63

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +831 to +832
serviceTierAbove272k: priorityTierPricing?.input_cost_per_token_above_272k_tokens,
serviceTierAbove200k: priorityTierPricing?.input_cost_per_token_above_200k_tokens,
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Include tier fields when detecting long-context threshold

This adds serviceTierAbove272k/200k rates, but threshold activation is still driven by resolveLongContextThreshold(priceData), which does not inspect service_tier_pricing.priority.*_above_* fields. In priority requests where above-threshold rates are defined only under service_tier_pricing (and model_family is not forcing 272k), longContextThresholdExceeded remains false until 1M tokens, so these new tier rates are skipped and mid-range requests are billed at base rates. Threshold detection needs to include the new service-tier above-threshold fields.

Useful? React with 👍 / 👎.

@ding113
Copy link
Copy Markdown
Owner

ding113 commented Apr 28, 2026

您好,项目当前云端价格表位于 https://claude-code-hub.app/config/prices-base.toml ,如果您需要优化相关计价,请优先考虑云端价格表格式和数据。
如果需要添加自定义字段,请确保同步修改了自定义模型价格逻辑。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:core bug Something isn't working size/M Medium PR (< 500 lines)

Projects

Status: Backlog

Development

Successfully merging this pull request may close these issues.

2 participants