diff --git a/api/cron/monitor-chutes.ts b/api/cron/monitor-chutes.ts index e000da6b4..26e3b375c 100644 --- a/api/cron/monitor-chutes.ts +++ b/api/cron/monitor-chutes.ts @@ -1,10 +1,13 @@ -import { runMonitor, round6 } from '@models.dev/monitor' +import { runMonitor, round6 } from '../../packages/monitor/index.ts' -export const config = { maxDuration: 60 } +export const config = { + maxDuration: 60, +} -export default async function handler(req: Request) { - if (req.headers.get('authorization') !== `Bearer ${process.env.CRON_SECRET}`) { - return new Response('Unauthorized', { status: 401 }) +export default async function handler(req: any, res: any) { + const authHeader = req.headers['authorization'] + if (authHeader !== `Bearer ${process.env.CRON_SECRET}`) { + return res.status(401).send('Unauthorized') } try { @@ -16,9 +19,10 @@ export default async function handler(req: Request) { const headers: Record = {} if (process.env.CHUTES_API_KEY) headers['Authorization'] = `Bearer ${process.env.CHUTES_API_KEY}` - const res = await fetch('https://llm.chutes.ai/v1/models', { headers }) - if (!res.ok) throw new Error(`Chutes API error: ${res.status}`) - const data = await res.json() as { data: Array<{ id: string; pricing: { prompt: number; completion: number } }> } + const fetchRes = await fetch('https://llm.chutes.ai/v1/models', { headers }) + if (!fetchRes.ok) throw new Error(`Chutes API error: ${fetchRes.status}`) + const data = await fetchRes.json() as { data: Array<{ id: string; pricing: { prompt: number; completion: number } }> } + return data.data.map(m => ({ id: m.id, price_prompt: round6(m.pricing.prompt), @@ -26,9 +30,9 @@ export default async function handler(req: Request) { })) }, }) - return new Response('ok') + return res.send('ok') } catch (err) { console.error(err) - return new Response(String(err), { status: 500 }) + return res.status(500).send('error') } -} +} \ No newline at end of file diff --git a/api/cron/monitor-openrouter.ts b/api/cron/monitor-openrouter.ts index 9cb370994..f31de46b8 100644 --- a/api/cron/monitor-openrouter.ts +++ b/api/cron/monitor-openrouter.ts @@ -1,10 +1,13 @@ -import { runMonitor, round6 } from '@models.dev/monitor' +import { runMonitor, round6 } from '../../packages/monitor/index.ts' -export const config = { maxDuration: 60 } +export const config = { + maxDuration: 60, +} -export default async function handler(req: Request) { - if (req.headers.get('authorization') !== `Bearer ${process.env.CRON_SECRET}`) { - return new Response('Unauthorized', { status: 401 }) +export default async function handler(req: any, res: any) { + const authHeader = req.headers['authorization'] + if (authHeader !== `Bearer ${process.env.CRON_SECRET}`) { + return res.status(401).send('Unauthorized') } try { @@ -13,9 +16,9 @@ export default async function handler(req: Request) { title: '🛰 OpenRouter Models Update', s3Key: 'openrouter/snapshot.json', async fetchModels() { - const res = await fetch('https://openrouter.ai/api/v1/models') - if (!res.ok) throw new Error(`OpenRouter API error: ${res.status}`) - const data = await res.json() as { data: Array<{ id: string; pricing: { prompt: string; completion: string } }> } + const fetchRes = await fetch('https://openrouter.ai/api/v1/models') + if (!fetchRes.ok) throw new Error(`OpenRouter API error: ${fetchRes.status}`) + const data = await fetchRes.json() as { data: Array<{ id: string; pricing: { prompt: string; completion: string } }> } return data.data.map(m => ({ id: m.id, price_prompt: round6(parseFloat(m.pricing.prompt) * 1_000_000), @@ -23,9 +26,9 @@ export default async function handler(req: Request) { })) }, }) - return new Response('ok') + return res.send('ok') } catch (err) { console.error(err) - return new Response(String(err), { status: 500 }) + return res.status(500).send('error') } -} +} \ No newline at end of file diff --git a/bun.lock b/bun.lock index e4d39e2cf..5a1e4763e 100644 --- a/bun.lock +++ b/bun.lock @@ -6,6 +6,7 @@ "name": "models.dev", "dependencies": { "@aws-sdk/client-s3": "^3.1000.0", + "@models.dev/monitor": "workspace:*", }, }, "packages/core": { diff --git a/package.json b/package.json index 7bab27fda..dfd3e0979 100644 --- a/package.json +++ b/package.json @@ -29,6 +29,7 @@ } }, "dependencies": { - "@aws-sdk/client-s3": "^3.1000.0" + "@aws-sdk/client-s3": "^3.1000.0", + "@models.dev/monitor": "workspace:*" } } \ No newline at end of file diff --git a/packages/web/api/cron/monitor-chutes.ts b/packages/web/api/cron/monitor-chutes.ts deleted file mode 100644 index 6cd249c24..000000000 --- a/packages/web/api/cron/monitor-chutes.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { runMonitor, round6 } from '@models.dev/monitor' - -export const config = { - maxDuration: 60, -} - -export default async function handler(req: Request) { - const authHeader = req.headers.get('authorization') - if (authHeader !== `Bearer ${process.env.CRON_SECRET}`) { - return new Response('Unauthorized', { status: 401 }) - } - - try { - await runMonitor({ - name: 'Chutes', - title: '🛰 Chutes Models Update', - s3Key: 'chutes/snapshot.json', - async fetchModels() { - const headers: Record = {} - if (process.env.CHUTES_API_KEY) headers['Authorization'] = `Bearer ${process.env.CHUTES_API_KEY}` - - const res = await fetch('https://llm.chutes.ai/v1/models', { headers }) - if (!res.ok) throw new Error(`Chutes API error: ${res.status}`) - const data = await res.json() as { data: Array<{ id: string; pricing: { prompt: number; completion: number } }> } - - return data.data.map(m => ({ - id: m.id, - price_prompt: round6(m.pricing.prompt), - price_completion: round6(m.pricing.completion), - })) - }, - }) - return new Response('ok') - } catch (err) { - console.error(err) - return new Response('error', { status: 500 }) - } -} \ No newline at end of file diff --git a/packages/web/api/cron/monitor-openrouter.ts b/packages/web/api/cron/monitor-openrouter.ts deleted file mode 100644 index 03dbc780a..000000000 --- a/packages/web/api/cron/monitor-openrouter.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { runMonitor, round6 } from '@models.dev/monitor' - -export const config = { - maxDuration: 60, -} - -export default async function handler(req: Request) { - const authHeader = req.headers.get('authorization') - if (authHeader !== `Bearer ${process.env.CRON_SECRET}`) { - return new Response('Unauthorized', { status: 401 }) - } - - try { - await runMonitor({ - name: 'OpenRouter', - title: '🛰 OpenRouter Models Update', - s3Key: 'openrouter/snapshot.json', - async fetchModels() { - const res = await fetch('https://openrouter.ai/api/v1/models') - if (!res.ok) throw new Error(`OpenRouter API error: ${res.status}`) - const data = await res.json() as { data: Array<{ id: string; pricing: { prompt: string; completion: string } }> } - return data.data.map(m => ({ - id: m.id, - price_prompt: round6(parseFloat(m.pricing.prompt) * 1_000_000), - price_completion: round6(parseFloat(m.pricing.completion) * 1_000_000), - })) - }, - }) - return new Response('ok') - } catch (err) { - console.error(err) - return new Response('error', { status: 500 }) - } -} \ No newline at end of file diff --git a/vercel.json b/vercel.json index 5727cf4fa..3f7b803e8 100644 --- a/vercel.json +++ b/vercel.json @@ -6,6 +6,11 @@ "installCommand": "bun install", "framework": null, "cleanUrls": false, + "functions": { + "api/cron/*.ts": { + "includeFiles": "packages/monitor/**" + } + }, "crons": [ { "path": "/api/cron/monitor-openrouter", @@ -32,10 +37,6 @@ { "source": "/logos/:path*", "destination": "/logos/default.svg" - }, - { - "source": "/(.*)", - "destination": "/_index.html" } ] } \ No newline at end of file