File size: 4,738 Bytes
f1dd159 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 | import type { ModelRouteDTO } from "@/entities/model/types";
import { apiRequest, type PaginatedDTO } from "@/shared/api/client";
import { createObjectDecoder, createPaginatedDecoder, decodeBooleanResult, decodeCountResult, hasShape, isArrayOf, isBoolean, isNumber, isOneOf, isOptional, isString } from "@/shared/api/decoder";
import type { SortOrder } from "@/shared/lib/table-sort";
type ListModelsInput = {
page: number;
pageSize: number;
search?: string;
status?: string;
provider?: "grok_build" | "grok_web" | "grok_console" | "";
providerScope?: Array<"grok_build" | "grok_web" | "grok_console">;
tierScope?: Array<"free" | "super">;
activeScope?: boolean;
sortBy?: string;
sortOrder?: SortOrder;
};
const modelRouteValidator = hasShape({
id: isString,
publicId: isString,
provider: isOneOf("grok_build", "grok_web", "grok_console"),
upstreamModel: isString,
capability: isOneOf("responses", "chat", "image", "image_edit", "video"),
origin: isOneOf("catalog", "discovered", "manual"),
enabled: isBoolean,
accountIds: isArrayOf(isString),
bindingMode: isBoolean,
supportedAccounts: isNumber,
syncedAccounts: isNumber,
totalAccounts: isNumber,
capabilityKnown: isBoolean,
available: isBoolean,
lastSyncedAt: isOptional(isString),
});
const decodeModelRoute = createObjectDecoder<ModelRouteDTO>("model route", {
id: isString, publicId: isString, provider: isOneOf("grok_build", "grok_web", "grok_console"), upstreamModel: isString,
capability: isOneOf("responses", "chat", "image", "image_edit", "video"), origin: isOneOf("catalog", "discovered", "manual"),
enabled: isBoolean, accountIds: isArrayOf(isString), bindingMode: isBoolean, supportedAccounts: isNumber,
syncedAccounts: isNumber, totalAccounts: isNumber, capabilityKnown: isBoolean, available: isBoolean, lastSyncedAt: isOptional(isString),
});
const decodeModelPage = createPaginatedDecoder<ModelRouteDTO>(modelRouteValidator);
const modelAccountValidator = hasShape({ id: isString, name: isString });
const decodeModelAccounts = createObjectDecoder<{ items: ModelAccountOptionDTO[] }>("model accounts", { items: isArrayOf(modelAccountValidator) });
export function listModels(input: ListModelsInput): Promise<PaginatedDTO<ModelRouteDTO>> {
const query = new URLSearchParams({ page: String(input.page), pageSize: String(input.pageSize) });
if (input.search) query.set("search", input.search);
if (input.status) query.set("status", input.status);
if (input.provider) query.set("provider", input.provider);
for (const value of input.providerScope ?? []) query.append("providerScope", value);
for (const value of input.tierScope ?? []) query.append("tierScope", value);
if (input.activeScope) query.set("activeScope", "true");
if (input.sortBy && input.sortOrder) {
query.set("sortBy", input.sortBy);
query.set("sortOrder", input.sortOrder);
}
return apiRequest(`/api/admin/v1/models?${query}`, {}, decodeModelPage);
}
export function syncModels(): Promise<{ synced: number }> {
return apiRequest("/api/admin/v1/models/sync", { method: "POST" }, decodeCountResult<{ synced: number }>("synced"));
}
export type ModelAccountOptionDTO = { id: string; name: string };
export type CreateModelInput = {
publicId: string;
provider: ModelRouteDTO["provider"];
upstreamModel: string;
capability: ModelRouteDTO["capability"];
enabled: boolean;
accountIds: string[];
};
export function listModelAccountOptions(provider: ModelRouteDTO["provider"]): Promise<{ items: ModelAccountOptionDTO[] }> {
return apiRequest(`/api/admin/v1/models/accounts?provider=${provider}`, {}, decodeModelAccounts);
}
export function createModel(input: CreateModelInput): Promise<ModelRouteDTO> {
return apiRequest("/api/admin/v1/models", { method: "POST", body: input }, decodeModelRoute);
}
export function updateModel(id: string, input: { publicId: string; enabled: boolean; accountIds: string[] }): Promise<ModelRouteDTO> {
return apiRequest(`/api/admin/v1/models/${id}`, { method: "PATCH", body: input }, decodeModelRoute);
}
export function deleteModel(id: string): Promise<{ deleted: boolean }> {
return apiRequest(`/api/admin/v1/models/${id}`, { method: "DELETE" }, decodeBooleanResult<{ deleted: boolean }>("deleted"));
}
export function deleteModels(ids: string[]): Promise<{ deleted: number }> {
return apiRequest("/api/admin/v1/models", { method: "DELETE", body: { ids } }, decodeCountResult<{ deleted: number }>("deleted"));
}
export function updateModelsEnabled(ids: string[], enabled: boolean): Promise<{ updated: number }> {
return apiRequest("/api/admin/v1/models/batch", { method: "PATCH", body: { ids, enabled } }, decodeCountResult<{ updated: number }>("updated"));
}
|