Skip to content

Commit dd9c9cd

Browse files
committed
refactor(openai): split Codex service tiers
1 parent d481f51 commit dd9c9cd

8 files changed

Lines changed: 50 additions & 31 deletions

File tree

packages/types/src/__tests__/provider-settings.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,23 @@ import {
44
providerSettingsSchema,
55
providerSettingsSchemaDiscriminated,
66
} from "../provider-settings.js"
7-
import { OpenAiServiceTier } from "../model.js"
7+
import { OpenAiCodexServiceTier, OpenAiServiceTier } from "../model.js"
88
import { providerIdentifiers } from "../provider-identifiers.js"
99

1010
describe("OpenAI Codex provider settings", () => {
1111
it("preserves the Fast preference in general and provider-specific schemas", () => {
1212
const settings = {
1313
apiProvider: providerIdentifiers.openaiCodex,
1414
apiModelId: "gpt-5.6-sol",
15-
openAiCodexServiceTier: OpenAiServiceTier.Priority,
15+
openAiCodexServiceTier: OpenAiCodexServiceTier.Priority,
1616
}
1717

1818
expect(providerSettingsSchema.parse(settings)).toEqual(settings)
1919
expect(providerSettingsSchemaDiscriminated.parse(settings)).toEqual(settings)
2020
expect(PROVIDER_SETTINGS_KEYS).toContain("openAiCodexServiceTier")
2121
})
2222

23-
it.each([undefined, OpenAiServiceTier.Default])(
23+
it.each([undefined, OpenAiCodexServiceTier.Default])(
2424
"accepts %s as the Standard preference",
2525
(openAiCodexServiceTier) => {
2626
const standardSettings = {

packages/types/src/model.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ export const verbosityLevelsSchema = z.enum(verbosityLevels)
5555
export type VerbosityLevel = z.infer<typeof verbosityLevelsSchema>
5656

5757
/**
58-
* Service tiers (OpenAI Responses API)
58+
* Service tiers for the public OpenAI Responses API.
5959
*/
6060
export enum OpenAiServiceTier {
6161
Default = "default",
@@ -67,6 +67,14 @@ export const serviceTiers = Object.values(OpenAiServiceTier) as [`${OpenAiServic
6767
export const serviceTierSchema = z.enum(serviceTiers)
6868
export type ServiceTier = `${OpenAiServiceTier}`
6969

70+
/**
71+
* Service tiers for Codex requests authenticated through a ChatGPT subscription.
72+
*/
73+
export enum OpenAiCodexServiceTier {
74+
Default = "default",
75+
Priority = "priority",
76+
}
77+
7078
/**
7179
* ModelParameter
7280
*/

packages/types/src/provider-settings.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { z } from "zod"
22

33
import {
44
modelInfoSchema,
5-
OpenAiServiceTier,
5+
OpenAiCodexServiceTier,
66
reasoningEffortSettingSchema,
77
verbosityLevelsSchema,
88
serviceTierSchema,
@@ -284,7 +284,7 @@ const geminiCliSchema = apiModelIdProviderModelSchema.extend({
284284

285285
const openAiCodexSchema = apiModelIdProviderModelSchema.extend({
286286
// Codex "Fast" mode maps to the Responses API priority service tier.
287-
openAiCodexServiceTier: z.enum([OpenAiServiceTier.Default, OpenAiServiceTier.Priority]).optional(),
287+
openAiCodexServiceTier: z.enum([OpenAiCodexServiceTier.Default, OpenAiCodexServiceTier.Priority]).optional(),
288288
})
289289

290290
const openAiNativeSchema = apiModelIdProviderModelSchema.extend({

src/api/providers/__tests__/openai-codex.spec.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ vitest.mock("@roo-code/telemetry", () => ({
99
}))
1010

1111
import { Anthropic } from "@anthropic-ai/sdk"
12-
import { OpenAiServiceTier } from "@roo-code/types"
12+
import { OpenAiCodexServiceTier } from "@roo-code/types"
1313
import { OpenAiCodexHandler, transformLunaResponsesLiteBody } from "../openai-codex"
1414
import { openAiCodexOAuthManager } from "../../../integrations/openai-codex/oauth"
1515

@@ -85,7 +85,7 @@ describe("OpenAiCodexHandler.createMessage", () => {
8585
it("sends the priority service tier in streaming SDK requests when Fast is selected", async () => {
8686
const handler = new OpenAiCodexHandler({
8787
apiModelId: "gpt-5.6-sol",
88-
openAiCodexServiceTier: OpenAiServiceTier.Priority,
88+
openAiCodexServiceTier: OpenAiCodexServiceTier.Priority,
8989
})
9090
vitest.spyOn(openAiCodexOAuthManager, "getAccessToken").mockResolvedValue("test-token")
9191
vitest.spyOn(openAiCodexOAuthManager, "getAccountId").mockResolvedValue("acct_test")
@@ -95,14 +95,14 @@ describe("OpenAiCodexHandler.createMessage", () => {
9595
await drainStream(handler.createMessage("System prompt", []))
9696

9797
const [body] = mockCreate.mock.calls[0]
98-
expect(body).toMatchObject({ stream: true, service_tier: OpenAiServiceTier.Priority })
98+
expect(body).toMatchObject({ stream: true, service_tier: OpenAiCodexServiceTier.Priority })
9999
})
100100

101101
it.each([
102102
["an absent preference", {}],
103103
[
104104
"an explicit Standard preference from an older profile",
105-
{ openAiCodexServiceTier: OpenAiServiceTier.Default },
105+
{ openAiCodexServiceTier: OpenAiCodexServiceTier.Default },
106106
],
107107
])("omits the service tier in streaming SDK requests for %s", async (_description, serviceTierOptions) => {
108108
const handler = new OpenAiCodexHandler({
@@ -122,7 +122,7 @@ describe("OpenAiCodexHandler.createMessage", () => {
122122
it("preserves the priority service tier in the manual streaming fallback", async () => {
123123
const handler = new OpenAiCodexHandler({
124124
apiModelId: "gpt-5.6-sol",
125-
openAiCodexServiceTier: OpenAiServiceTier.Priority,
125+
openAiCodexServiceTier: OpenAiCodexServiceTier.Priority,
126126
})
127127
vitest.spyOn(openAiCodexOAuthManager, "getAccessToken").mockResolvedValue("test-token")
128128
vitest.spyOn(openAiCodexOAuthManager, "getAccountId").mockResolvedValue("acct_test")
@@ -148,7 +148,7 @@ describe("OpenAiCodexHandler.createMessage", () => {
148148

149149
expect(JSON.parse(mockFetch.mock.calls[0][1].body)).toMatchObject({
150150
stream: true,
151-
service_tier: OpenAiServiceTier.Priority,
151+
service_tier: OpenAiCodexServiceTier.Priority,
152152
})
153153
})
154154

@@ -258,8 +258,8 @@ describe("OpenAiCodexHandler.completePrompt service tier", () => {
258258
vitest.unstubAllGlobals()
259259
})
260260

261-
it.each<[string, OpenAiServiceTier.Priority | undefined, OpenAiServiceTier.Priority | undefined]>([
262-
["Fast", OpenAiServiceTier.Priority, OpenAiServiceTier.Priority],
261+
it.each<[string, OpenAiCodexServiceTier.Priority | undefined, OpenAiCodexServiceTier.Priority | undefined]>([
262+
["Fast", OpenAiCodexServiceTier.Priority, OpenAiCodexServiceTier.Priority],
263263
["Standard", undefined, undefined],
264264
])("uses the %s preference in non-streaming requests", async (_mode, configuredTier, expectedTier) => {
265265
const handler = new OpenAiCodexHandler({

src/api/providers/openai-codex.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import OpenAI from "openai"
55

66
import {
77
type ModelInfo,
8-
OpenAiServiceTier,
8+
OpenAiCodexServiceTier,
99
openAiCodexDefaultModelId,
1010
OpenAiCodexModelId,
1111
openAiCodexModels,
@@ -30,7 +30,7 @@ import { t } from "../../i18n"
3030

3131
export type OpenAiCodexModel = ReturnType<OpenAiCodexHandler["getModel"]>
3232

33-
type OpenAiCodexRequestServiceTier = OpenAiServiceTier.Priority
33+
type OpenAiCodexRequestServiceTier = OpenAiCodexServiceTier.Priority
3434

3535
/**
3636
* OpenAI Codex base URL for API requests
@@ -41,7 +41,7 @@ const LUNA_MODEL_ID = "gpt-5.6-luna"
4141
const LUNA_CODEX_VERSION = "0.144.0"
4242

4343
const getOpenAiCodexServiceTier = (options: ApiHandlerOptions): OpenAiCodexRequestServiceTier | undefined =>
44-
options.openAiCodexServiceTier === OpenAiServiceTier.Priority ? OpenAiServiceTier.Priority : undefined
44+
options.openAiCodexServiceTier === OpenAiCodexServiceTier.Priority ? OpenAiCodexServiceTier.Priority : undefined
4545

4646
function stripInputImageDetail(value: any): any {
4747
if (Array.isArray(value)) {

src/core/config/__tests__/ProviderSettingsManager.spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import { ExtensionContext } from "vscode"
44

5-
import { OpenAiServiceTier, providerIdentifiers, type ProviderSettings } from "@roo-code/types"
5+
import { OpenAiCodexServiceTier, providerIdentifiers, type ProviderSettings } from "@roo-code/types"
66

77
import { ProviderSettingsManager, ProviderProfiles, SyncCloudProfilesResult } from "../ProviderSettingsManager"
88

@@ -451,7 +451,7 @@ describe("ProviderSettingsManager", () => {
451451
expect(storedConfig).toEqual(expectedConfig)
452452
})
453453

454-
it.each([OpenAiServiceTier.Default, OpenAiServiceTier.Priority] as const)(
454+
it.each([OpenAiCodexServiceTier.Default, OpenAiCodexServiceTier.Priority] as const)(
455455
"should persist the OpenAI Codex %s speed preference",
456456
async (openAiCodexServiceTier) => {
457457
mockSecrets.get.mockResolvedValue(

webview-ui/src/components/settings/providers/OpenAICodex.tsx

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
import React from "react"
22

3-
import { OpenAiServiceTier, type ProviderSettings, openAiCodexDefaultModelId, openAiCodexModels } from "@roo-code/types"
3+
import {
4+
OpenAiCodexServiceTier,
5+
type ProviderSettings,
6+
openAiCodexDefaultModelId,
7+
openAiCodexModels,
8+
} from "@roo-code/types"
49

510
import { useAppTranslation } from "@src/i18n/TranslationContext"
611
import {
@@ -85,7 +90,7 @@ export const OpenAICodex: React.FC<OpenAICodexProps> = ({
8590
</StandardTooltip>
8691
</div>
8792
<Select
88-
value={apiConfiguration[OPEN_AI_CODEX_SERVICE_TIER_KEY] ?? OpenAiServiceTier.Default}
93+
value={apiConfiguration[OPEN_AI_CODEX_SERVICE_TIER_KEY] ?? OpenAiCodexServiceTier.Default}
8994
onValueChange={(value) =>
9095
setApiConfigurationField(
9196
OPEN_AI_CODEX_SERVICE_TIER_KEY,
@@ -96,10 +101,10 @@ export const OpenAICodex: React.FC<OpenAICodexProps> = ({
96101
<SelectValue placeholder={t("settings:common.select")} />
97102
</SelectTrigger>
98103
<SelectContent>
99-
<SelectItem value={OpenAiServiceTier.Default}>
104+
<SelectItem value={OpenAiCodexServiceTier.Default}>
100105
{t("settings:openAiCodexSpeed.standard")}
101106
</SelectItem>
102-
<SelectItem value={OpenAiServiceTier.Priority}>
107+
<SelectItem value={OpenAiCodexServiceTier.Priority}>
103108
{t("settings:openAiCodexSpeed.fast")}
104109
</SelectItem>
105110
</SelectContent>

webview-ui/src/components/settings/providers/__tests__/OpenAICodex.spec.tsx

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import React from "react"
22

3-
import { OpenAiServiceTier, providerIdentifiers, type ProviderSettings } from "@roo-code/types"
3+
import { OpenAiCodexServiceTier, providerIdentifiers, type ProviderSettings } from "@roo-code/types"
44

55
import { fireEvent, render, screen } from "@/utils/test-utils"
66

@@ -56,7 +56,7 @@ describe("OpenAICodex speed selector", () => {
5656
it("defaults to Standard and clearly explains the Fast quota trade-off", () => {
5757
const { selector } = renderSelector({ apiProvider: providerIdentifiers.openaiCodex })
5858

59-
expect(selector).toHaveValue(OpenAiServiceTier.Default)
59+
expect(selector).toHaveValue(OpenAiCodexServiceTier.Default)
6060
expect(screen.getByRole("option", { name: "Standard" })).toBeInTheDocument()
6161
expect(screen.getByRole("option", { name: "Fast (1.5x speed, increased usage)" })).toBeInTheDocument()
6262
expect(
@@ -69,15 +69,21 @@ describe("OpenAICodex speed selector", () => {
6969
it("selects Fast from a saved preference and persists changes through the settings callback", () => {
7070
const { selector, setApiConfigurationField } = renderSelector({
7171
apiProvider: providerIdentifiers.openaiCodex,
72-
openAiCodexServiceTier: OpenAiServiceTier.Priority,
72+
openAiCodexServiceTier: OpenAiCodexServiceTier.Priority,
7373
})
7474

75-
expect(selector).toHaveValue(OpenAiServiceTier.Priority)
75+
expect(selector).toHaveValue(OpenAiCodexServiceTier.Priority)
7676

77-
fireEvent.change(selector, { target: { value: OpenAiServiceTier.Default } })
78-
expect(setApiConfigurationField).toHaveBeenLastCalledWith("openAiCodexServiceTier", OpenAiServiceTier.Default)
77+
fireEvent.change(selector, { target: { value: OpenAiCodexServiceTier.Default } })
78+
expect(setApiConfigurationField).toHaveBeenLastCalledWith(
79+
"openAiCodexServiceTier",
80+
OpenAiCodexServiceTier.Default,
81+
)
7982

80-
fireEvent.change(selector, { target: { value: OpenAiServiceTier.Priority } })
81-
expect(setApiConfigurationField).toHaveBeenLastCalledWith("openAiCodexServiceTier", OpenAiServiceTier.Priority)
83+
fireEvent.change(selector, { target: { value: OpenAiCodexServiceTier.Priority } })
84+
expect(setApiConfigurationField).toHaveBeenLastCalledWith(
85+
"openAiCodexServiceTier",
86+
OpenAiCodexServiceTier.Priority,
87+
)
8288
})
8389
})

0 commit comments

Comments
 (0)