🌳
pt0/deployF/openrouterF/opnRtrDeployAI.mts
1import fs from 'fs'
2import { getPlainNoMappedSec, type secretNameType } from '../../serverF/secretsF/getPlainSecAI.mts'
11const opnRtrProvisionerKey = () => getPlainNoMappedSec('openrouter-provisioner-apikey' as secretNameType)
13export const opnRtrProvisionerFetch = async (urlPath: string, {method = 'GET', bodyH, apiKey}: {method?: string, bodyH?: Record<string, unknown>, apiKey?: string} = {}) => {
14 const token = apiKey || opnRtrProvisionerKey()
15 const resp = await fetch('https://openrouter.ai' + urlPath, {
16 method,
17 headers: {'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json'},
18 body: bodyH ? JSON.stringify(bodyH) : undefined,
19 })
20 return resp
23const listOpnRtrKeys = async () => {
24 const resp = await opnRtrProvisionerFetch('/api/v1/keys')
25 assertTruthy(resp.ok, {status: resp.status})
26 const {data} = await resp.json()
27 return data
30export const opnRtrSecretName = (name: string) => `openrouter-${name}`
32export const ensureOpnRtrKey = async ({name, limit, limitReset}: {name: string, limit?: number, limitReset?: string}) => {
33 assertDefined(name, {name})
34 const secName = opnRtrSecretName(name)
35 const secPath = pathDownJoin(secretsDir, secName)
36 if (fs.existsSync(secPath)) return secName
38 betLog({provisioningOpnRtrKey: name, limit, limitReset})
39 const existingKeys = await listOpnRtrKeys()
40 const existingKeyOnServer = existingKeys.find((k: {name: string}) => k.name === name)
41 throwIf(() => existingKeyOnServer, {name, secName, existingKeyOnServer})
43 const resp = await opnRtrProvisionerFetch('/api/v1/keys', {
44 method: 'POST',
45 bodyH: {name, limit, limit_reset: limitReset},
46 })
47 const respStatus = resp.status, respBody = !resp.ok ? await resp.text().catch(() => '') : undefined
48 assertTruthy(resp.ok, {respStatus, respBody})
49 const {key} = await resp.json()
50 assertDefined(key, {name})
51 fs.writeFileSync(secPath, key)
52 betLog({provisionedOpnRtrKey: name, secretFile: secName})
53 return secName
56export const opnRtrKeyUsageFromSecret = async ({secretName}: {secretName: string}) => {
57 const secPath = pathDownJoin(secretsDir, secretName)
58 const apiKey = fs.readFileSync(secPath, 'utf-8').trim()
59 const resp = await opnRtrProvisionerFetch('/api/v1/key', {apiKey})
60 const usageRespStatus = resp.status
61 assertTruthy(resp.ok, {usageRespStatus})
62 const {data} = await resp.json()
63 return data
66export const openrouterusage = async () => {
67 const {name} = getReqAppCfg()
68 assertDefined(name, {name})
69 const secretName = opnRtrSecretName(name)
70 const usage = await opnRtrKeyUsageFromSecret({secretName})
71 console.log(`OpenRouter key: ${usage.name || name}`)
72 console.log(` limit: $${usage.limit ?? 'none'} (resets: ${usage.limit_reset || 'never'})`)
73 console.log(` remaining: $${usage.limit_remaining ?? 'n/a'}`)
74 console.log(` daily: $${usage.usage_daily}`)
75 console.log(` weekly: $${usage.usage_weekly}`)
76 console.log(` monthly: $${usage.usage_monthly}`)
77 console.log(` total: $${usage.usage}`)
79openrouterusage.cliDescript = 'show OpenRouter API key usage and budget'