mirror of
https://github.com/getpaseo/paseo.git
synced 2026-11-02 06:33:05 +00:00
fix(server): Codex returns the tier it resolved and drops a speed the new model lacks
A live service_tier: fast is stored as the catalog's Fast tier id instead of a value the control cannot show, and a model switch to a model without the stored speed reports Normal so choosing a supporting model again does not bring the paid tier back.
This commit is contained in:
@@ -563,6 +563,39 @@ describe("Codex app-server provider controls", () => {
|
||||
await expect(appServer.waitForTurnStart()).resolves.toMatchObject({ serviceTier: "priority" });
|
||||
});
|
||||
|
||||
test("a live service_tier: fast is returned as the model's Fast tier", async () => {
|
||||
const { session, appServer } = await createConnectedSession();
|
||||
|
||||
await expect(session.applyOptions?.({ service_tier: "fast" })).resolves.toEqual({
|
||||
service_tier: "priority",
|
||||
});
|
||||
|
||||
await session.startTurn("hello");
|
||||
await expect(appServer.waitForTurnStart()).resolves.toMatchObject({ serviceTier: "priority" });
|
||||
});
|
||||
|
||||
test("switching to a model without the speed tier says Normal and keeps it so on the way back", async () => {
|
||||
const models = [
|
||||
...TEST_SPEED_MODELS,
|
||||
{ id: "plain", isDefault: false, defaultReasoningEffort: "medium", serviceTiers: [] },
|
||||
];
|
||||
const { session, appServer } = await createConnectedSession(
|
||||
{ model: "gpt-5.4", providerOptions: { service_tier: "priority" } },
|
||||
{ models },
|
||||
);
|
||||
const events: AgentStreamEvent[] = [];
|
||||
session.subscribe((event) => events.push(event));
|
||||
|
||||
await session.setModel?.("plain");
|
||||
await session.setModel?.("gpt-5.4");
|
||||
|
||||
expect(events.filter((event) => event.type === "options_changed")).toEqual([
|
||||
{ type: "options_changed", provider: "codex", patch: { service_tier: "default" } },
|
||||
]);
|
||||
await session.startTurn("hello");
|
||||
await expect(appServer.waitForTurnStart()).resolves.toMatchObject({ serviceTier: "default" });
|
||||
});
|
||||
|
||||
describe("a pre-v0.10 fast_mode: true option", () => {
|
||||
function createLegacyFastHarness(configDefaults: Record<string, unknown> = {}) {
|
||||
const appServer = createFakeCodexAppServer({
|
||||
|
||||
@@ -4665,6 +4665,26 @@ export class CodexAppServerAgentSession implements AgentSession {
|
||||
this.config.model = modelId ?? undefined;
|
||||
this.refreshResolvedCollaborationMode();
|
||||
this.cachedRuntimeInfo = null;
|
||||
this.dropUnavailableServiceTier();
|
||||
}
|
||||
|
||||
/**
|
||||
* A speed the new model does not offer turns into Normal and is reported, so choosing a model
|
||||
* that does offer it again does not bring the paid tier back. It is reported as Normal rather
|
||||
* than removed so a configured default cannot fill the old speed back in.
|
||||
*/
|
||||
private dropUnavailableServiceTier(): void {
|
||||
const requested = this.requestedServiceTier;
|
||||
if (requested === null || this.speedModels.length === 0) return;
|
||||
if (this.isServiceTierAvailable(requested)) return;
|
||||
this.requestedServiceTier = "default";
|
||||
const { fast_mode: legacyFast, ...running } = this.providerOptions;
|
||||
this.providerOptions = { ...running, service_tier: "default" };
|
||||
this.emitEvent({
|
||||
type: "options_changed",
|
||||
provider: CODEX_PROVIDER,
|
||||
patch: { service_tier: "default", ...(legacyFast === undefined ? {} : { fast_mode: null }) },
|
||||
});
|
||||
}
|
||||
|
||||
async setThinkingOption(thinkingOptionId: string | null): Promise<void | AgentProviderNotice> {
|
||||
@@ -4707,6 +4727,15 @@ export class CodexAppServerAgentSession implements AgentSession {
|
||||
if ("fast_mode" in options && !("service_tier" in options) && options.fast_mode !== null) {
|
||||
return tier === null ? {} : { service_tier: tier, fast_mode: null };
|
||||
}
|
||||
// The catalog may name the tier differently from the request (`fast` is the Fast tier's id).
|
||||
if (
|
||||
"service_tier" in options &&
|
||||
tier !== null &&
|
||||
requestedTier !== null &&
|
||||
tier !== requestedTier
|
||||
) {
|
||||
return { service_tier: tier };
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user