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
38 changes: 38 additions & 0 deletions packages/core/src/__tests__/model-metadata.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import { strict as assert } from 'node:assert';
import { describe, it } from 'node:test';
import {
installRefreshedModelMetadata,
lookupModelMetadata,
openAiAdapterApiProtocol,
providerReportsCompleteModelCatalog,
Expand All @@ -36,6 +37,43 @@ describe('provider model-catalog completeness', () => {
});
});

describe('OpenAI Codex OAuth metadata', () => {
it('does not inherit public API input limits across shipped, refreshed, and fallback metadata', () => {
assert.equal(lookupModelMetadata('openai', 'gpt-5.6-sol').inputLimit, 922_000);
assert.equal(lookupModelMetadata('openai-codex', 'gpt-5.6-sol').inputLimit, undefined);
assert.equal(lookupModelMetadata('openai-codex', 'gpt-5.6-terra').inputLimit, undefined);

installRefreshedModelMetadata({
openai: {
'gpt-5.6-sol': { displayName: 'Refreshed Sol', inputLimit: 123_456 },
'gpt-5.6-luna': {
displayName: 'Refreshed Luna',
inputLimit: 234_567,
capabilities: { vision: true },
},
},
});
try {
assert.equal(lookupModelMetadata('openai', 'gpt-5.6-sol').inputLimit, 123_456);
assert.equal(lookupModelMetadata('openai-codex', 'gpt-5.6-sol').inputLimit, undefined);
const refreshedLuna = lookupModelMetadata('openai', 'gpt-5.6-luna');
assert.equal(refreshedLuna.inputLimit, 234_567);

const oauthLuna = lookupModelMetadata('openai-codex', 'gpt-5.6-luna');
assert.equal(oauthLuna.displayName, 'Refreshed Luna');
assert.equal(oauthLuna.capabilities?.vision, true);
assert.equal(oauthLuna.inputLimit, undefined);

const fallback = lookupModelMetadata('openai-codex', 'gpt-5.5');
assert.equal(fallback.displayName, 'GPT-5.5');
assert.equal(fallback.contextWindow, 272_000);
assert.equal(fallback.inputLimit, undefined);
} finally {
installRefreshedModelMetadata(undefined);
}
});
});

describe('model-metadata vision capability', () => {
it('treats a Claude newer than the generated snapshot as able to read images', () => {
assert.deepEqual(lookupModelMetadata('anthropic', 'claude-opus-6'), {});
Expand Down
22 changes: 16 additions & 6 deletions packages/core/src/model-metadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,8 @@ export function lookupModelMetadata(providerType: ProviderType, modelId: string)
const id = modelId.trim();
const metadataProviderType = generatedMetadataProviderType(providerType);
const generated = activeMetadata()[metadataProviderType]?.[id];
const providerMetadata =
providerType === 'openai-codex' ? withoutInputLimit(generated) : generated;
const statics = staticModelMetadata();
const override =
statics[providerType]?.[id] ??
Expand All @@ -113,13 +115,13 @@ export function lookupModelMetadata(providerType: ProviderType, modelId: string)
: providerType === 'opencode-free'
? statics.opencode?.[id]
: undefined);
if (!generated) return override ?? {};
if (!override) return generated;
if (!providerMetadata) return override ?? {};
if (!override) return providerMetadata;
return {
...generated,
...providerMetadata,
...override,
capabilities: { ...generated.capabilities, ...override.capabilities },
modalities: override.modalities ?? generated.modalities,
capabilities: { ...providerMetadata.capabilities, ...override.capabilities },
modalities: override.modalities ?? providerMetadata.modalities,
};
}

Expand Down Expand Up @@ -251,7 +253,15 @@ const GOOGLE_MODEL_OVERRIDES: Record<string, ModelMetadata> = {
// catalog says. Base facts come from the active table, falling back to the
// shipped snapshot so a model upstream stops listing keeps a display name.
function openAiOAuthBase(active: ModelsDevMetadata, modelId: string): ModelMetadata {
return active.openai?.[modelId] ?? GENERATED_MODELS_DEV_METADATA.openai[modelId] ?? {};
const metadata = active.openai?.[modelId] ?? GENERATED_MODELS_DEV_METADATA.openai[modelId];
return withoutInputLimit(metadata) ?? {};
}

/** OAuth model metadata must not inherit public OpenAI API input limits. */
function withoutInputLimit(metadata: ModelMetadata | undefined): ModelMetadata | undefined {
if (!metadata) return undefined;
const { inputLimit: _inputLimit, ...withoutLimit } = metadata;
return withoutLimit;
}

function openAiOAuthModelMetadata(active: ModelsDevMetadata): Record<string, ModelMetadata> {
Expand Down
70 changes: 70 additions & 0 deletions packages/runtime/src/__tests__/context-budget-model-facts.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,3 +120,73 @@ test('a reported model context window is metadata, not a Maka declaration', () =
assert.equal(resolveSelectedModelContextWindow(connection, undefined), 100_000);
assert.equal(resolveDeclaredContextWindow(connection, undefined), undefined);
});

test('Codex OAuth pinned windows do not inherit public API input limits', () => {
for (const [modelId, window] of [
['gpt-5.5', 272_000],
['gpt-5.4', 272_000],
['gpt-5.6-sol', 372_000],
['gpt-5.4-mini', 272_000],
] as const) {
const connection = {
slug: 'codex',
providerType: 'openai-codex' as const,
defaultModel: modelId,
};
assert.equal(resolveSelectedModelContextWindow(connection, undefined), window, modelId);
assert.equal(resolveDeclaredContextWindow(connection, undefined), undefined);
}
});

test('Codex OAuth discovered windows remain usable after model discovery', () => {
for (const id of ['gpt-5.6-terra', 'gpt-5.6-luna', 'gpt-5.5']) {
const connection = {
slug: 'codex',
providerType: 'openai-codex' as const,
defaultModel: id,
models: [{ id, contextWindow: 272_000 }],
};
assert.equal(resolveSelectedModelContextWindow(connection, undefined), 272_000, id);
assert.equal(resolveDeclaredContextWindow(connection, undefined), undefined);
assert.equal(
resolveSelectedModelContextWindow(
{ ...connection, modelOverrides: { [id]: { inputLimit: 262_144 } } },
undefined,
),
262_144,
);
}
});

test('Codex OAuth keeps explicit input limits and rejects their conflicts', () => {
const connection = {
slug: 'codex',
providerType: 'openai-codex' as const,
defaultModel: 'gpt-5.5',
models: [{ id: 'gpt-5.5', contextWindow: 272_000, inputLimit: 200_000 }],
};
assert.equal(resolveSelectedModelContextWindow(connection, undefined), 200_000);
assert.equal(
resolveSelectedModelContextWindow(
{ ...connection, modelOverrides: { 'gpt-5.5': { inputLimit: 262_144 } } },
undefined,
),
262_144,
);
assert.throws(
() =>
resolveSelectedModelContextWindow(
{ ...connection, modelOverrides: { 'gpt-5.5': { inputLimit: 300_000 } } },
undefined,
),
/input limit exceeds/i,
);
assert.throws(
() =>
resolveSelectedModelContextWindow(
{ ...connection, models: [{ id: 'gpt-5.5', contextWindow: 272_000, inputLimit: 300_000 }] },
undefined,
),
/input limit exceeds/i,
);
});