Skip to content

refactor(api): centralize service-tier primitives - #1040

Open
WebMad wants to merge 10 commits into
Zoo-Code-Org:mainfrom
WebMad:refactor/service-tier-primitives
Open

refactor(api): centralize service-tier primitives#1040
WebMad wants to merge 10 commits into
Zoo-Code-Org:mainfrom
WebMad:refactor/service-tier-primitives

Conversation

@WebMad

@WebMad WebMad commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Responsibility and scope

Centralizes the shared service-tier primitives used by provider request construction so later stack layers can consume one canonical representation. Tests travel with the behavior in this PR.

Behavior and non-goals

  • Refactor only: there is no behavior change and no request-shape change.
  • Does not add OpenAI Codex Fast priority handling.
  • Does not add settings UI or translations.
  • Does not include the unrelated Task.throttle.test.ts fix.
  • Does not add a changeset.

Test evidence

  • Existing focused coverage was updated/retained with the refactored primitives.
  • Repository type checks passed from the push hook.
  • The completed stack was locally verified before publication.

Stack dependency

  1. This PR — shared service-tier primitives (base: canonical main).
  2. WebMad/Zoo-Code#2 — backend Fast priority persistence/request behavior.
  3. WebMad/Zoo-Code#3 — webview speed selector and translations.

Review and merge this PR first; each subsequent PR is based on the preceding contributor branch.

Summary by CodeRabbit

  • New Features

    • Added/standardized OpenAI service-tier support for Default, Flex, and Priority, including tier-specific pricing in model settings.
    • Standardized service-tier field handling across providers and only shows tier pricing/selection when the selected model supports non-default tiers.
  • Bug Fixes

    • Improved OpenAI streamed and fallback usage/cost calculations to use the resolved service tier (while keeping the requested tier in the outgoing payload).
    • Ensured “standard pricing” is retained when tier-specific pricing doesn’t apply.
  • Tests

    • Expanded coverage for OpenAI and Bedrock service-tier behavior and pricing scenarios.

@coderabbitai

coderabbitai Bot commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 73f8220a-6f0d-4597-b0b8-aba20b24b9b0

📥 Commits

Reviewing files that changed from the base of the PR and between 66ae5a9 and 5f0179c.

📒 Files selected for processing (4)
  • packages/types/src/model.ts
  • src/api/providers/__tests__/openai-native.spec.ts
  • src/api/providers/openai-native.ts
  • webview-ui/src/components/settings/ModelInfoView.tsx
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/api/providers/openai-native.ts
  • webview-ui/src/components/settings/ModelInfoView.tsx

📝 Walkthrough

Walkthrough

OpenAI service tiers are centralized in a shared enum and payload-key constant, then applied to provider request/response handling, pricing calculations, and settings UI components. Tests cover request payloads, resolved-tier pricing, streaming behavior, tier selection, and pricing-table rendering.

Changes

Service tier integration

