diff --git a/src/backend/drivers/ai-chat/providers/openrouter/OpenRouterProvider.test.ts b/src/backend/drivers/ai-chat/providers/openrouter/OpenRouterProvider.test.ts index 944fa18ff..503d94a88 100644 --- a/src/backend/drivers/ai-chat/providers/openrouter/OpenRouterProvider.test.ts +++ b/src/backend/drivers/ai-chat/providers/openrouter/OpenRouterProvider.test.ts @@ -92,6 +92,7 @@ const SAMPLE_API_MODELS = [ { id: 'openai/gpt-5-nano', name: 'GPT-5 Nano', + created: 1714564800, context_length: 128000, pricing: { prompt: 0.00001, completion: 0.00003 }, top_provider: { max_completion_tokens: 16000 }, @@ -99,6 +100,7 @@ const SAMPLE_API_MODELS = [ { id: 'anthropic/claude-haiku-4.5', name: 'Claude Haiku 4.5', + created: 1760529600, context_length: 200000, pricing: { prompt: 0.000002, completion: 0.00001 }, top_provider: { max_completion_tokens: 8192 }, @@ -107,6 +109,7 @@ const SAMPLE_API_MODELS = [ // 'openrouter/auto' is filtered out — disallowed. id: 'openrouter/auto', name: 'Auto', + created: 1704067200, context_length: 32768, pricing: { prompt: 0, completion: 0 }, top_provider: { max_completion_tokens: 4096 }, @@ -224,6 +227,23 @@ describe('OpenRouterProvider model catalog', () => { // Second call should be a cache hit, not a second axios request. expect(axiosRequestMock).toHaveBeenCalledTimes(1); }); + + it('maps OpenRouter created timestamps to release_date metadata', async () => { + const { provider } = makeProvider(); + const models = await provider.models(); + expect(models).toEqual( + expect.arrayContaining([ + expect.objectContaining({ + id: 'openrouter:openai/gpt-5-nano', + release_date: '2024-05-01', + }), + expect.objectContaining({ + id: 'openrouter:anthropic/claude-haiku-4.5', + release_date: '2025-10-15', + }), + ]), + ); + }); }); // ── Disallowed model gate ─────────────────────────────────────────── diff --git a/src/backend/drivers/ai-chat/providers/openrouter/OpenRouterProvider.ts b/src/backend/drivers/ai-chat/providers/openrouter/OpenRouterProvider.ts index 4cd31d656..bf633c425 100644 --- a/src/backend/drivers/ai-chat/providers/openrouter/OpenRouterProvider.ts +++ b/src/backend/drivers/ai-chat/providers/openrouter/OpenRouterProvider.ts @@ -36,6 +36,18 @@ type OpenrouterUsage = OpenAI.Completions.CompletionUsage & { cost?: number; }; +const openRouterReleaseDate = (created: unknown): string | undefined => { + const seconds = Number(created); + if (!Number.isFinite(seconds) || seconds <= 0) { + return undefined; + } + const date = new Date(seconds * 1000); + const year = date.getUTCFullYear(); + const month = String(date.getUTCMonth() + 1).padStart(2, '0'); + const day = String(date.getUTCDate()).padStart(2, '0'); + return `${year}-${month}-${day}`; +}; + export class OpenRouterProvider implements IChatProvider { #meteringService: MeteringService; @@ -275,6 +287,7 @@ export class OpenRouterProvider implements IChatProvider { tokens: 1_000_000, ...microcentCosts, }, + release_date: openRouterReleaseDate(model.created), ...overridenModel, }); }