Add OpenRouter model release dates (#3144)
Maintain Release Merge PR / update-release-pr (push) Has been cancelled
Notify HeyPuter / notify (push) Has been cancelled
release-please / release-please (push) Has been cancelled

* Add OpenRouter model release dates

* simplify implementation

---------

Co-authored-by: Reynaldi Chernando <reynaldichernando@gmail.com>
This commit is contained in:
Nightt
2026-05-23 00:58:59 +08:00
committed by GitHub
parent 948f771838
commit 7438db7a90
2 changed files with 33 additions and 0 deletions
@@ -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 ───────────────────────────────────────────
@@ -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,
});
}