Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions backend/cli/src/cli/cmd/models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { EOL } from "os"
const PROVIDER_LABELS: Record<string, string> = {
anthropic: "Anthropic",
openai: "OpenAI",
"openai-codex": "OpenAI Codex",
"openai-codex": "OpenAI (ChatGPT subscription)",
google: "Google",
gemini: "Google Gemini",
openrouter: "OpenRouter",
Expand All @@ -25,7 +25,7 @@ const PROVIDER_LABELS: Record<string, string> = {
* - anything else with a key → BYOK.
*/
function routingLabel(providerID: string, provider: Provider.Info): string {
if (providerID === "openai-codex") return "Signed in with Codex"
if (providerID === "openai-codex") return "ChatGPT subscription"
// Read the EFFECTIVE credential, not just provider.key: a custom loader stores
// its key under options.apiKey (e.g. openrouter), and a multi-env provider
// (google's GEMINI_API_KEY + GOOGLE_GENERATIVE_AI_API_KEY) leaves provider.key
Expand Down
5 changes: 2 additions & 3 deletions backend/cli/src/provider/provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,7 @@ export namespace Provider {
}

function codexOAuthModes(modelID: string) {
if (/^gpt-5[.-]4-mini$/.test(modelID)) return undefined
if (!/^gpt-5[.-](?:4|5|6)(?:-(?:sol|terra|luna))?$/.test(modelID)) return undefined
if (!/^gpt-5[.-](?:4(?:-mini)?|5|6(?:-(?:sol|terra|luna))?)$/.test(modelID)) return undefined
return {
fast: {
provider: {
Expand Down Expand Up @@ -1430,7 +1429,7 @@ export namespace Provider {
database["openai-codex"] = {
...baseOpenai,
id: "openai-codex",
name: "OpenAI Codex (ChatGPT subscription)",
name: "OpenAI (ChatGPT subscription)",
env: [],
options: {},
models: codexModels,
Expand Down
3 changes: 2 additions & 1 deletion backend/cli/test/provider/provider.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,8 @@ test("synthesized Codex OAuth models use Codex variants and context instead of p
const codex54 = codex.models["gpt-5.4"]
expect(Object.keys(codex54.variants ?? {})).toEqual(["low", "medium", "high", "xhigh"])
expect(Object.keys(codex54.modes ?? {})).toEqual(["fast"])
expect(codex.models["gpt-5.4-mini"].modes).toBeUndefined()
expect(Object.keys(codex.models["gpt-5.4-mini"].modes ?? {})).toEqual(["fast"])
expect(codex.name).toBe("OpenAI (ChatGPT subscription)")

const publicSol = providers.openai?.models["gpt-5.6-sol"]
expect(Object.keys(publicSol?.variants ?? {})).toEqual(["none", "low", "medium", "high", "xhigh", "max"])
Expand Down
25 changes: 12 additions & 13 deletions frontend/workspace/e2e/model-tier.spec.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,19 @@
import { test, expect } from "./fixtures"
import { modelTierCycleSelector, promptSelector } from "./utils"

test("model service mode cycles through supported modes and reaches the prompt request", async ({
page,
sdk,
gotoSession,
}) => {
test("model Fast mode toggles and reaches the prompt request", async ({ page, sdk, gotoSession }) => {
await gotoSession()

await page.addStyleTag({
content: `${modelTierCycleSelector} { display: inline-block !important; }`,
})

const button = page.locator(modelTierCycleSelector)
await expect(button).toBeVisible()
await expect(button).toHaveText("standard")
await expect(button).toHaveAttribute("aria-label", /cycle tier: standard/i)
const toggle = page.locator(modelTierCycleSelector)
const input = toggle.locator('[data-slot="switch-input"]')
const control = toggle.locator('[data-slot="switch-control"]')
await expect(toggle).toBeVisible()
await expect(toggle).toHaveText("Fast")
await expect(input).toHaveAttribute("aria-checked", "false")

const send = async (tier?: string) => {
const request = page.waitForRequest((request) => {
Expand Down Expand Up @@ -53,12 +51,13 @@ test("model service mode cycles through supported modes and reaches the prompt r
)
.toContain(standard)

await button.click()
await expect(button).toHaveText("fast")
await expect(button).toHaveAttribute("aria-label", /cycle tier: fast/i)
await control.click()
await expect(toggle).toHaveText("Fast")
await expect(input).toHaveAttribute("aria-checked", "true")

await page.reload()
await expect(button).toHaveText("fast")
await expect(toggle).toHaveText("Fast")
await expect(input).toHaveAttribute("aria-checked", "true")

const fast = await send("fast")
await expect
Expand Down
10 changes: 6 additions & 4 deletions frontend/workspace/e2e/thinking-level.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ test("thinking effort starts at standard and reaches the prompt request", async
if (!exists) return

await expect(button).toBeVisible()
await expect(button).toHaveText("standard")
await expect(button).toHaveText("Thinking")
await expect(button).toHaveAttribute("aria-label", /thinking effort: standard/i)

const send = async (options: { variant?: string; tier?: string } = {}) => {
Expand Down Expand Up @@ -59,15 +59,17 @@ test("thinking effort starts at standard and reaches the prompt request", async
await expect(button).toHaveAttribute("aria-label", /thinking effort: high/i)

const tier = page.locator(modelTierCycleSelector)
await tier.click()
await expect(tier).toHaveText("fast")
await tier.locator('[data-slot="switch-control"]').click()
await expect(tier).toHaveText("Fast")
await expect(tier.locator('[data-slot="switch-input"]')).toHaveAttribute("aria-checked", "true")

const high = await send({ variant: "high", tier: "fast" })
await expect.poll(output, { timeout: 20_000 }).toContain(high)

await page.reload()
await expect(button).toHaveText("high")
await expect(tier).toHaveText("fast")
await expect(tier).toHaveText("Fast")
await expect(tier.locator('[data-slot="switch-input"]')).toHaveAttribute("aria-checked", "true")
} finally {
await sdk.session.delete({ sessionID }).catch(() => undefined)
}
Expand Down
2 changes: 1 addition & 1 deletion frontend/workspace/src/atlas/Composer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ const BYOK_URL = URLS.dashboard
const PROVIDER_LABEL: Record<string, string> = {
anthropic: "Anthropic",
openai: "OpenAI",
"openai-codex": "OpenAI Codex",
"openai-codex": "OpenAI (ChatGPT subscription)",
google: "Google",
"google-vertex": "Google Vertex",
"github-copilot": "GitHub Copilot",
Expand Down
16 changes: 6 additions & 10 deletions frontend/workspace/src/components/prompt-input.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import { useSync } from "@/context/sync"
import { useComments } from "@/context/comments"
import { FileIcon } from "@synsci/ui/file-icon"
import { Button } from "@synsci/ui/button"
import { Switch as Toggle } from "@synsci/ui/switch"
import { Icon } from "@synsci/ui/icon"
import { ProviderIcon } from "@synsci/ui/provider-icon"
import type { IconName } from "@synsci/ui/icons/provider"
Expand Down Expand Up @@ -2050,19 +2051,14 @@ export const PromptInput: Component<PromptInputProps> = (props) => {
title={language.t("command.tier.cycle")}
keybind={command.keybind("tier.cycle")}
>
<Button
<Toggle
data-action="model-tier-cycle"
aria-label={`Fast mode: ${local.model.tier.current() === "fast" ? "on" : "off"}`}
aria-pressed={local.model.tier.current() === "fast"}
variant="ghost"
class="text-text-base group-hover/prompt-input:inline-block capitalize"
classList={{
"bg-surface-raised-base-active text-text-strong": local.model.tier.current() === "fast",
}}
onClick={() => local.model.tier.set(local.model.tier.current() === "fast" ? "standard" : "fast")}
checked={local.model.tier.current() === "fast"}
class="text-text-base group-hover/prompt-input:flex items-center gap-1.5"
onChange={(checked) => local.model.tier.set(checked ? "fast" : "standard")}
>
Fast
</Button>
</Toggle>
</TooltipKeybind>
</Show>
<Show when={permission.permissionsEnabled() && params.id}>
Expand Down
4 changes: 2 additions & 2 deletions frontend/workspace/src/components/settings/Credentials.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -462,15 +462,15 @@ export const Credentials: Component = () => {
</p>
</div>

{/* Sign in with ChatGPT (Codex OAuth) — an OpenAI plan's credits, no key */}
{/* Sign in with ChatGPT — an OpenAI plan's credits, no key */}
<div
class="flex flex-col sm:flex-row sm:items-center gap-3 sm:justify-between"
style={{ border: "1px solid var(--color-border)", "border-radius": "4px", padding: "14px 18px" }}
>
<div class="flex flex-col gap-0.5 min-w-0">
<span class="text-13-medium text-text-base">Sign in with ChatGPT</span>
<span class="text-12-regular text-text-weak">
Use your ChatGPT Plus / Pro / Business plan (Codex) — no API key needed.
Use your ChatGPT Plus / Pro / Business plan — no API key needed.
</span>
</div>
<Show
Expand Down