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
2 changes: 1 addition & 1 deletion src/codex/catalog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// Public surface preserved exactly; importers keep using "src/codex/catalog".
export { isMediaGenerationModelId, shouldExposeRoutedModel, readCodexCatalogPath, readCatalog, normalizeRoutedCatalogEntry, catalogModelSlug, filterSupportedNativeSlugs, catalogModelSupportsReasoningSummaries } from "./catalog/parsing";
export type { CatalogModel, MultiAgentMode } from "./catalog/parsing";
export { accountBoundNativeOpenAiSlugs, accountBoundNativeOpenAiSlugsBySelector, CODEX_NATIVE_ALIAS_CATALOG_KIND, NATIVE_DAYBREAK_BLUE_MODEL, NATIVE_GPT56_CONTEXT_WINDOW, NATIVE_GPT56_MAX_INPUT_TOKENS, NATIVE_GPT56_OPT_IN_CONTEXT_WINDOW, NATIVE_OPENAI_CAPABILITY_ALIAS_MODELS, NATIVE_OPENAI_MODELS, configuredNativeAliasSlugs, desktopAllowlistSuppressedNativeSlugs, isNativeAliasCatalogEntry, isNativeOpenAiCapabilityAliasModel, nativeContextLimits, nativeOpenAiCapabilitySourceSlug, nativeOpenAiContextWindow, nativeOpenAiMaxInputTokens, nativeOpenAiContextTier, disabledNativeSlugs, visibleNativeSlugs, desktopVisibleNativeSlugs, nativeModelRows, applyNativeVisibility, observedAccountBoundNativeEntries, observedAccountBoundNativeOpenAiSlugs, upstreamNativeEntry, nativeOpenAiSlugs, listCatalogNativeSlugs, nativeInputModalities, nativeReasoningEfforts, nativeDefaultReasoningEffort, shouldIncludeAccountBoundNativeOpenAi, shouldIncludeNativeOpenAi, type NativeContextLimits, type NativeContextLimitsInput } from "./catalog/metadata";
export { accountBoundNativeOpenAiSlugs, accountBoundNativeOpenAiSlugsBySelector, CODEX_NATIVE_ALIAS_CATALOG_KIND, NATIVE_DAYBREAK_BLUE_MODEL, NATIVE_GPT56_CONTEXT_WINDOW, NATIVE_GPT56_MAX_INPUT_TOKENS, NATIVE_GPT56_OPT_IN_CONTEXT_WINDOW, NATIVE_OPENAI_CAPABILITY_ALIAS_MODELS, NATIVE_OPENAI_MODELS, configuredNativeAliasSlugs, desktopAllowlistSuppressedNativeSlugs, isNativeAliasCatalogEntry, isNativeOpenAiCapabilityAliasModel, nativeContextLimits, nativeOpenAiCapabilitySourceSlug, nativeOpenAiContextWindow, nativeOpenAiMaxInputTokens, nativeOpenAiMaxOutputTokens, nativeOpenAiContextTier, disabledNativeSlugs, visibleNativeSlugs, desktopVisibleNativeSlugs, nativeModelRows, applyNativeVisibility, observedAccountBoundNativeEntries, observedAccountBoundNativeOpenAiSlugs, upstreamNativeEntry, nativeOpenAiSlugs, listCatalogNativeSlugs, nativeInputModalities, nativeReasoningEfforts, nativeDefaultReasoningEffort, shouldIncludeAccountBoundNativeOpenAi, shouldIncludeNativeOpenAi, type NativeContextLimits, type NativeContextLimitsInput } from "./catalog/metadata";
export { isSpawnableCodexCandidate, codexExecInvocation, loadBundledCodexCatalog, materializeBundledCodexCatalog, loadCatalogTemplate } from "./catalog/bundled";
export { nativeEffortClamp, shouldApplyNativeEffortClamp, catalogModelEfforts, codexSupportedReasoningEfforts, clampedDefaultEffort, clampEntryToCodexSupportedEfforts, clampCatalogModelsToCodexSupport } from "./catalog/effort";
export { applyProviderConfigHints, isDatedVariantId, filterCatalogVisibleModels, gatherRoutedModels, clearGatherRoutedModelsInflight, augmentRoutedModelsWithRegistryOpenAiApiRows, augmentRoutedModelsWithMetadata, resolveComboCatalogMember, configuredComboTargetModelsByProvider } from "./catalog/provider-fetch";
Expand Down
8 changes: 8 additions & 0 deletions src/codex/catalog/aggregation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,12 @@ export function deriveComboCatalogModel(
contextWindow,
...members.map(member => member.maxInputTokens ?? member.contextWindow!),
);
const knownMaxOutputTokens = members
.map(member => member.maxOutputTokens)
.filter((value): value is number => typeof value === "number" && value > 0);
const maxOutputTokens = knownMaxOutputTokens.length === members.length
? Math.min(...knownMaxOutputTokens)
: undefined;
const autoCompactTokenLimit = Math.min(
...members.map(member => clampAutoCompactTokenLimit(
member.contextWindow!,
Expand All @@ -180,6 +186,7 @@ export function deriveComboCatalogModel(
owned_by: COMBO_NAMESPACE,
contextWindow,
maxInputTokens,
...(maxOutputTokens !== undefined ? { maxOutputTokens } : {}),
autoCompactTokenLimit,
...(hasLimitingContextCapMetadata ? { contextCapped } : {}),
inputModalities,
Expand Down Expand Up @@ -320,6 +327,7 @@ export function normalizedOpenAiApiSignature(model: CatalogModel): string {
id: model.id,
contextWindow: model.contextWindow ?? null,
maxInputTokens: model.maxInputTokens ?? null,
maxOutputTokens: model.maxOutputTokens ?? null,
autoCompactTokenLimit: model.autoCompactTokenLimit ?? null,
inputModalities: [...new Set(model.inputModalities ?? [])].sort(),
reasoningEfforts: [...new Set(model.reasoningEfforts ?? [])].sort(),
Expand Down
5 changes: 5 additions & 0 deletions src/codex/catalog/metadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,11 @@ export function nativeOpenAiContextWindow(slug: string, limits?: NativeContextLi
return narrowToLimits(raw, slug, limits);
}

export function nativeOpenAiMaxOutputTokens(slug: string): number | undefined {
const sourceSlug = nativeOpenAiCapabilitySourceSlug(slug);
return positiveInt(getModelMetadata("openai", sourceSlug)?.maxTokens);
}

/**
* Long-context tier for a native slug as a (default, long) pair, for clients that let the user
* pick a window per request (Cursor's local-agent "Context" selector). The pair is the family's
Expand Down
2 changes: 2 additions & 0 deletions src/codex/catalog/parsing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,8 @@ export interface CatalogModel {
defaultReasoningEffort?: string;
contextWindow?: number;
maxInputTokens?: number;
/** Model-scoped output-token ceiling; omitted when no authoritative value is known. */
maxOutputTokens?: number;
/** Soft client compaction threshold; hard context/input limits remain authoritative. */
autoCompactTokenLimit?: number;
contextCap?: number;
Expand Down
Loading
Loading