| author | |
| committer | |
| log | 9fdb45be1efb0e0b542a0dd78d868de6f71d7d4a |
| tree | e8e861c56557446f870d00987394b96ce5eb43ff |
| parent | b946f00f1a31f16a51f9bd1f579baf40c8eaed83 |
- Drop `serviceTier` from orchestration/provider contracts and server dispatch paths
- Remove service-tier app setting/UI and related resolver logic
- Keep fast badge behavior tied to explicit fast-mode boolean9 files changed, 26 insertions(+), 130 deletions(-)
apps/server/src/orchestration/Layers/ProviderCommandReactor.ts+7-10| ... | @@ -5,7 +5,6 @@ import { | ... | @@ -5,7 +5,6 @@ import { |
| 5 | type OrchestrationEvent, | 5 | type OrchestrationEvent, |
| 6 | type ProviderModelOptions, | 6 | type ProviderModelOptions, |
| 7 | type ProviderKind, | 7 | type ProviderKind, |
| 8 | type ProviderServiceTier, | ||
| 9 | type ProviderStartOptions, | 8 | type ProviderStartOptions, |
| 10 | type OrchestrationSession, | 9 | type OrchestrationSession, |
| 11 | ThreadId, | 10 | ThreadId, |
| ... | @@ -205,7 +204,6 @@ const make = Effect.gen(function* () { | ... | @@ -205,7 +204,6 @@ const make = Effect.gen(function* () { |
| 205 | readonly provider?: ProviderKind; | 204 | readonly provider?: ProviderKind; |
| 206 | readonly model?: string; | 205 | readonly model?: string; |
| 207 | readonly modelOptions?: ProviderModelOptions; | 206 | readonly modelOptions?: ProviderModelOptions; |
| 208 | readonly serviceTier?: ProviderServiceTier | null; | ||
| 209 | readonly providerOptions?: ProviderStartOptions; | 207 | readonly providerOptions?: ProviderStartOptions; |
| 210 | }, | 208 | }, |
| 211 | ) { | 209 | ) { |
| ... | @@ -241,7 +239,6 @@ const make = Effect.gen(function* () { | ... | @@ -241,7 +239,6 @@ const make = Effect.gen(function* () { |
| 241 | : {}), | 239 | : {}), |
| 242 | ...(effectiveCwd ? { cwd: effectiveCwd } : {}), | 240 | ...(effectiveCwd ? { cwd: effectiveCwd } : {}), |
| 243 | ...(desiredModel ? { model: desiredModel } : {}), | 241 | ...(desiredModel ? { model: desiredModel } : {}), |
| 244 | ...(options?.serviceTier !== undefined ? { serviceTier: options.serviceTier } : {}), | ||
| 245 | ...(options?.modelOptions !== undefined ? { modelOptions: options.modelOptions } : {}), | 242 | ...(options?.modelOptions !== undefined ? { modelOptions: options.modelOptions } : {}), |
| 246 | ...(options?.providerOptions !== undefined ? { providerOptions: options.providerOptions } : {}), | 243 | ...(options?.providerOptions !== undefined ? { providerOptions: options.providerOptions } : {}), |
| 247 | ...(input?.resumeCursor !== undefined ? { resumeCursor: input.resumeCursor } : {}), | 244 | ...(input?.resumeCursor !== undefined ? { resumeCursor: input.resumeCursor } : {}), |
| ... | @@ -328,7 +325,6 @@ const make = Effect.gen(function* () { | ... | @@ -328,7 +325,6 @@ const make = Effect.gen(function* () { |
| 328 | readonly attachments?: ReadonlyArray<ChatAttachment>; | 325 | readonly attachments?: ReadonlyArray<ChatAttachment>; |
| 329 | readonly provider?: ProviderKind; | 326 | readonly provider?: ProviderKind; |
| 330 | readonly model?: string; | 327 | readonly model?: string; |
| 331 | readonly serviceTier?: ProviderServiceTier | null; | ||
| 332 | readonly modelOptions?: ProviderModelOptions; | 328 | readonly modelOptions?: ProviderModelOptions; |
| 333 | readonly providerOptions?: ProviderStartOptions; | 329 | readonly providerOptions?: ProviderStartOptions; |
| 334 | readonly interactionMode?: "default" | "plan"; | 330 | readonly interactionMode?: "default" | "plan"; |
| ... | @@ -344,7 +340,6 @@ const make = Effect.gen(function* () { | ... | @@ -344,7 +340,6 @@ const make = Effect.gen(function* () { |
| 344 | yield* ensureSessionForThread(input.threadId, input.createdAt, { | 340 | yield* ensureSessionForThread(input.threadId, input.createdAt, { |
| 345 | ...(input.provider !== undefined ? { provider: input.provider } : {}), | 341 | ...(input.provider !== undefined ? { provider: input.provider } : {}), |
| 346 | ...(input.model !== undefined ? { model: input.model } : {}), | 342 | ...(input.model !== undefined ? { model: input.model } : {}), |
| 347 | ...(input.serviceTier !== undefined ? { serviceTier: input.serviceTier } : {}), | ||
| 348 | ...(input.modelOptions !== undefined ? { modelOptions: input.modelOptions } : {}), | 343 | ...(input.modelOptions !== undefined ? { modelOptions: input.modelOptions } : {}), |
| 349 | ...(input.providerOptions !== undefined ? { providerOptions: input.providerOptions } : {}), | 344 | ...(input.providerOptions !== undefined ? { providerOptions: input.providerOptions } : {}), |
| 350 | }); | 345 | }); |
| ... | @@ -365,7 +360,6 @@ const make = Effect.gen(function* () { | ... | @@ -365,7 +360,6 @@ const make = Effect.gen(function* () { |
| 365 | ...(normalizedInput ? { input: normalizedInput } : {}), | 360 | ...(normalizedInput ? { input: normalizedInput } : {}), |
| 366 | ...(normalizedAttachments.length > 0 ? { attachments: normalizedAttachments } : {}), | 361 | ...(normalizedAttachments.length > 0 ? { attachments: normalizedAttachments } : {}), |
| 367 | ...(modelForTurn !== undefined ? { model: modelForTurn } : {}), | 362 | ...(modelForTurn !== undefined ? { model: modelForTurn } : {}), |
| 368 | ...(input.serviceTier !== undefined ? { serviceTier: input.serviceTier } : {}), | ||
| 369 | ...(input.modelOptions !== undefined ? { modelOptions: input.modelOptions } : {}), | 363 | ...(input.modelOptions !== undefined ? { modelOptions: input.modelOptions } : {}), |
| 370 | ...(input.interactionMode !== undefined ? { interactionMode: input.interactionMode } : {}), | 364 | ...(input.interactionMode !== undefined ? { interactionMode: input.interactionMode } : {}), |
| 371 | }); | 365 | }); |
| ... | @@ -480,7 +474,6 @@ const make = Effect.gen(function* () { | ... | @@ -480,7 +474,6 @@ const make = Effect.gen(function* () { |
| 480 | ...(message.attachments !== undefined ? { attachments: message.attachments } : {}), | 474 | ...(message.attachments !== undefined ? { attachments: message.attachments } : {}), |
| 481 | ...(event.payload.provider !== undefined ? { provider: event.payload.provider } : {}), | 475 | ...(event.payload.provider !== undefined ? { provider: event.payload.provider } : {}), |
| 482 | ...(event.payload.model !== undefined ? { model: event.payload.model } : {}), | 476 | ...(event.payload.model !== undefined ? { model: event.payload.model } : {}), |
| 483 | ...(event.payload.serviceTier !== undefined ? { serviceTier: event.payload.serviceTier } : {}), | ||
| 484 | ...(event.payload.modelOptions !== undefined ? { modelOptions: event.payload.modelOptions } : {}), | 477 | ...(event.payload.modelOptions !== undefined ? { modelOptions: event.payload.modelOptions } : {}), |
| 485 | ...(event.payload.providerOptions !== undefined ? { providerOptions: event.payload.providerOptions } : {}), | 478 | ...(event.payload.providerOptions !== undefined ? { providerOptions: event.payload.providerOptions } : {}), |
| 486 | interactionMode: event.payload.interactionMode, | 479 | interactionMode: event.payload.interactionMode, |
| ... | @@ -639,9 +632,13 @@ const make = Effect.gen(function* () { | ... | @@ -639,9 +632,13 @@ const make = Effect.gen(function* () { |
| 639 | return; | 632 | return; |
| 640 | } | 633 | } |
| 641 | const cachedProviderOptions = threadProviderOptions.get(event.payload.threadId); | 634 | const cachedProviderOptions = threadProviderOptions.get(event.payload.threadId); |
| 642 | yield* ensureSessionForThread(event.payload.threadId, event.occurredAt, { | 635 | yield* ensureSessionForThread( |
| 643 | ...(cachedProviderOptions !== undefined ? { providerOptions: cachedProviderOptions } : {}), | 636 | event.payload.threadId, |
| 644 | }); | 637 | event.occurredAt, |
| 638 | cachedProviderOptions !== undefined | ||
| 639 | ? { providerOptions: cachedProviderOptions } | ||
| 640 | : undefined, | ||
| 641 | ); | ||
| 645 | return; | 642 | return; |
| 646 | } | 643 | } |
| 647 | case "thread.turn-start-requested": | 644 | case "thread.turn-start-requested": |
apps/server/src/orchestration/decider.ts-1| ... | @@ -301,7 +301,6 @@ export const decideOrchestrationCommand = Effect.fn("decideOrchestrationCommand" | ... | @@ -301,7 +301,6 @@ export const decideOrchestrationCommand = Effect.fn("decideOrchestrationCommand" |
| 301 | messageId: command.message.messageId, | 301 | messageId: command.message.messageId, |
| 302 | ...(command.provider !== undefined ? { provider: command.provider } : {}), | 302 | ...(command.provider !== undefined ? { provider: command.provider } : {}), |
| 303 | ...(command.model !== undefined ? { model: command.model } : {}), | 303 | ...(command.model !== undefined ? { model: command.model } : {}), |
| 304 | ...(command.serviceTier !== undefined ? { serviceTier: command.serviceTier } : {}), | ||
| 305 | ...(command.modelOptions !== undefined ? { modelOptions: command.modelOptions } : {}), | 304 | ...(command.modelOptions !== undefined ? { modelOptions: command.modelOptions } : {}), |
| 306 | ...(command.providerOptions !== undefined ? { providerOptions: command.providerOptions } : {}), | 305 | ...(command.providerOptions !== undefined ? { providerOptions: command.providerOptions } : {}), |
| 307 | assistantDeliveryMode: command.assistantDeliveryMode ?? DEFAULT_ASSISTANT_DELIVERY_MODE, | 306 | assistantDeliveryMode: command.assistantDeliveryMode ?? DEFAULT_ASSISTANT_DELIVERY_MODE, |
apps/server/src/provider/Layers/CodexAdapter.ts-1| ... | @@ -1354,7 +1354,6 @@ const makeCodexAdapter = (options?: CodexAdapterLiveOptions) => | ... | @@ -1354,7 +1354,6 @@ const makeCodexAdapter = (options?: CodexAdapterLiveOptions) => |
| 1354 | threadId: input.threadId, | 1354 | threadId: input.threadId, |
| 1355 | ...(input.input !== undefined ? { input: input.input } : {}), | 1355 | ...(input.input !== undefined ? { input: input.input } : {}), |
| 1356 | ...(input.model !== undefined ? { model: input.model } : {}), | 1356 | ...(input.model !== undefined ? { model: input.model } : {}), |
| 1357 | ...(input.serviceTier !== undefined ? { serviceTier: input.serviceTier } : {}), | ||
| 1358 | ...(input.modelOptions?.codex?.reasoningEffort !== undefined | 1357 | ...(input.modelOptions?.codex?.reasoningEffort !== undefined |
| 1359 | ? { effort: input.modelOptions.codex.reasoningEffort } | 1358 | ? { effort: input.modelOptions.codex.reasoningEffort } |
| 1360 | : {}), | 1359 | : {}), |
apps/web/src/appSettings.test.ts+4-16| ... | @@ -4,7 +4,6 @@ import { | ... | @@ -4,7 +4,6 @@ import { |
| 4 | getAppModelOptions, | 4 | getAppModelOptions, |
| 5 | getSlashModelOptions, | 5 | getSlashModelOptions, |
| 6 | normalizeCustomModelSlugs, | 6 | normalizeCustomModelSlugs, |
| 7 | resolveAppServiceTier, | ||
| 8 | shouldShowFastTierIcon, | 7 | shouldShowFastTierIcon, |
| 9 | resolveAppModelSelection, | 8 | resolveAppModelSelection, |
| 10 | } from "./appSettings"; | 9 | } from "./appSettings"; |
| ... | @@ -85,21 +84,10 @@ describe("getSlashModelOptions", () => { | ... | @@ -85,21 +84,10 @@ describe("getSlashModelOptions", () => { |
| 85 | }); | 84 | }); |
| 86 | }); | 85 | }); |
| 87 | 86 | ||
| 88 | describe("resolveAppServiceTier", () => { | ||
| 89 | it("maps automatic to no override", () => { | ||
| 90 | expect(resolveAppServiceTier("auto")).toBeNull(); | ||
| 91 | }); | ||
| 92 | |||
| 93 | it("preserves explicit service tier overrides", () => { | ||
| 94 | expect(resolveAppServiceTier("fast")).toBe("fast"); | ||
| 95 | expect(resolveAppServiceTier("flex")).toBe("flex"); | ||
| 96 | }); | ||
| 97 | }); | ||
| 98 | |||
| 99 | describe("shouldShowFastTierIcon", () => { | 87 | describe("shouldShowFastTierIcon", () => { |
| 100 | it("shows the fast-tier icon only for gpt-5.4 on fast tier", () => { | 88 | it("shows the fast-tier icon only for gpt-5.4 when fast mode is enabled", () => { |
| 101 | expect(shouldShowFastTierIcon("gpt-5.4", "fast")).toBe(true); | 89 | expect(shouldShowFastTierIcon("gpt-5.4", true)).toBe(true); |
| 102 | expect(shouldShowFastTierIcon("gpt-5.4", "auto")).toBe(false); | 90 | expect(shouldShowFastTierIcon("gpt-5.4", false)).toBe(false); |
| 103 | expect(shouldShowFastTierIcon("gpt-5.3-codex", "fast")).toBe(false); | 91 | expect(shouldShowFastTierIcon("gpt-5.3-codex", true)).toBe(false); |
| 104 | }); | 92 | }); |
| 105 | }); | 93 | }); |
apps/web/src/appSettings.ts+3-27| ... | @@ -1,30 +1,11 @@ | ... | @@ -1,30 +1,11 @@ |
| 1 | import { useCallback, useSyncExternalStore } from "react"; | 1 | import { useCallback, useSyncExternalStore } from "react"; |
| 2 | import { Option, Schema } from "effect"; | 2 | import { Option, Schema } from "effect"; |
| 3 | import { type ProviderKind, type ProviderServiceTier } from "@t3tools/contracts"; | 3 | import { type ProviderKind } from "@t3tools/contracts"; |
| 4 | import { getDefaultModel, getModelOptions, normalizeModelSlug } from "@t3tools/shared/model"; | 4 | import { getDefaultModel, getModelOptions, normalizeModelSlug } from "@t3tools/shared/model"; |
| 5 | 5 | ||
| 6 | const APP_SETTINGS_STORAGE_KEY = "t3code:app-settings:v1"; | 6 | const APP_SETTINGS_STORAGE_KEY = "t3code:app-settings:v1"; |
| 7 | const MAX_CUSTOM_MODEL_COUNT = 32; | 7 | const MAX_CUSTOM_MODEL_COUNT = 32; |
| 8 | export const MAX_CUSTOM_MODEL_LENGTH = 256; | 8 | export const MAX_CUSTOM_MODEL_LENGTH = 256; |
| 9 | export const APP_SERVICE_TIER_OPTIONS = [ | ||
| 10 | { | ||
| 11 | value: "auto", | ||
| 12 | label: "Automatic", | ||
| 13 | description: "Use Codex defaults without forcing a service tier.", | ||
| 14 | }, | ||
| 15 | { | ||
| 16 | value: "fast", | ||
| 17 | label: "Fast", | ||
| 18 | description: "Request the fast service tier when the model supports it.", | ||
| 19 | }, | ||
| 20 | { | ||
| 21 | value: "flex", | ||
| 22 | label: "Flex", | ||
| 23 | description: "Request the flex service tier when the model supports it.", | ||
| 24 | }, | ||
| 25 | ] as const; | ||
| 26 | export type AppServiceTier = (typeof APP_SERVICE_TIER_OPTIONS)[number]["value"]; | ||
| 27 | const AppServiceTierSchema = Schema.Literals(["auto", "fast", "flex"]); | ||
| 28 | const MODELS_WITH_FAST_SUPPORT = new Set(["gpt-5.4"]); | 9 | const MODELS_WITH_FAST_SUPPORT = new Set(["gpt-5.4"]); |
| 29 | const BUILT_IN_MODEL_SLUGS_BY_PROVIDER: Record<ProviderKind, ReadonlySet<string>> = { | 10 | const BUILT_IN_MODEL_SLUGS_BY_PROVIDER: Record<ProviderKind, ReadonlySet<string>> = { |
| 30 | codex: new Set(getModelOptions("codex").map((option) => option.slug)), | 11 | codex: new Set(getModelOptions("codex").map((option) => option.slug)), |
| ... | @@ -41,7 +22,6 @@ const AppSettingsSchema = Schema.Struct({ | ... | @@ -41,7 +22,6 @@ const AppSettingsSchema = Schema.Struct({ |
| 41 | enableAssistantStreaming: Schema.Boolean.pipe( | 22 | enableAssistantStreaming: Schema.Boolean.pipe( |
| 42 | Schema.withConstructorDefault(() => Option.some(false)), | 23 | Schema.withConstructorDefault(() => Option.some(false)), |
| 43 | ), | 24 | ), |
| 44 | codexServiceTier: AppServiceTierSchema.pipe(Schema.withConstructorDefault(() => Option.some("auto"))), | ||
| 45 | customCodexModels: Schema.Array(Schema.String).pipe( | 25 | customCodexModels: Schema.Array(Schema.String).pipe( |
| 46 | Schema.withConstructorDefault(() => Option.some([])), | 26 | Schema.withConstructorDefault(() => Option.some([])), |
| 47 | ), | 27 | ), |
| ... | @@ -53,17 +33,13 @@ export interface AppModelOption { | ... | @@ -53,17 +33,13 @@ export interface AppModelOption { |
| 53 | isCustom: boolean; | 33 | isCustom: boolean; |
| 54 | } | 34 | } |
| 55 | 35 | ||
| 56 | export function resolveAppServiceTier(serviceTier: AppServiceTier): ProviderServiceTier | null { | ||
| 57 | return serviceTier === "auto" ? null : serviceTier; | ||
| 58 | } | ||
| 59 | |||
| 60 | export function shouldShowFastTierIcon( | 36 | export function shouldShowFastTierIcon( |
| 61 | model: string | null | undefined, | 37 | model: string | null | undefined, |
| 62 | serviceTier: AppServiceTier, | 38 | fastModeEnabled: boolean, |
| 63 | ): boolean { | 39 | ): boolean { |
| 64 | const normalizedModel = normalizeModelSlug(model); | 40 | const normalizedModel = normalizeModelSlug(model); |
| 65 | return ( | 41 | return ( |
| 66 | resolveAppServiceTier(serviceTier) === "fast" && | 42 | fastModeEnabled && |
| 67 | normalizedModel !== null && | 43 | normalizedModel !== null && |
| 68 | MODELS_WITH_FAST_SUPPORT.has(normalizedModel) | 44 | MODELS_WITH_FAST_SUPPORT.has(normalizedModel) |
| 69 | ); | 45 | ); |
apps/web/src/components/ChatView.tsx+7-12| ... | @@ -205,9 +205,7 @@ import { readNativeApi } from "~/nativeApi"; | ... | @@ -205,9 +205,7 @@ import { readNativeApi } from "~/nativeApi"; |
| 205 | import { | 205 | import { |
| 206 | getAppModelOptions, | 206 | getAppModelOptions, |
| 207 | resolveAppModelSelection, | 207 | resolveAppModelSelection, |
| 208 | resolveAppServiceTier, | ||
| 209 | shouldShowFastTierIcon, | 208 | shouldShowFastTierIcon, |
| 210 | type AppServiceTier, | ||
| 211 | useAppSettings, | 209 | useAppSettings, |
| 212 | } from "../appSettings"; | 210 | } from "../appSettings"; |
| 213 | import { | 211 | import { |
| ... | @@ -785,8 +783,6 @@ export default function ChatView({ threadId }: ChatViewProps) { | ... | @@ -785,8 +783,6 @@ export default function ChatView({ threadId }: ChatViewProps) { |
| 785 | activeThread.messages.length > 0 || | 783 | activeThread.messages.length > 0 || |
| 786 | activeThread.session !== null), | 784 | activeThread.session !== null), |
| 787 | ); | 785 | ); |
| 788 | const selectedServiceTierSetting = settings.codexServiceTier; | ||
| 789 | const selectedServiceTier = resolveAppServiceTier(selectedServiceTierSetting); | ||
| 790 | const lockedProvider: ProviderKind | null = hasThreadStarted | 786 | const lockedProvider: ProviderKind | null = hasThreadStarted |
| 791 | ? (sessionProvider ?? selectedProviderByThreadId ?? null) | 787 | ? (sessionProvider ?? selectedProviderByThreadId ?? null) |
| 792 | : null; | 788 | : null; |
| ... | @@ -1255,9 +1251,9 @@ export default function ChatView({ threadId }: ChatViewProps) { | ... | @@ -1255,9 +1251,9 @@ export default function ChatView({ threadId }: ChatViewProps) { |
| 1255 | label: name, | 1251 | label: name, |
| 1256 | description: `${providerLabel} · ${slug}`, | 1252 | description: `${providerLabel} · ${slug}`, |
| 1257 | showFastBadge: | 1253 | showFastBadge: |
| 1258 | provider === "codex" && shouldShowFastTierIcon(slug, selectedServiceTierSetting), | 1254 | provider === "codex" && shouldShowFastTierIcon(slug, selectedCodexFastModeEnabled), |
| 1259 | })); | 1255 | })); |
| 1260 | }, [composerTrigger, searchableModelOptions, selectedServiceTierSetting, workspaceEntries]); | 1256 | }, [composerTrigger, searchableModelOptions, selectedCodexFastModeEnabled, workspaceEntries]); |
| 1261 | const composerMenuOpen = Boolean(composerTrigger); | 1257 | const composerMenuOpen = Boolean(composerTrigger); |
| 1262 | const activeComposerMenuItem = useMemo( | 1258 | const activeComposerMenuItem = useMemo( |
| 1263 | () => | 1259 | () => |
| ... | @@ -2665,7 +2661,6 @@ export default function ChatView({ threadId }: ChatViewProps) { | ... | @@ -2665,7 +2661,6 @@ export default function ChatView({ threadId }: ChatViewProps) { |
| 2665 | attachments: turnAttachments, | 2661 | attachments: turnAttachments, |
| 2666 | }, | 2662 | }, |
| 2667 | model: selectedModel || undefined, | 2663 | model: selectedModel || undefined, |
| 2668 | serviceTier: selectedServiceTier, | ||
| 2669 | ...(selectedModelOptionsForDispatch | 2664 | ...(selectedModelOptionsForDispatch |
| 2670 | ? { modelOptions: selectedModelOptionsForDispatch } | 2665 | ? { modelOptions: selectedModelOptionsForDispatch } |
| 2671 | : {}), | 2666 | : {}), |
| ... | @@ -3700,7 +3695,7 @@ export default function ChatView({ threadId }: ChatViewProps) { | ... | @@ -3700,7 +3695,7 @@ export default function ChatView({ threadId }: ChatViewProps) { |
| 3700 | model={selectedModelForPickerWithCustomFallback} | 3695 | model={selectedModelForPickerWithCustomFallback} |
| 3701 | lockedProvider={lockedProvider} | 3696 | lockedProvider={lockedProvider} |
| 3702 | modelOptionsByProvider={modelOptionsByProvider} | 3697 | modelOptionsByProvider={modelOptionsByProvider} |
| 3703 | serviceTierSetting={selectedServiceTierSetting} | 3698 | fastModeEnabled={selectedCodexFastModeEnabled} |
| 3704 | onProviderModelChange={onProviderModelSelect} | 3699 | onProviderModelChange={onProviderModelSelect} |
| 3705 | /> | 3700 | /> |
| 3706 | 3701 | ||
| ... | @@ -5548,7 +5543,7 @@ const ProviderModelPicker = memo(function ProviderModelPicker(props: { | ... | @@ -5548,7 +5543,7 @@ const ProviderModelPicker = memo(function ProviderModelPicker(props: { |
| 5548 | model: ModelSlug; | 5543 | model: ModelSlug; |
| 5549 | lockedProvider: ProviderKind | null; | 5544 | lockedProvider: ProviderKind | null; |
| 5550 | modelOptionsByProvider: Record<ProviderKind, ReadonlyArray<{ slug: string; name: string }>>; | 5545 | modelOptionsByProvider: Record<ProviderKind, ReadonlyArray<{ slug: string; name: string }>>; |
| 5551 | serviceTierSetting: AppServiceTier; | 5546 | fastModeEnabled: boolean; |
| 5552 | disabled?: boolean; | 5547 | disabled?: boolean; |
| 5553 | onProviderModelChange: (provider: ProviderKind, model: ModelSlug) => void; | 5548 | onProviderModelChange: (provider: ProviderKind, model: ModelSlug) => void; |
| 5554 | }) { | 5549 | }) { |
| ... | @@ -5578,10 +5573,10 @@ const ProviderModelPicker = memo(function ProviderModelPicker(props: { | ... | @@ -5578,10 +5573,10 @@ const ProviderModelPicker = memo(function ProviderModelPicker(props: { |
| 5578 | disabled={props.disabled} | 5573 | disabled={props.disabled} |
| 5579 | /> | 5574 | /> |
| 5580 | } | 5575 | } |
| 5581 | > | 5576 | > |
| 5582 | <span className="flex min-w-0 items-center gap-2"> | 5577 | <span className="flex min-w-0 items-center gap-2"> |
| 5583 | <ProviderIcon aria-hidden="true" className="size-4 shrink-0 text-muted-foreground/70" /> | 5578 | <ProviderIcon aria-hidden="true" className="size-4 shrink-0 text-muted-foreground/70" /> |
| 5584 | {props.provider === "codex" && shouldShowFastTierIcon(props.model, props.serviceTierSetting) ? ( | 5579 | {props.provider === "codex" && shouldShowFastTierIcon(props.model, props.fastModeEnabled) ? ( |
| 5585 | <ZapIcon className="size-3.5 shrink-0 text-amber-500" /> | 5580 | <ZapIcon className="size-3.5 shrink-0 text-amber-500" /> |
| 5586 | ) : null} | 5581 | ) : null} |
| 5587 | <span className="truncate">{selectedModelLabel}</span> | 5582 | <span className="truncate">{selectedModelLabel}</span> |
| ... | @@ -5627,7 +5622,7 @@ const ProviderModelPicker = memo(function ProviderModelPicker(props: { | ... | @@ -5627,7 +5622,7 @@ const ProviderModelPicker = memo(function ProviderModelPicker(props: { |
| 5627 | onClick={() => setIsMenuOpen(false)} | 5622 | onClick={() => setIsMenuOpen(false)} |
| 5628 | > | 5623 | > |
| 5629 | {option.value === "codex" && | 5624 | {option.value === "codex" && |
| 5630 | shouldShowFastTierIcon(modelOption.slug, props.serviceTierSetting) ? ( | 5625 | shouldShowFastTierIcon(modelOption.slug, props.fastModeEnabled) ? ( |
| 5631 | <ZapIcon className="size-3.5 shrink-0 text-amber-500" /> | 5626 | <ZapIcon className="size-3.5 shrink-0 text-amber-500" /> |
| 5632 | ) : null} | 5627 | ) : null} |
| 5633 | {modelOption.name} | 5628 | {modelOption.name} |
apps/web/src/routes/_chat.settings.tsx+5-55| ... | @@ -3,14 +3,8 @@ import { useQuery } from "@tanstack/react-query"; | ... | @@ -3,14 +3,8 @@ import { useQuery } from "@tanstack/react-query"; |
| 3 | import { useCallback, useState } from "react"; | 3 | import { useCallback, useState } from "react"; |
| 4 | import { type ProviderKind } from "@t3tools/contracts"; | 4 | import { type ProviderKind } from "@t3tools/contracts"; |
| 5 | import { getModelOptions, normalizeModelSlug } from "@t3tools/shared/model"; | 5 | import { getModelOptions, normalizeModelSlug } from "@t3tools/shared/model"; |
| 6 | import { ZapIcon } from "lucide-react"; | 6 | |
| 7 | 7 | import { MAX_CUSTOM_MODEL_LENGTH, useAppSettings } from "../appSettings"; | |
| 8 | import { | ||
| 9 | APP_SERVICE_TIER_OPTIONS, | ||
| 10 | MAX_CUSTOM_MODEL_LENGTH, | ||
| 11 | shouldShowFastTierIcon, | ||
| 12 | useAppSettings, | ||
| 13 | } from "../appSettings"; | ||
| 14 | import { isElectron } from "../env"; | 8 | import { isElectron } from "../env"; |
| 15 | import { useTheme } from "../hooks/useTheme"; | 9 | import { useTheme } from "../hooks/useTheme"; |
| 16 | import { serverConfigQueryOptions } from "../lib/serverReactQuery"; | 10 | import { serverConfigQueryOptions } from "../lib/serverReactQuery"; |
| ... | @@ -18,7 +12,6 @@ import { ensureNativeApi } from "../nativeApi"; | ... | @@ -18,7 +12,6 @@ import { ensureNativeApi } from "../nativeApi"; |
| 18 | import { preferredTerminalEditor } from "../terminal-links"; | 12 | import { preferredTerminalEditor } from "../terminal-links"; |
| 19 | import { Button } from "../components/ui/button"; | 13 | import { Button } from "../components/ui/button"; |
| 20 | import { Input } from "../components/ui/input"; | 14 | import { Input } from "../components/ui/input"; |
| 21 | import { Select, SelectItem, SelectPopup, SelectTrigger, SelectValue } from "../components/ui/select"; | ||
| 22 | import { Switch } from "../components/ui/switch"; | 15 | import { Switch } from "../components/ui/switch"; |
| 23 | import { SidebarInset } from "~/components/ui/sidebar"; | 16 | import { SidebarInset } from "~/components/ui/sidebar"; |
| 24 | 17 | ||
| ... | @@ -103,7 +96,6 @@ function SettingsRouteView() { | ... | @@ -103,7 +96,6 @@ function SettingsRouteView() { |
| 103 | 96 | ||
| 104 | const codexBinaryPath = settings.codexBinaryPath; | 97 | const codexBinaryPath = settings.codexBinaryPath; |
| 105 | const codexHomePath = settings.codexHomePath; | 98 | const codexHomePath = settings.codexHomePath; |
| 106 | const codexServiceTier = settings.codexServiceTier; | ||
| 107 | const keybindingsConfigPath = serverConfigQuery.data?.keybindingsConfigPath ?? null; | 99 | const keybindingsConfigPath = serverConfigQuery.data?.keybindingsConfigPath ?? null; |
| 108 | 100 | ||
| 109 | const openKeybindingsFile = useCallback(() => { | 101 | const openKeybindingsFile = useCallback(() => { |
| ... | @@ -310,43 +302,6 @@ function SettingsRouteView() { | ... | @@ -310,43 +302,6 @@ function SettingsRouteView() { |
| 310 | </div> | 302 | </div> |
| 311 | 303 | ||
| 312 | <div className="space-y-5"> | 304 | <div className="space-y-5"> |
| 313 | <label className="block space-y-1"> | ||
| 314 | <span className="text-xs font-medium text-foreground">Default service tier</span> | ||
| 315 | <Select | ||
| 316 | items={APP_SERVICE_TIER_OPTIONS.map((option) => ({ | ||
| 317 | label: option.label, | ||
| 318 | value: option.value, | ||
| 319 | }))} | ||
| 320 | value={codexServiceTier} | ||
| 321 | onValueChange={(value) => { | ||
| 322 | if (!value) return; | ||
| 323 | updateSettings({ codexServiceTier: value }); | ||
| 324 | }} | ||
| 325 | > | ||
| 326 | <SelectTrigger> | ||
| 327 | <SelectValue /> | ||
| 328 | </SelectTrigger> | ||
| 329 | <SelectPopup alignItemWithTrigger={false}> | ||
| 330 | {APP_SERVICE_TIER_OPTIONS.map((option) => ( | ||
| 331 | <SelectItem key={option.value} value={option.value}> | ||
| 332 | <div className="flex min-w-0 items-center gap-2"> | ||
| 333 | {option.value === "fast" ? ( | ||
| 334 | <ZapIcon className="size-3.5 text-amber-500" /> | ||
| 335 | ) : ( | ||
| 336 | <span className="size-3.5 shrink-0" aria-hidden="true" /> | ||
| 337 | )} | ||
| 338 | <span className="truncate">{option.label}</span> | ||
| 339 | </div> | ||
| 340 | </SelectItem> | ||
| 341 | ))} | ||
| 342 | </SelectPopup> | ||
| 343 | </Select> | ||
| 344 | <span className="text-xs text-muted-foreground"> | ||
| 345 | {APP_SERVICE_TIER_OPTIONS.find((option) => option.value === codexServiceTier) | ||
| 346 | ?.description ?? "Use Codex defaults without forcing a service tier."} | ||
| 347 | </span> | ||
| 348 | </label> | ||
| 349 | |||
| 350 | {MODEL_PROVIDER_SETTINGS.map((providerSettings) => { | 305 | {MODEL_PROVIDER_SETTINGS.map((providerSettings) => { |
| 351 | const provider = providerSettings.provider; | 306 | const provider = providerSettings.provider; |
| 352 | const customModels = getCustomModelsForProvider(settings, provider); | 307 | const customModels = getCustomModelsForProvider(settings, provider); |
| ... | @@ -445,14 +400,9 @@ function SettingsRouteView() { | ... | @@ -445,14 +400,9 @@ function SettingsRouteView() { |
| 445 | key={`${provider}:${slug}`} | 400 | key={`${provider}:${slug}`} |
| 446 | className="flex items-center justify-between gap-3 rounded-lg border border-border bg-background px-3 py-2" | 401 | className="flex items-center justify-between gap-3 rounded-lg border border-border bg-background px-3 py-2" |
| 447 | > | 402 | > |
| 448 | <div className="flex min-w-0 flex-1 items-center gap-2"> | 403 | <code className="min-w-0 flex-1 truncate text-xs text-foreground"> |
| 449 | {provider === "codex" && shouldShowFastTierIcon(slug, codexServiceTier) ? ( | 404 | {slug} |
| 450 | <ZapIcon className="size-3.5 shrink-0 text-amber-500" /> | 405 | </code> |
| 451 | ) : null} | ||
| 452 | <code className="min-w-0 flex-1 truncate text-xs text-foreground"> | ||
| 453 | {slug} | ||
| 454 | </code> | ||
| 455 | </div> | ||
| 456 | <Button | 406 | <Button |
| 457 | size="xs" | 407 | size="xs" |
| 458 | variant="ghost" | 408 | variant="ghost" |
packages/contracts/src/orchestration.ts-5| ... | @@ -42,8 +42,6 @@ export const ProviderSandboxMode = Schema.Literals([ | ... | @@ -42,8 +42,6 @@ export const ProviderSandboxMode = Schema.Literals([ |
| 42 | "danger-full-access", | 42 | "danger-full-access", |
| 43 | ]); | 43 | ]); |
| 44 | export type ProviderSandboxMode = typeof ProviderSandboxMode.Type; | 44 | export type ProviderSandboxMode = typeof ProviderSandboxMode.Type; |
| 45 | export const ProviderServiceTier = Schema.Literals(["fast", "flex"]); | ||
| 46 | export type ProviderServiceTier = typeof ProviderServiceTier.Type; | ||
| 47 | export const DEFAULT_PROVIDER_KIND: ProviderKind = "codex"; | 45 | export const DEFAULT_PROVIDER_KIND: ProviderKind = "codex"; |
| 48 | const CodexProviderStartOptions = Schema.Struct({ | 46 | const CodexProviderStartOptions = Schema.Struct({ |
| 49 | binaryPath: Schema.optional(TrimmedNonEmptyString), | 47 | binaryPath: Schema.optional(TrimmedNonEmptyString), |
| ... | @@ -371,7 +369,6 @@ export const ThreadTurnStartCommand = Schema.Struct({ | ... | @@ -371,7 +369,6 @@ export const ThreadTurnStartCommand = Schema.Struct({ |
| 371 | }), | 369 | }), |
| 372 | provider: Schema.optional(ProviderKind), | 370 | provider: Schema.optional(ProviderKind), |
| 373 | model: Schema.optional(TrimmedNonEmptyString), | 371 | model: Schema.optional(TrimmedNonEmptyString), |
| 374 | serviceTier: Schema.optional(Schema.NullOr(ProviderServiceTier)), | ||
| 375 | modelOptions: Schema.optional(ProviderModelOptions), | 372 | modelOptions: Schema.optional(ProviderModelOptions), |
| 376 | providerOptions: Schema.optional(ProviderStartOptions), | 373 | providerOptions: Schema.optional(ProviderStartOptions), |
| 377 | assistantDeliveryMode: Schema.optional(AssistantDeliveryMode), | 374 | assistantDeliveryMode: Schema.optional(AssistantDeliveryMode), |
| ... | @@ -394,7 +391,6 @@ const ClientThreadTurnStartCommand = Schema.Struct({ | ... | @@ -394,7 +391,6 @@ const ClientThreadTurnStartCommand = Schema.Struct({ |
| 394 | }), | 391 | }), |
| 395 | provider: Schema.optional(ProviderKind), | 392 | provider: Schema.optional(ProviderKind), |
| 396 | model: Schema.optional(TrimmedNonEmptyString), | 393 | model: Schema.optional(TrimmedNonEmptyString), |
| 397 | serviceTier: Schema.optional(Schema.NullOr(ProviderServiceTier)), | ||
| 398 | modelOptions: Schema.optional(ProviderModelOptions), | 394 | modelOptions: Schema.optional(ProviderModelOptions), |
| 399 | providerOptions: Schema.optional(ProviderStartOptions), | 395 | providerOptions: Schema.optional(ProviderStartOptions), |
| 400 | assistantDeliveryMode: Schema.optional(AssistantDeliveryMode), | 396 | assistantDeliveryMode: Schema.optional(AssistantDeliveryMode), |
| ... | @@ -675,7 +671,6 @@ export const ThreadTurnStartRequestedPayload = Schema.Struct({ | ... | @@ -675,7 +671,6 @@ export const ThreadTurnStartRequestedPayload = Schema.Struct({ |
| 675 | messageId: MessageId, | 671 | messageId: MessageId, |
| 676 | provider: Schema.optional(ProviderKind), | 672 | provider: Schema.optional(ProviderKind), |
| 677 | model: Schema.optional(TrimmedNonEmptyString), | 673 | model: Schema.optional(TrimmedNonEmptyString), |
| 678 | serviceTier: Schema.optional(Schema.NullOr(ProviderServiceTier)), | ||
| 679 | modelOptions: Schema.optional(ProviderModelOptions), | 674 | modelOptions: Schema.optional(ProviderModelOptions), |
| 680 | providerOptions: Schema.optional(ProviderStartOptions), | 675 | providerOptions: Schema.optional(ProviderStartOptions), |
| 681 | assistantDeliveryMode: Schema.optional(AssistantDeliveryMode), | 676 | assistantDeliveryMode: Schema.optional(AssistantDeliveryMode), |
packages/contracts/src/provider.ts-3| ... | @@ -19,7 +19,6 @@ import { | ... | @@ -19,7 +19,6 @@ import { |
| 19 | ProviderKind, | 19 | ProviderKind, |
| 20 | ProviderRequestKind, | 20 | ProviderRequestKind, |
| 21 | ProviderSandboxMode, | 21 | ProviderSandboxMode, |
| 22 | ProviderServiceTier, | ||
| 23 | ProviderUserInputAnswers, | 22 | ProviderUserInputAnswers, |
| 24 | RuntimeMode, | 23 | RuntimeMode, |
| 25 | } from "./orchestration"; | 24 | } from "./orchestration"; |
| ... | @@ -65,7 +64,6 @@ export const ProviderSessionStartInput = Schema.Struct({ | ... | @@ -65,7 +64,6 @@ export const ProviderSessionStartInput = Schema.Struct({ |
| 65 | model: Schema.optional(TrimmedNonEmptyStringSchema), | 64 | model: Schema.optional(TrimmedNonEmptyStringSchema), |
| 66 | modelOptions: Schema.optional(ProviderModelOptions), | 65 | modelOptions: Schema.optional(ProviderModelOptions), |
| 67 | resumeCursor: Schema.optional(Schema.Unknown), | 66 | resumeCursor: Schema.optional(Schema.Unknown), |
| 68 | serviceTier: Schema.optional(Schema.NullOr(ProviderServiceTier)), | ||
| 69 | approvalPolicy: Schema.optional(ProviderApprovalPolicy), | 67 | approvalPolicy: Schema.optional(ProviderApprovalPolicy), |
| 70 | sandboxMode: Schema.optional(ProviderSandboxMode), | 68 | sandboxMode: Schema.optional(ProviderSandboxMode), |
| 71 | providerOptions: Schema.optional(ProviderStartOptions), | 69 | providerOptions: Schema.optional(ProviderStartOptions), |
| ... | @@ -82,7 +80,6 @@ export const ProviderSendTurnInput = Schema.Struct({ | ... | @@ -82,7 +80,6 @@ export const ProviderSendTurnInput = Schema.Struct({ |
| 82 | Schema.Array(ChatAttachment).check(Schema.isMaxLength(PROVIDER_SEND_TURN_MAX_ATTACHMENTS)), | 80 | Schema.Array(ChatAttachment).check(Schema.isMaxLength(PROVIDER_SEND_TURN_MAX_ATTACHMENTS)), |
| 83 | ), | 81 | ), |
| 84 | model: Schema.optional(TrimmedNonEmptyStringSchema), | 82 | model: Schema.optional(TrimmedNonEmptyStringSchema), |
| 85 | serviceTier: Schema.optional(Schema.NullOr(ProviderServiceTier)), | ||
| 86 | modelOptions: Schema.optional(ProviderModelOptions), | 83 | modelOptions: Schema.optional(ProviderModelOptions), |
| 87 | interactionMode: Schema.optional(ProviderInteractionMode), | 84 | interactionMode: Schema.optional(ProviderInteractionMode), |
| 88 | }); | 85 | }); |