Initial ForgeLM import
This commit is contained in:
commit
a392b9dc60
4296 files changed
+1212675
No files matched your search
@@ -0,0 +1,21 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { getNextSelectedModel } from "./model-selection";
|
||||
|
||||
const models = [
|
||||
{ id: "alpha", object: "model", created: 1, owned_by: "me" },
|
||||
{ id: "beta", object: "model", created: 2, owned_by: "me" },
|
||||
];
|
||||
|
||||
describe("getNextSelectedModel", () => {
|
||||
it("keeps the current selection when it still exists", () => {
|
||||
expect(getNextSelectedModel("beta", models)).toBe("beta");
|
||||
});
|
||||
|
||||
it("falls back to the first model when the selection is missing", () => {
|
||||
expect(getNextSelectedModel("missing", models)).toBe("alpha");
|
||||
});
|
||||
|
||||
it("clears the selection when the model list becomes empty", () => {
|
||||
expect(getNextSelectedModel("alpha", [])).toBe("");
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,13 @@
|
||||
import type { ModelInfo } from "../lib/types";
|
||||
|
||||
export function getNextSelectedModel(current: string, models: ModelInfo[]): string {
|
||||
if (models.length === 0) {
|
||||
return "";
|
||||
}
|
||||
|
||||
if (current && models.some((model) => model.id === current)) {
|
||||
return current;
|
||||
}
|
||||
|
||||
return models[0]?.id || "";
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
import { useState, useEffect } from "react";
|
||||
import { DB, initDB } from "../lib/db";
|
||||
|
||||
export function useDB() {
|
||||
const [db, setDb] = useState<DB | null>(null);
|
||||
const [ready, setReady] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
initDB().then((instance) => {
|
||||
setDb(instance);
|
||||
setReady(true);
|
||||
});
|
||||
}, []);
|
||||
|
||||
return { db, ready };
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
import { useState, useEffect, useCallback } from "react";
|
||||
import type { ModelInfo, ServerStatus } from "../lib/types";
|
||||
import { getNextSelectedModel } from "./model-selection";
|
||||
|
||||
export function useModels(server: string, apiKey: string, enabled = true) {
|
||||
const [models, setModels] = useState<ModelInfo[]>([]);
|
||||
const [selectedModel, setSelectedModel] = useState<string>("");
|
||||
const [status, setStatus] = useState<ServerStatus>("loading");
|
||||
|
||||
const refresh = useCallback(async () => {
|
||||
if (!enabled || !server.trim()) {
|
||||
setModels([]);
|
||||
setStatus("error");
|
||||
return;
|
||||
}
|
||||
|
||||
setStatus("loading");
|
||||
try {
|
||||
const headers: Record<string, string> = {};
|
||||
if (apiKey) headers["Authorization"] = `Bearer ${apiKey}`;
|
||||
const res = await fetch(`${server}/v1/models`, { headers });
|
||||
if (!res.ok) {
|
||||
throw new Error(`HTTP ${res.status}`);
|
||||
}
|
||||
const data = await res.json();
|
||||
const list: ModelInfo[] = data.data || [];
|
||||
setModels(list);
|
||||
setSelectedModel((current) => getNextSelectedModel(current, list));
|
||||
setStatus("ok");
|
||||
} catch {
|
||||
setModels([]);
|
||||
setStatus("error");
|
||||
}
|
||||
}, [enabled, server, apiKey]);
|
||||
|
||||
useEffect(() => {
|
||||
refresh();
|
||||
const id = setInterval(refresh, 30_000);
|
||||
return () => clearInterval(id);
|
||||
}, [refresh]);
|
||||
|
||||
return { models, selectedModel, setSelectedModel, status, refresh };
|
||||
}
|
||||
Reference in new issue
Block a user