Skip to content

Commit ea32196

Browse files
authored
add cron for models monitor (#9)
1 parent 8956860 commit ea32196

3 files changed

Lines changed: 75 additions & 0 deletions

File tree

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import { runMonitor, round6 } from '../../../../models-monitor/lib.ts'
2+
3+
export const config = { maxDuration: 60 }
4+
5+
export default async function handler(req: Request) {
6+
if (req.headers.get('authorization') !== `Bearer ${process.env.CRON_SECRET}`) {
7+
return new Response('Unauthorized', { status: 401 })
8+
}
9+
10+
try {
11+
await runMonitor({
12+
name: 'Chutes',
13+
title: '🛰 Chutes Models Update',
14+
s3Key: 'chutes/snapshot.json',
15+
async fetchModels() {
16+
const headers: Record<string, string> = {}
17+
if (process.env.CHUTES_API_KEY) headers['Authorization'] = `Bearer ${process.env.CHUTES_API_KEY}`
18+
19+
const res = await fetch('https://llm.chutes.ai/v1/models', { headers })
20+
if (!res.ok) throw new Error(`Chutes API error: ${res.status}`)
21+
const data = await res.json() as { data: Array<{ id: string; pricing: { prompt: number; completion: number } }> }
22+
return data.data.map(m => ({
23+
id: m.id,
24+
price_prompt: round6(m.pricing.prompt),
25+
price_completion: round6(m.pricing.completion),
26+
}))
27+
},
28+
})
29+
return new Response('ok')
30+
} catch (err) {
31+
console.error(err)
32+
return new Response(String(err), { status: 500 })
33+
}
34+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import { runMonitor, round6 } from '../../../../models-monitor/lib.ts'
2+
3+
export const config = { maxDuration: 60 }
4+
5+
export default async function handler(req: Request) {
6+
if (req.headers.get('authorization') !== `Bearer ${process.env.CRON_SECRET}`) {
7+
return new Response('Unauthorized', { status: 401 })
8+
}
9+
10+
try {
11+
await runMonitor({
12+
name: 'OpenRouter',
13+
title: '🛰 OpenRouter Models Update',
14+
s3Key: 'openrouter/snapshot.json',
15+
async fetchModels() {
16+
const res = await fetch('https://openrouter.ai/api/v1/models')
17+
if (!res.ok) throw new Error(`OpenRouter API error: ${res.status}`)
18+
const data = await res.json() as { data: Array<{ id: string; pricing: { prompt: string; completion: string } }> }
19+
return data.data.map(m => ({
20+
id: m.id,
21+
price_prompt: round6(parseFloat(m.pricing.prompt) * 1_000_000),
22+
price_completion: round6(parseFloat(m.pricing.completion) * 1_000_000),
23+
}))
24+
},
25+
})
26+
return new Response('ok')
27+
} catch (err) {
28+
console.error(err)
29+
return new Response(String(err), { status: 500 })
30+
}
31+
}

vercel.json

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,16 @@
66
"installCommand": "bun install",
77
"framework": null,
88
"cleanUrls": false,
9+
"crons": [
10+
{
11+
"path": "/api/cron/monitor-openrouter",
12+
"schedule": "50 * * * *"
13+
},
14+
{
15+
"path": "/api/cron/monitor-chutes",
16+
"schedule": "50 * * * *"
17+
}
18+
],
919
"rewrites": [
1020
{
1121
"source": "/api.json",

0 commit comments

Comments
 (0)