fix(team): downgrade unavailable codex fast launches
This commit is contained in:
parent
0a3876e141
commit
08b1de7fa2
4 changed files with 47 additions and 44 deletions
|
|
@ -55,15 +55,6 @@ function buildProviderFastModeArgs(config: ScheduleLaunchConfig): string[] {
|
|||
}
|
||||
|
||||
function validateFastModeLaunchConfig(config: ScheduleLaunchConfig): void {
|
||||
if (
|
||||
config.providerId === 'codex' &&
|
||||
config.fastMode === 'on' &&
|
||||
config.resolvedFastMode !== true
|
||||
) {
|
||||
throw new Error(
|
||||
'Codex Fast mode was requested for this schedule, but the saved launch profile is not Fast-eligible. Reopen the schedule and save it again with a supported ChatGPT account configuration.'
|
||||
);
|
||||
}
|
||||
if (config.providerId !== 'codex' || config.resolvedFastMode !== true) {
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4987,22 +4987,8 @@ export class TeamProvisioningService {
|
|||
);
|
||||
}
|
||||
|
||||
const codexSelection = resolveCodexSelectionFromFacts({
|
||||
selectedModel: params.model,
|
||||
facts: params.facts,
|
||||
});
|
||||
const codexFastResolution = resolveCodexFastMode({
|
||||
selection: codexSelection,
|
||||
selectedFastMode: params.fastMode,
|
||||
});
|
||||
if ((params.fastMode ?? 'inherit') === 'on' && !codexFastResolution.selectable) {
|
||||
throw new Error(
|
||||
`${params.actorLabel} enables Codex Fast mode, but ${
|
||||
codexFastResolution.disabledReason ??
|
||||
'it is unavailable for the selected runtime, model, or auth mode.'
|
||||
}`
|
||||
);
|
||||
}
|
||||
// Codex Fast is optional acceleration. If it is no longer eligible, the launch identity
|
||||
// resolves it to normal Codex mode instead of blocking an otherwise launch-ready model.
|
||||
|
||||
if (!explicitModel || params.facts.modelIds.has(explicitModel)) {
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -529,26 +529,32 @@ describe('ScheduledTaskExecutor', () => {
|
|||
proc.emit('close', 0);
|
||||
});
|
||||
|
||||
it('rejects explicit Codex schedule Fast before spawn when saved eligibility is false', async () => {
|
||||
it('runs a standard Codex schedule when saved Fast eligibility is false', async () => {
|
||||
const proc = createMockProcess();
|
||||
mockSpawnCli.mockReturnValue(proc);
|
||||
|
||||
const executor = new ScheduledTaskExecutor();
|
||||
|
||||
await expect(
|
||||
executor.execute(
|
||||
makeRequest({
|
||||
config: {
|
||||
cwd: '/tmp/project',
|
||||
prompt: 'do it',
|
||||
providerId: 'codex',
|
||||
providerBackendId: 'codex-native',
|
||||
model: 'gpt-5.4-mini',
|
||||
fastMode: 'on',
|
||||
resolvedFastMode: false,
|
||||
},
|
||||
})
|
||||
)
|
||||
).rejects.toThrow('Codex Fast mode was requested');
|
||||
void executor.execute(
|
||||
makeRequest({
|
||||
config: {
|
||||
cwd: '/tmp/project',
|
||||
prompt: 'do it',
|
||||
providerId: 'codex',
|
||||
providerBackendId: 'codex-native',
|
||||
model: 'gpt-5.4-mini',
|
||||
fastMode: 'on',
|
||||
resolvedFastMode: false,
|
||||
},
|
||||
})
|
||||
);
|
||||
await flushAsync();
|
||||
|
||||
expect(mockSpawnCli).not.toHaveBeenCalled();
|
||||
const args = mockSpawnCli.mock.calls[0][1] as string[];
|
||||
expect(args).not.toContain('service_tier="fast"');
|
||||
expect(args).not.toContain('features.fast_mode=true');
|
||||
|
||||
proc.emit('close', 0);
|
||||
});
|
||||
|
||||
it('does not hard-code Codex Fast schedules to GPT-5.4 when saved eligibility is true', async () => {
|
||||
|
|
|
|||
|
|
@ -4556,7 +4556,7 @@ describe('TeamProvisioningService prepare/auth behavior', () => {
|
|||
});
|
||||
});
|
||||
|
||||
it('rejects explicit Codex Fast before launch when auth or model eligibility is invalid', () => {
|
||||
it('allows explicit Codex Fast to downgrade before launch when auth or model eligibility is invalid', () => {
|
||||
const svc = new TeamProvisioningService();
|
||||
const facts = {
|
||||
defaultModel: 'gpt-5.4-mini',
|
||||
|
|
@ -4624,7 +4624,27 @@ describe('TeamProvisioningService prepare/auth behavior', () => {
|
|||
fastMode: 'on',
|
||||
facts,
|
||||
})
|
||||
).toThrow('enables Codex Fast mode');
|
||||
).not.toThrow();
|
||||
|
||||
expect(
|
||||
(svc as any).buildProviderModelLaunchIdentity({
|
||||
request: {
|
||||
providerId: 'codex',
|
||||
providerBackendId: 'codex-native',
|
||||
model: 'gpt-5.4-mini',
|
||||
fastMode: 'on',
|
||||
},
|
||||
facts,
|
||||
})
|
||||
).toMatchObject({
|
||||
providerId: 'codex',
|
||||
providerBackendId: 'codex-native',
|
||||
selectedModel: 'gpt-5.4-mini',
|
||||
resolvedLaunchModel: 'gpt-5.4-mini',
|
||||
selectedFastMode: 'on',
|
||||
resolvedFastMode: false,
|
||||
fastResolutionReason: expect.stringContaining('API key mode uses standard API pricing'),
|
||||
});
|
||||
});
|
||||
|
||||
it('rejects Anthropic max and fast when the exact resolved launch model does not support them', () => {
|
||||
|
|
|
|||
Loading…
Reference in a new issue