oc-plugin-litellm-budget 0.3.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/tui.tsx +38 -10
package/package.json
CHANGED
package/tui.tsx
CHANGED
|
@@ -11,10 +11,36 @@ type QuotaData = {
|
|
|
11
11
|
tpm: number
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
14
|
+
const readKeyFromConfig = async (): Promise<string> => {
|
|
15
|
+
try {
|
|
16
|
+
const home = process.env.HOME || process.env.USERPROFILE || ""
|
|
17
|
+
if (!home) return ""
|
|
18
|
+
const base = process.env.XDG_CONFIG_HOME || `${home}/.config`
|
|
19
|
+
for (const name of ["opencode.json", "opencode.jsonc"]) {
|
|
20
|
+
try {
|
|
21
|
+
const raw = await Bun.file(`${base}/opencode/${name}`).text()
|
|
22
|
+
if (!raw) continue
|
|
23
|
+
const d = JSON.parse(raw)
|
|
24
|
+
const k = d?.provider?.binetz?.options?.apiKey
|
|
25
|
+
if (k && typeof k === "string" && !k.startsWith("{env:")) return k
|
|
26
|
+
} catch {
|
|
27
|
+
try {
|
|
28
|
+
const raw = await Bun.file(`${base}/opencode/${name}`).text()
|
|
29
|
+
const clean = raw.replace(/^\s*\/\/.*$/gm, "").replace(/,(\s*[}\]])/g, "$1")
|
|
30
|
+
const d = JSON.parse(clean)
|
|
31
|
+
const k = d?.provider?.binetz?.options?.apiKey
|
|
32
|
+
if (k && typeof k === "string" && !k.startsWith("{env:")) return k
|
|
33
|
+
} catch {}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
} catch {}
|
|
37
|
+
return ""
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const getConfig = async () => {
|
|
41
|
+
const envKey = process.env.LITELLM_API_KEY || process.env.OPENAI_API_KEY || process.env.BINETZ_REMOTE_CONFIG_TOKEN || ""
|
|
42
|
+
const key = envKey || await readKeyFromConfig()
|
|
43
|
+
const url = process.env.LITELLM_BASE_URL || process.env.OPENAI_BASE_URL || (key ? "https://litellm.binetz.com" : "")
|
|
18
44
|
return { url: url.replace(/\/+$/, ""), key }
|
|
19
45
|
}
|
|
20
46
|
|
|
@@ -56,12 +82,14 @@ const fmtTpm = (n: number): string =>
|
|
|
56
82
|
n >= 1_000_000 ? `${(n / 1_000_000).toFixed(0)}M` : n >= 1_000 ? `${(n / 1_000).toFixed(0)}K` : `${n}`
|
|
57
83
|
|
|
58
84
|
const useQuota = () => {
|
|
59
|
-
const { url, key } = getConfig()
|
|
60
85
|
const [data, setData] = createSignal<QuotaData | null>(null)
|
|
61
|
-
const [err, setErr] = createSignal(
|
|
86
|
+
const [err, setErr] = createSignal(false)
|
|
87
|
+
const [configured, setConfigured] = createSignal(true)
|
|
62
88
|
|
|
63
89
|
const poll = async () => {
|
|
64
|
-
|
|
90
|
+
const { url, key } = await getConfig()
|
|
91
|
+
if (!url || !key) { setConfigured(false); setErr(true); return }
|
|
92
|
+
setConfigured(true)
|
|
65
93
|
const q = await fetchQuota(url, key)
|
|
66
94
|
if (q) { setData(q); setErr(false) }
|
|
67
95
|
else setErr(true)
|
|
@@ -71,7 +99,7 @@ const useQuota = () => {
|
|
|
71
99
|
const timer = setInterval(poll, POLL_MS)
|
|
72
100
|
onCleanup(() => clearInterval(timer))
|
|
73
101
|
|
|
74
|
-
return { data, err, configured
|
|
102
|
+
return { data, err, configured }
|
|
75
103
|
}
|
|
76
104
|
|
|
77
105
|
const colorForPct = (pct: number, theme: any) =>
|
|
@@ -83,7 +111,7 @@ const Sidebar = (props: { theme: any }) => {
|
|
|
83
111
|
return (
|
|
84
112
|
<box paddingTop={1} width="100%" flexDirection="column">
|
|
85
113
|
<text bold fg={props.theme.current.primary}>Quota</text>
|
|
86
|
-
<Show when={configured} fallback={
|
|
114
|
+
<Show when={configured()} fallback={
|
|
87
115
|
<text fg={props.theme.current.textMuted}>Not configured</text>
|
|
88
116
|
}>
|
|
89
117
|
<Show when={!err()} fallback={
|
|
@@ -118,7 +146,7 @@ const FooterQuota = (props: { theme: any }) => {
|
|
|
118
146
|
|
|
119
147
|
return (
|
|
120
148
|
<box>
|
|
121
|
-
<Show when={configured} fallback={
|
|
149
|
+
<Show when={configured()} fallback={
|
|
122
150
|
<text fg={props.theme.current.textMuted}>Quota: not configured</text>
|
|
123
151
|
}>
|
|
124
152
|
<Show when={!err() && data()} fallback={
|