fix(model-policy-freshness): accept OpenAI deprecated cells with a display name before the backticked ids (#3155)

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
This commit is contained in:
garrytanandcapy-ai[bot] committed 2026-10-24 20:06:55 +00:00
1 parent 00100f1598
commit efe8f74ffd
3 files changed
+12 -2

No files matched your search

-1
View File
@@ -178,7 +178,6 @@ function openaiLifecycle(text: string): ParsedSource {
if (!upcoming || !modelTables.length) throw new Error('missing-deprecation-tables');
const lifecycle = modelTables.flatMap(table => table.slice(1).flatMap(row => {
if (/^(?:Videos API|Assistants API|OpenAI-Beta: |New fine-tuning training on )/.test(row[1]) || row[1].startsWith('`/')) return [];
if (!row[1].startsWith('`')) throw new Error('unrecognized-deprecated-model-cell');
const floor = row[0].startsWith('at earliest ');
const date = lifecycleDate(row[0].replace(/^at earliest /, ''));
if (!date) throw new Error('missing-shutdown-date');
@@ -9,6 +9,7 @@ This page lists all API deprecations, along with recommended replacements.
| Shutdown date | Model / system | Recommended replacement |
| --- | --- | --- |
| Apr 1, 2027 | `gpt-5.3-codex` | `gpt-6-sol` |
| Feb 16, 2027 | GPT-4o (`gpt-4o-2024-08-06`, `gpt-4o-2024-11-20`) | `gpt-6-sol` |
## Past deprecations
+11 -1
View File
@@ -11,7 +11,7 @@ describe('official recommendation and lifecycle structures', () => {
expect(anthropic.recommendations).toEqual({ frontier: 'claude-fable-5-1', smart: 'claude-opus-5-5' });
expect(anthropic.lineup).not.toContain('claude-mythos-5-1');
const openai = parseOfficialSource('openai-lifecycle', freshnessFixture('openai-lifecycle'));
expect(openai.lifecycle?.map(row => row.modelId)).toEqual(['gpt-5.3-codex', 'gpt-old', 'gpt-unicode-date', 'gpt-iso-date', 'gpt-date-floor']);
expect(openai.lifecycle?.map(row => row.modelId)).toEqual(['gpt-5.3-codex', 'gpt-4o-2024-08-06', 'gpt-4o-2024-11-20', 'gpt-old', 'gpt-unicode-date', 'gpt-iso-date', 'gpt-date-floor']);
expect(openai.lifecycle?.find(row => row.modelId === 'gpt-date-floor')).toMatchObject({ deadline: null, supportFloor: '2024-06-13' });
});
@@ -57,6 +57,16 @@ describe('official recommendation and lifecycle structures', () => {
expect(report.state.lifecycle[0]).toMatchObject({ modelId: 'gpt-6-astra', deadline: '2027-04-01' });
});
test('OpenAI deprecated cells with a display name before the backticked IDs yield every ID', () => {
const openai = parseOfficialSource('openai-lifecycle', freshnessFixture('openai-lifecycle'));
expect(openai.lifecycle?.filter(row => row.modelId.startsWith('gpt-4o-'))).toEqual([
{ modelId: 'gpt-4o-2024-08-06', state: 'deprecated', deadline: '2027-02-16', supportFloor: null },
{ modelId: 'gpt-4o-2024-11-20', state: 'deprecated', deadline: '2027-02-16', supportFloor: null },
]);
const unticked = freshnessFixture('openai-lifecycle').replace('GPT-4o (`gpt-4o-2024-08-06`, `gpt-4o-2024-11-20`)', 'GPT-4o (gpt-4o-2024-08-06, gpt-4o-2024-11-20)');
expect(() => parseOfficialSource('openai-lifecycle', unticked)).toThrow('unrecognized-deprecated-model-cell');
});
test('missing required structures and semantic drift fail closed', () => {
expect(() => parseOfficialSource('anthropic-models', freshnessFixture('anthropic-models').replace('Claude API ID', 'Google Cloud ID'))).toThrow('missing-api-id-row');
expect(() => parseOfficialSource('anthropic-models', freshnessFixture('anthropic-models').replace('for demanding reasoning', 'for unexplained goals'))).toThrow('unrecognized-recommendation');