chore: v1.0.17 — detect llama-server from api.state.config.provider

This commit is contained in:
Troed Sångberg
2026-07-08 13:10:52 +02:00
parent 04baa5b053
commit dfd3591f16
3 changed files with 23 additions and 85 deletions
+1 -1
View File
@@ -30,7 +30,7 @@ The plugin renders a single line in the session prompt right slot:
### Server Discovery
The plugin discovers the llama-server URL by reading the OpenCode configuration file (parsed as JSONC) and extracting `baseURL`/`base_url` fields from provider options that contain "localhost". Falls back to `http://localhost:8080`.
The plugin discovers the llama-server URL by reading the OpenCode configuration via the TUI API and extracting `baseURL`/`base_url` fields from provider options whose name contains "llama" (but excludes providers whose name contains "ollama"). Falls back to `http://localhost:8080` if no matching provider is found.
### Slot Polling
+1 -1
View File
@@ -1,7 +1,7 @@
{
"$schema": "https://json.schemastore.org/package.json",
"name": "@troed/oc-ls-stats",
"version": "1.0.5",
"version": "1.0.17",
"type": "module",
"exports": {
"./tui": {
+21 -83
View File
@@ -49,70 +49,6 @@ function estimateStreamTokens(delta: string) {
return Math.max(1, Math.ceil(Buffer.byteLength(delta, "utf8") / 5))
}
function parseJSONC(text: string): unknown {
let result = ""
let inString = false
let escape = false
let i = 0
while (i < text.length) {
const ch = text[i]
if (escape) {
result += ch
escape = false
i++
continue
}
if (ch === "\\") {
result += ch
escape = true
i++
continue
}
if (ch === '"') {
result += ch
inString = !inString
i++
continue
}
if (inString) {
result += ch
i++
continue
}
if (ch === "/" && text[i + 1] === "/") {
while (i < text.length && text[i] !== "\n") i++
continue
}
if (ch === "/" && text[i + 1] === "*") {
i += 2
while (i < text.length - 1 && !(text[i] === "*" && text[i + 1] === "/")) i++
i += 2
result += " "
continue
}
if (ch === ",") {
const next = text.indexOf(/[\s}\]]/, i + 1)
if (next !== -1 && /[\s}\]]/.test(text[next])) {
i++
continue
}
}
result += ch
i++
}
return JSON.parse(result)
}
function stripBaseUrlPath(baseURL: string): string {
try {
const url = new URL(baseURL)
@@ -129,12 +65,12 @@ function extractProviderUrls(config: unknown): string[] {
if (!provider || typeof provider !== "object") return []
const urls: string[] = []
for (const [_key, val] of Object.entries(provider as Record<string, unknown>)) {
for (const [key, val] of Object.entries(provider as Record<string, unknown>)) {
if (val && typeof val === "object") {
const opts = (val as Record<string, unknown>).options
if (opts && typeof opts === "object") {
const baseURL = (opts as Record<string, unknown>).baseURL || (opts as Record<string, unknown>).base_url
if (typeof baseURL === "string" && baseURL.includes("localhost")) {
if (typeof baseURL === "string" && key.toLowerCase().includes("llama") && !key.toLowerCase().includes("ollama")) {
urls.push(stripBaseUrlPath(baseURL))
}
}
@@ -145,13 +81,8 @@ function extractProviderUrls(config: unknown): string[] {
async function loadConfigUrls(api: Parameters<TuiPlugin>[0]): Promise<string[]> {
try {
const configPath = api.state.path.config
const resp = await fetch(`file://${configPath}`)
if (!resp.ok) return []
const text = await resp.text()
const config = parseJSONC(text)
return extractProviderUrls(config)
} catch {
return extractProviderUrls(api.state.config as unknown)
} catch (e) {
return []
}
}
@@ -280,7 +211,7 @@ const tui: TuiPlugin = async (api) => {
bump()
}
let llamaServerUrls: string[] = ["http://localhost:8080"]
let llamaServerUrls: string[] = []
let llamaServerModel: string | undefined
const pollMetrics = async () => {
@@ -313,8 +244,9 @@ const tui: TuiPlugin = async (api) => {
continue
}
tracker.failure = null
bump()
debug(`poll baseUrl=${baseUrl} slots=${JSON.stringify(slotList)}`)
for (const slot of slotList) {
if (slot?.is_processing) {
@@ -324,7 +256,13 @@ const tui: TuiPlugin = async (api) => {
for (const slotId of prevProcessingSlotIds) {
if (!currProcessingSlotIds.has(slotId)) {
delete tracker.prevNdBySlot[slotId]
const prev = tracker.prevNdBySlot[slotId]
if (prev) {
prev.hasIncreased = false
prev.baseline = 0
} else {
delete tracker.prevNdBySlot[slotId]
}
}
}
@@ -375,7 +313,7 @@ const tui: TuiPlugin = async (api) => {
tracker.prefillCapturedTokens = nt
tracker.prefillStartAt = now
tracker.lastPrefillRate = 0
debug(`prefill new slot id=${slotId} nt=${nt}`)
}
} else {
if (tracker.isPrefilling) {
@@ -396,7 +334,7 @@ const tui: TuiPlugin = async (api) => {
const delta = nd - tracker.generatePrevNd
if (dt > 0 && delta > 0) {
tracker.lastGeneratedTps = delta / dt
debug(`gen slot=${slotId} nd=${nd} prev=${tracker.generatePrevNd} delta=${delta} dt=${dt.toFixed(2)} tps=${tracker.lastGeneratedTps.toFixed(1)}`)
}
tracker.generatePrevNd = nd
tracker.generateStartAt = now
@@ -405,7 +343,7 @@ const tui: TuiPlugin = async (api) => {
tracker.generatePrevNd = nd
tracker.generateStartAt = now
tracker.lastGeneratedTps = 0
debug(`gen new slot id=${slotId} nd=${nd}`)
}
} else {
if (tracker.isGenerating) {
@@ -414,7 +352,7 @@ const tui: TuiPlugin = async (api) => {
tracker.generateStartAt = 0
tracker.lastGeneratedTps = 0
genEnded = true
debug(`gen no slot found ending`)
}
}
@@ -501,11 +439,11 @@ const tui: TuiPlugin = async (api) => {
})
try {
if (!llamaServerUrls.length) {
llamaServerUrls = await loadConfigUrls(api)
}
const configUrls = await loadConfigUrls(api)
llamaServerUrls = configUrls.length > 0 ? configUrls : ["http://localhost:8080"]
} catch (e) {
console.error("[oc-ls-stats] loadConfigUrls error:", e)
llamaServerUrls = ["http://localhost:8080"]
}
api.slots.register({