fix(ui): restore provider assets and model availability endpoint (#367)
* fix(usage): track lifetime request total beyond history cap * fix(ui): restore provider assets and model availability endpoint
This commit is contained in:
103
src/app/api/models/availability/route.js
Normal file
103
src/app/api/models/availability/route.js
Normal file
@@ -0,0 +1,103 @@
|
||||
import { NextResponse } from "next/server";
|
||||
import {
|
||||
getProviderConnections,
|
||||
updateProviderConnection,
|
||||
} from "@/lib/localDb";
|
||||
|
||||
const MODEL_LOCK_PREFIX = "modelLock_";
|
||||
|
||||
function getActiveModelLocks(connection) {
|
||||
const now = Date.now();
|
||||
return Object.entries(connection)
|
||||
.filter(([key, value]) => key.startsWith(MODEL_LOCK_PREFIX) && value)
|
||||
.map(([key, value]) => ({
|
||||
key,
|
||||
model: key.slice(MODEL_LOCK_PREFIX.length) || "__all",
|
||||
until: value,
|
||||
active: new Date(value).getTime() > now,
|
||||
}))
|
||||
.filter((lock) => lock.active);
|
||||
}
|
||||
|
||||
export async function GET() {
|
||||
try {
|
||||
const connections = await getProviderConnections();
|
||||
const models = [];
|
||||
|
||||
for (const connection of connections) {
|
||||
const locks = getActiveModelLocks(connection);
|
||||
for (const lock of locks) {
|
||||
models.push({
|
||||
provider: connection.provider,
|
||||
model: lock.model,
|
||||
status: "cooldown",
|
||||
until: lock.until,
|
||||
connectionId: connection.id,
|
||||
connectionName: connection.name || connection.email || connection.id,
|
||||
lastError: connection.lastError || null,
|
||||
});
|
||||
}
|
||||
|
||||
if (locks.length === 0 && connection.testStatus === "unavailable") {
|
||||
models.push({
|
||||
provider: connection.provider,
|
||||
model: "__all",
|
||||
status: "unavailable",
|
||||
connectionId: connection.id,
|
||||
connectionName: connection.name || connection.email || connection.id,
|
||||
lastError: connection.lastError || null,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return NextResponse.json({
|
||||
models,
|
||||
unavailableCount: models.length,
|
||||
});
|
||||
} catch (error) {
|
||||
console.error("[API] Failed to get model availability:", error);
|
||||
return NextResponse.json(
|
||||
{ error: "Failed to fetch model availability" },
|
||||
{ status: 500 },
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export async function POST(request) {
|
||||
try {
|
||||
const { action, provider, model } = await request.json();
|
||||
|
||||
if (action !== "clearCooldown" || !provider || !model) {
|
||||
return NextResponse.json({ error: "Invalid request" }, { status: 400 });
|
||||
}
|
||||
|
||||
const connections = await getProviderConnections({ provider });
|
||||
const lockKey = `${MODEL_LOCK_PREFIX}${model}`;
|
||||
|
||||
await Promise.all(
|
||||
connections
|
||||
.filter((connection) => connection[lockKey])
|
||||
.map((connection) =>
|
||||
updateProviderConnection(connection.id, {
|
||||
[lockKey]: null,
|
||||
...(connection.testStatus === "unavailable"
|
||||
? {
|
||||
testStatus: "active",
|
||||
lastError: null,
|
||||
lastErrorAt: null,
|
||||
backoffLevel: 0,
|
||||
}
|
||||
: {}),
|
||||
}),
|
||||
),
|
||||
);
|
||||
|
||||
return NextResponse.json({ ok: true });
|
||||
} catch (error) {
|
||||
console.error("[API] Failed to clear model cooldown:", error);
|
||||
return NextResponse.json(
|
||||
{ error: "Failed to clear cooldown" },
|
||||
{ status: 500 },
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user