Layer / File(s) Summary
Service tier contract
packages/types/src/model.ts
Exports SERVICE_TIER_KEY and OpenAiServiceTier, with service-tier values and types derived from the enum.
Provider requests, events, and pricing
src/api/providers/bedrock.ts, src/api/providers/openai-native.ts, src/shared/cost.ts, src/api/providers/__tests__/*, src/utils/__tests__/cost.spec.ts
Uses the shared service-tier key and enum across Bedrock and OpenAI payloads, SSE event parsing, pricing defaults, and provider cost tests.
Service-tier settings and pricing UI
webview-ui/src/components/settings/ModelInfoView.tsx, webview-ui/src/components/settings/providers/OpenAI.tsx, webview-ui/src/components/settings/**/__tests__/*
Uses enum-based tier selection and provider checks, renders tier-specific pricing with standard-price fallbacks, and adds UI coverage for selector and pricing-table behavior.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Suggested labels: awaiting-review

Suggested reviewers: taltas

Sequence Diagram(s)

sequenceDiagram
  participant OpenAiNativeHandler
  participant OpenAIResponsesAPI
  participant SSEEventProcessor
  participant CostCalculator
  OpenAiNativeHandler->>OpenAIResponsesAPI: Send request with service tier
  OpenAIResponsesAPI-->>SSEEventProcessor: Stream events with resolved tier
  SSEEventProcessor->>CostCalculator: Calculate cost from resolved tier
Loading
🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description covers scope, behavior, and tests, but it omits required template sections like the linked issue, test procedure, checklist, and contact info. Add the required template sections, especially the linked GitHub issue, step-by-step test procedure, pre-submission checklist, and Discord contact.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise and accurately summarizes the main refactor to centralize shared service-tier primitives.
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.
✨ 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.

@codecov

codecov Bot commented Jul 28, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@WebMad
WebMad marked this pull request as ready for review July 29, 2026 00:51

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick comments (2)
src/api/providers/openai-native.ts (1)

373-376: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Duplicate tier-gating logic between buildRequestBody and completePrompt.

Both methods independently rebuild allowedTierNames and re-implement the identical "is tier allowed" condition (requestedTier === OpenAiServiceTier.Default || allowedTierNames.has(requestedTier)). Extracting a shared private helper avoids future divergence if the gating rule changes.

♻️ Proposed helper extraction
+	private resolveEffectiveServiceTier(model: OpenAiNativeModel): ServiceTier | undefined {
+		const requestedTier = (this.options.openAiNativeServiceTier as ServiceTier | undefined) || undefined
+		if (!requestedTier) return undefined
+		const allowedTierNames = new Set(model.info.tiers?.map((t) => t.name).filter(Boolean) || [])
+		return requestedTier === OpenAiServiceTier.Default || allowedTierNames.has(requestedTier)
+			? requestedTier
+			: undefined
+	}
+
 	private buildRequestBody(...): any {
 		...
-		const requestedTier = (this.options.openAiNativeServiceTier as ServiceTier | undefined) || undefined
-		const allowedTierNames = new Set(model.info.tiers?.map((t) => t.name).filter(Boolean) || [])
+		const effectiveRequestedTier = this.resolveEffectiveServiceTier(model)
 		...
-			...(requestedTier &&
-				(requestedTier === OpenAiServiceTier.Default || allowedTierNames.has(requestedTier)) && {
-					[SERVICE_TIER_KEY]: requestedTier,
-				}),
+			...(effectiveRequestedTier && { [SERVICE_TIER_KEY]: effectiveRequestedTier }),
 	async completePrompt(prompt: string, options?: CompletePromptOptions): Promise<string> {
 		...
-		const requestedTier = (this.options.openAiNativeServiceTier as ServiceTier | undefined) || undefined
-		const allowedTierNames = new Set(model.info.tiers?.map((t) => t.name).filter(Boolean) || [])
-		if (requestedTier && (requestedTier === OpenAiServiceTier.Default || allowedTierNames.has(requestedTier))) {
-			requestBody[SERVICE_TIER_KEY] = requestedTier
+		const effectiveRequestedTier = this.resolveEffectiveServiceTier(model)
+		if (effectiveRequestedTier) {
+			requestBody[SERVICE_TIER_KEY] = effectiveRequestedTier
 		}

Also applies to: 1513-1515

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/api/providers/openai-native.ts` around lines 373 - 376, Extract the
shared tier-approval logic from buildRequestBody and completePrompt into a
private helper that accepts requestedTier and the allowed tier names, then reuse
it in both SERVICE_TIER_KEY construction paths. Remove the duplicated
allowedTierNames setup and condition while preserving acceptance of
OpenAiServiceTier.Default and configured allowed tiers.
webview-ui/src/components/settings/ModelInfoView.tsx (1)

149-194: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Flex and Priority pricing rows are near-identical; extract a shared row renderer.

Each block repeats the same td/fmt/tiers.find(...) pattern, differing only by tier enum and label. A small helper removes the duplication and keeps the two rows from drifting.

♻️ Proposed row-renderer helper
+							{([
+								[OpenAiServiceTier.Flex, t("settings:serviceTier.flex")],
+								[OpenAiServiceTier.Priority, t("settings:serviceTier.priority")],
+							] as const)
+								.filter(([tierName]) => allowedTierNames.includes(tierName))
+								.map(([tierName, label]) => {
+									const tierInfo = modelInfo?.tiers?.find((t) => t.name === tierName)
+									return (
+										<tr key={tierName} className="border-t border-vscode-dropdown-border/60">
+											<td className="px-3 py-1.5">{label}</td>
+											<td className="px-3 py-1.5 text-right">
+												{fmt(tierInfo?.inputPrice ?? modelInfo?.inputPrice)}
+											</td>
+											<td className="px-3 py-1.5 text-right">
+												{fmt(tierInfo?.outputPrice ?? modelInfo?.outputPrice)}
+											</td>
+											<td className="px-3 py-1.5 text-right">
+												{fmt(tierInfo?.cacheReadsPrice ?? modelInfo?.cacheReadsPrice)}
+											</td>
+										</tr>
+									)
+								})}
-							{allowedTierNames.includes(OpenAiServiceTier.Flex) && ( ... )}
-							{allowedTierNames.includes(OpenAiServiceTier.Priority) && ( ... )}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@webview-ui/src/components/settings/ModelInfoView.tsx` around lines 149 - 194,
In ModelInfoView, extract the duplicated Flex and Priority pricing-row markup
into a shared row renderer or component that accepts the tier enum and
translated label, while preserving the existing allowedTierNames checks and
fallback pricing behavior. Replace both inline blocks with calls to this helper
so the tier-specific lookup and labels remain configurable without repeating the
td/fmt structure.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@src/api/providers/openai-native.ts`:
- Around line 373-376: Extract the shared tier-approval logic from
buildRequestBody and completePrompt into a private helper that accepts
requestedTier and the allowed tier names, then reuse it in both SERVICE_TIER_KEY
construction paths. Remove the duplicated allowedTierNames setup and condition
while preserving acceptance of OpenAiServiceTier.Default and configured allowed
tiers.

In `@webview-ui/src/components/settings/ModelInfoView.tsx`:
- Around line 149-194: In ModelInfoView, extract the duplicated Flex and
Priority pricing-row markup into a shared row renderer or component that accepts
the tier enum and translated label, while preserving the existing
allowedTierNames checks and fallback pricing behavior. Replace both inline
blocks with calls to this helper so the tier-specific lookup and labels remain
configurable without repeating the td/fmt structure.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 56e7c7fe-047d-4f43-8288-851cb3b38ebe

📥 Commits

Reviewing files that changed from the base of the PR and between d27153a and 007a4bd.

📒 Files selected for processing (12)
  • packages/types/src/model.ts
  • src/api/providers/__tests__/bedrock.spec.ts
  • src/api/providers/__tests__/openai-native-usage.spec.ts
  • src/api/providers/__tests__/openai-native.spec.ts
  • src/api/providers/bedrock.ts
  • src/api/providers/openai-native.ts
  • src/shared/cost.ts
  • src/utils/__tests__/cost.spec.ts
  • webview-ui/src/components/settings/ModelInfoView.tsx
  • webview-ui/src/components/settings/__tests__/ModelInfoView.spec.tsx
  • webview-ui/src/components/settings/providers/OpenAI.tsx
  • webview-ui/src/components/settings/providers/__tests__/OpenAI.spec.tsx

@github-actions github-actions Bot added the awaiting-review PR changes are ready and waiting for maintainer re-review label Jul 29, 2026

@edelauna edelauna left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nice! Thanks for this PR - had 2 comments related to the implementation.

Comment thread packages/types/src/model.ts Outdated
Comment thread src/api/providers/__tests__/openai-native.spec.ts Outdated
@github-actions github-actions Bot added awaiting-author PR is waiting for the author to address requested changes and removed awaiting-review PR changes are ready and waiting for maintainer re-review labels Jul 29, 2026
@WebMad

WebMad commented Jul 29, 2026

Copy link
Copy Markdown
Contributor Author

Addressed both review comments in 5f0179c:

  • Replaced the TypeScript enum with an as const OpenAiServiceTier object, kept serviceTiers as a readonly tuple for z.enum, and now infer ServiceTier from the schema.
  • Reworked the three pricing-invariant tests to exercise the public createMessage usage path instead of reaching into private methods with Reflect.get / Reflect.apply.

Also centralized request-tier gating so streaming requests and completePrompt use the same helper, and kept the shared tier-pricing row renderer strictly typed with ServiceTier.

Validation completed:

  • 197 focused backend tests passed
  • 6 focused webview tests passed
  • repository lint and all 11 applicable type-check tasks passed via commit/push hooks

@WebMad
WebMad requested a review from edelauna July 29, 2026 15:36
@github-actions github-actions Bot added awaiting-review PR changes are ready and waiting for maintainer re-review and removed awaiting-author PR is waiting for the author to address requested changes labels Jul 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

awaiting-review PR changes are ready and waiting for maintainer re-review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants