refactor: 简化模型管理,移除启用/禁用,优化测试和布局
- 移除供应商/模型启用禁用能力,清理DB schema/migration/API/前端 - 供应商测试改为Base URL连通性+/models探测 - 新增POST /api/models/test模型连接测试 - 新增GET /api/providers/options专用供应商选项接口 - 统一工具栏为ModelsToolbar,参考项目管理布局 - 模型弹窗优化:默认能力、响应式3列标签、并排数值 - 前后端正整数校验、供应商下拉loading/error/empty状态 - 表格列宽统一,操作列/名称列固定宽度
This commit is contained in:
@@ -8,10 +8,10 @@ import { createProviderRegistry, generateText } from "ai";
|
||||
import type { AIProviderConfig } from "./types";
|
||||
|
||||
export function buildProviderRegistry(db: Database) {
|
||||
const enabledProviders = getEnabledProviders(db);
|
||||
const providers = getProviders(db);
|
||||
|
||||
const providerEntries: Record<string, ReturnType<typeof createProvider>> = {};
|
||||
for (const p of enabledProviders) {
|
||||
for (const p of providers) {
|
||||
providerEntries[p.id] = createProvider({
|
||||
apiKey: p.api_key,
|
||||
baseUrl: p.base_url,
|
||||
@@ -23,24 +23,105 @@ export function buildProviderRegistry(db: Database) {
|
||||
return createProviderRegistry(providerEntries);
|
||||
}
|
||||
|
||||
export async function testProviderConnection(config: AIProviderConfig): Promise<{ message: string; ok: boolean }> {
|
||||
export async function testModelConnection(
|
||||
config: AIProviderConfig & { modelId: string },
|
||||
): Promise<{ message: string; ok: boolean }> {
|
||||
try {
|
||||
const provider = createProvider(config);
|
||||
const model = provider.languageModel("test");
|
||||
|
||||
await generateText({
|
||||
maxOutputTokens: 1,
|
||||
model,
|
||||
maxOutputTokens: 10,
|
||||
model: provider.languageModel(config.modelId),
|
||||
prompt: "Hi",
|
||||
});
|
||||
|
||||
return { message: "连接成功", ok: true };
|
||||
return { message: "模型连接成功", ok: true };
|
||||
} catch (e: unknown) {
|
||||
const msg = e instanceof Error ? e.message : String(e);
|
||||
return { message: `连接失败: ${msg}`, ok: false };
|
||||
return { message: `模型连接失败:${msg}`, ok: false };
|
||||
}
|
||||
}
|
||||
|
||||
export async function testProviderConnection(config: AIProviderConfig): Promise<{ message: string; ok: boolean }> {
|
||||
const baseUrlResult = await probeBaseUrl(config.baseUrl);
|
||||
if (!baseUrlResult.ok) return baseUrlResult;
|
||||
|
||||
const modelsUrl = buildModelsUrl(config.baseUrl);
|
||||
|
||||
try {
|
||||
const response = await fetch(modelsUrl, {
|
||||
headers: buildModelsHeaders(config),
|
||||
signal: AbortSignal.timeout(5000),
|
||||
});
|
||||
|
||||
if (response.status === 401 || response.status === 403) {
|
||||
return { message: "Base URL 可连接,但 API Key 无效或权限不足。", ok: false };
|
||||
}
|
||||
|
||||
if ([404, 405, 501].includes(response.status)) {
|
||||
return {
|
||||
message: "Base URL 可连接,但可能不支持 /models 接口;可检查 URL 或忽略此提示。",
|
||||
ok: true,
|
||||
};
|
||||
}
|
||||
|
||||
if (!response.ok) {
|
||||
return {
|
||||
message: `Base URL 可连接,但 /models 请求失败(HTTP ${response.status});可检查 URL 或忽略此提示。`,
|
||||
ok: true,
|
||||
};
|
||||
}
|
||||
|
||||
const body = (await response.json().catch(() => null)) as unknown;
|
||||
const modelCount = countModels(body);
|
||||
if (modelCount !== null) {
|
||||
return { message: `连接成功,/models 返回 ${modelCount} 个模型。`, ok: true };
|
||||
}
|
||||
|
||||
return {
|
||||
message: "Base URL 可连接,但 /models 返回格式不兼容,可能不支持 /models;可检查 URL 或忽略此提示。",
|
||||
ok: true,
|
||||
};
|
||||
} catch (e: unknown) {
|
||||
const msg = e instanceof Error ? e.message : String(e);
|
||||
return { message: `Base URL 可连接,但 /models 请求异常:${msg};可检查 URL 或忽略此提示。`, ok: true };
|
||||
}
|
||||
}
|
||||
|
||||
function buildModelsHeaders(config: AIProviderConfig): HeadersInit {
|
||||
if (config.type === "anthropic") {
|
||||
return {
|
||||
accept: "application/json",
|
||||
"anthropic-version": "2023-06-01",
|
||||
"x-api-key": config.apiKey,
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
accept: "application/json",
|
||||
authorization: `Bearer ${config.apiKey}`,
|
||||
};
|
||||
}
|
||||
|
||||
function buildModelsUrl(baseUrl: string): string {
|
||||
const url = new URL(baseUrl);
|
||||
url.pathname = `${url.pathname.replace(/\/$/, "")}/models`;
|
||||
url.search = "";
|
||||
url.hash = "";
|
||||
return url.toString();
|
||||
}
|
||||
|
||||
function countModels(body: unknown): null | number {
|
||||
if (Array.isArray(body)) return body.length;
|
||||
if (!body || typeof body !== "object") return null;
|
||||
|
||||
const data = (body as { data?: unknown }).data;
|
||||
if (Array.isArray(data)) return data.length;
|
||||
|
||||
const models = (body as { models?: unknown }).models;
|
||||
if (Array.isArray(models)) return models.length;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function createProvider(config: AIProviderConfig) {
|
||||
switch (config.type) {
|
||||
case "anthropic":
|
||||
@@ -56,14 +137,14 @@ function createProvider(config: AIProviderConfig) {
|
||||
}
|
||||
}
|
||||
|
||||
function getEnabledProviders(db: Database): Array<{
|
||||
function getProviders(db: Database): Array<{
|
||||
api_key: string;
|
||||
base_url: string;
|
||||
id: string;
|
||||
name: string;
|
||||
type: "anthropic" | "openai" | "openai-compatible";
|
||||
}> {
|
||||
const stmt = db.prepare("SELECT id, name, type, base_url, api_key FROM providers WHERE enabled = 1");
|
||||
const stmt = db.prepare("SELECT id, name, type, base_url, api_key FROM providers");
|
||||
return stmt.all() as Array<{
|
||||
api_key: string;
|
||||
base_url: string;
|
||||
@@ -72,3 +153,16 @@ function getEnabledProviders(db: Database): Array<{
|
||||
type: "anthropic" | "openai" | "openai-compatible";
|
||||
}>;
|
||||
}
|
||||
|
||||
async function probeBaseUrl(baseUrl: string): Promise<{ message: string; ok: boolean }> {
|
||||
try {
|
||||
await fetch(baseUrl, {
|
||||
method: "HEAD",
|
||||
signal: AbortSignal.timeout(5000),
|
||||
});
|
||||
return { message: "Base URL 可连接", ok: true };
|
||||
} catch (e: unknown) {
|
||||
const msg = e instanceof Error ? e.message : String(e);
|
||||
return { message: `Base URL 不可达:${msg}`, ok: false };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,7 +36,6 @@ export function createModel(
|
||||
capabilities: JSON.stringify(capabilities),
|
||||
contextLength: request.contextLength ?? null,
|
||||
createdAt: now,
|
||||
enabled: true,
|
||||
id,
|
||||
maxOutputTokens: request.maxOutputTokens ?? null,
|
||||
modelId,
|
||||
@@ -66,32 +65,6 @@ export function deleteModel(raw: Database, id: string): { error: string; status:
|
||||
return { success: true };
|
||||
}
|
||||
|
||||
export function disableModel(raw: Database, id: string): { error: string; status: number } | { model: Model } {
|
||||
const db = wrap(raw);
|
||||
const existing = db.select().from(models).where(eq(models.id, id)).get();
|
||||
if (!existing) return { error: "模型不存在", status: 404 };
|
||||
if (!existing.enabled) return { error: "模型已禁用", status: 409 };
|
||||
|
||||
const now = new Date().toISOString();
|
||||
db.update(models).set({ enabled: false, updatedAt: now }).where(eq(models.id, id)).run();
|
||||
|
||||
const updated = db.select().from(models).where(eq(models.id, id)).get();
|
||||
return { model: toModel(updated!) };
|
||||
}
|
||||
|
||||
export function enableModel(raw: Database, id: string): { error: string; status: number } | { model: Model } {
|
||||
const db = wrap(raw);
|
||||
const existing = db.select().from(models).where(eq(models.id, id)).get();
|
||||
if (!existing) return { error: "模型不存在", status: 404 };
|
||||
if (existing.enabled) return { error: "模型已启用", status: 409 };
|
||||
|
||||
const now = new Date().toISOString();
|
||||
db.update(models).set({ enabled: true, updatedAt: now }).where(eq(models.id, id)).run();
|
||||
|
||||
const updated = db.select().from(models).where(eq(models.id, id)).get();
|
||||
return { model: toModel(updated!) };
|
||||
}
|
||||
|
||||
export function getModel(raw: Database, id: string): { error: string; status: number } | { model: Model } {
|
||||
const db = wrap(raw);
|
||||
const row = db.select().from(models).where(eq(models.id, id)).get();
|
||||
@@ -222,7 +195,6 @@ function toModel(row: typeof models.$inferSelect): Model {
|
||||
capabilities: JSON.parse(row.capabilities) as ModelCapability[],
|
||||
contextLength: row.contextLength,
|
||||
createdAt: row.createdAt,
|
||||
enabled: row.enabled,
|
||||
id: row.id,
|
||||
maxOutputTokens: row.maxOutputTokens,
|
||||
modelId: row.modelId,
|
||||
|
||||
@@ -3,7 +3,7 @@ import type Database from "bun:sqlite";
|
||||
import { and, desc, eq, like, sql } from "drizzle-orm";
|
||||
import { drizzle } from "drizzle-orm/bun-sqlite";
|
||||
|
||||
import type { CreateProviderRequest, Provider, UpdateProviderRequest } from "../../shared/api";
|
||||
import type { CreateProviderRequest, Provider, ProviderOption, UpdateProviderRequest } from "../../shared/api";
|
||||
|
||||
import { providers } from "./schema";
|
||||
|
||||
@@ -30,7 +30,6 @@ export function createProvider(
|
||||
apiKey,
|
||||
baseUrl,
|
||||
createdAt: now,
|
||||
enabled: true,
|
||||
id,
|
||||
name,
|
||||
type: request.type,
|
||||
@@ -58,32 +57,6 @@ export function deleteProvider(raw: Database, id: string): { error: string; stat
|
||||
return { success: true };
|
||||
}
|
||||
|
||||
export function disableProvider(raw: Database, id: string): { error: string; status: number } | { provider: Provider } {
|
||||
const db = wrap(raw);
|
||||
const existing = db.select().from(providers).where(eq(providers.id, id)).get();
|
||||
if (!existing) return { error: "供应商不存在", status: 404 };
|
||||
if (!existing.enabled) return { error: "供应商已禁用", status: 409 };
|
||||
|
||||
const now = new Date().toISOString();
|
||||
db.update(providers).set({ enabled: false, updatedAt: now }).where(eq(providers.id, id)).run();
|
||||
|
||||
const updated = db.select().from(providers).where(eq(providers.id, id)).get();
|
||||
return { provider: toProvider(updated!) };
|
||||
}
|
||||
|
||||
export function enableProvider(raw: Database, id: string): { error: string; status: number } | { provider: Provider } {
|
||||
const db = wrap(raw);
|
||||
const existing = db.select().from(providers).where(eq(providers.id, id)).get();
|
||||
if (!existing) return { error: "供应商不存在", status: 404 };
|
||||
if (existing.enabled) return { error: "供应商已启用", status: 409 };
|
||||
|
||||
const now = new Date().toISOString();
|
||||
db.update(providers).set({ enabled: true, updatedAt: now }).where(eq(providers.id, id)).run();
|
||||
|
||||
const updated = db.select().from(providers).where(eq(providers.id, id)).get();
|
||||
return { provider: toProvider(updated!) };
|
||||
}
|
||||
|
||||
export function getProvider(raw: Database, id: string): { error: string; status: number } | { provider: Provider } {
|
||||
const db = wrap(raw);
|
||||
const row = db.select().from(providers).where(eq(providers.id, id)).get();
|
||||
@@ -92,6 +65,17 @@ export function getProvider(raw: Database, id: string): { error: string; status:
|
||||
return { provider: toProvider(row) };
|
||||
}
|
||||
|
||||
export function listProviderOptions(raw: Database): ProviderOption[] {
|
||||
const db = wrap(raw);
|
||||
const rows = db
|
||||
.select({ id: providers.id, name: providers.name, type: providers.type })
|
||||
.from(providers)
|
||||
.orderBy(desc(providers.createdAt))
|
||||
.all();
|
||||
|
||||
return rows;
|
||||
}
|
||||
|
||||
export function listProviders(
|
||||
raw: Database,
|
||||
options: { keyword?: string; page: number; pageSize: number },
|
||||
@@ -189,7 +173,6 @@ function toProvider(row: typeof providers.$inferSelect): Provider {
|
||||
apiKey: row.apiKey,
|
||||
baseUrl: row.baseUrl,
|
||||
createdAt: row.createdAt,
|
||||
enabled: row.enabled,
|
||||
id: row.id,
|
||||
name: row.name,
|
||||
type: row.type,
|
||||
|
||||
@@ -16,7 +16,6 @@ export const providers = sqliteTable("providers", {
|
||||
apiKey: text("api_key").notNull(),
|
||||
baseUrl: text("base_url").notNull(),
|
||||
createdAt: text("created_at").notNull(),
|
||||
enabled: integer("enabled", { mode: "boolean" }).notNull().default(true),
|
||||
id: text("id").primaryKey(),
|
||||
name: text("name").notNull().unique(),
|
||||
type: text("type", { enum: ["anthropic", "openai", "openai-compatible"] })
|
||||
@@ -31,7 +30,6 @@ export const models = sqliteTable(
|
||||
capabilities: text("capabilities").notNull(),
|
||||
contextLength: integer("context_length"),
|
||||
createdAt: text("created_at").notNull(),
|
||||
enabled: integer("enabled", { mode: "boolean" }).notNull().default(true),
|
||||
id: text("id").primaryKey(),
|
||||
maxOutputTokens: integer("max_output_tokens"),
|
||||
modelId: text("model_id").notNull(),
|
||||
|
||||
@@ -38,6 +38,12 @@ export async function handleCreateModel(req: Request, db: Database, mode: Runtim
|
||||
return jsonResponse(createApiError(`Invalid capabilities: ${invalidCaps.join(", ")}`, 400), { mode, status: 400 });
|
||||
}
|
||||
|
||||
const numberError = validateOptionalPositiveInteger("contextLength", body.contextLength);
|
||||
if (numberError) return jsonResponse(createApiError(numberError, 400), { mode, status: 400 });
|
||||
|
||||
const tokenError = validateOptionalPositiveInteger("maxOutputTokens", body.maxOutputTokens);
|
||||
if (tokenError) return jsonResponse(createApiError(tokenError, 400), { mode, status: 400 });
|
||||
|
||||
const result = createModel(db, body);
|
||||
if ("error" in result) {
|
||||
return jsonResponse(createApiError(result.error, result.status), { mode, status: result.status });
|
||||
@@ -45,3 +51,9 @@ export async function handleCreateModel(req: Request, db: Database, mode: Runtim
|
||||
|
||||
return jsonResponse(result, { mode, status: 201 });
|
||||
}
|
||||
|
||||
function validateOptionalPositiveInteger(field: string, value: null | number | undefined): null | string {
|
||||
if (value === undefined || value === null) return null;
|
||||
if (!Number.isInteger(value) || value <= 0) return `${field} must be a positive integer`;
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
import type Database from "bun:sqlite";
|
||||
|
||||
import type { RuntimeMode } from "../../../shared/api";
|
||||
|
||||
import { disableModel } from "../../db/models";
|
||||
import { createApiError, jsonResponse } from "../../helpers";
|
||||
import { validateIdParam } from "../../middleware";
|
||||
|
||||
export function handleDisableModel(req: Request, db: Database, mode: RuntimeMode): Response {
|
||||
const url = new URL(req.url);
|
||||
const idStr = url.pathname.split("/")[3];
|
||||
|
||||
const validated = validateIdParam(idStr ?? "", mode);
|
||||
if (validated instanceof Response) return validated;
|
||||
|
||||
const result = disableModel(db, validated.id);
|
||||
if ("error" in result) {
|
||||
return jsonResponse(createApiError(result.error, result.status), { mode, status: result.status });
|
||||
}
|
||||
|
||||
return jsonResponse(result, { mode });
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
import type Database from "bun:sqlite";
|
||||
|
||||
import type { RuntimeMode } from "../../../shared/api";
|
||||
|
||||
import { enableModel } from "../../db/models";
|
||||
import { createApiError, jsonResponse } from "../../helpers";
|
||||
import { validateIdParam } from "../../middleware";
|
||||
|
||||
export function handleEnableModel(req: Request, db: Database, mode: RuntimeMode): Response {
|
||||
const url = new URL(req.url);
|
||||
const idStr = url.pathname.split("/")[3];
|
||||
|
||||
const validated = validateIdParam(idStr ?? "", mode);
|
||||
if (validated instanceof Response) return validated;
|
||||
|
||||
const result = enableModel(db, validated.id);
|
||||
if ("error" in result) {
|
||||
return jsonResponse(createApiError(result.error, result.status), { mode, status: result.status });
|
||||
}
|
||||
|
||||
return jsonResponse(result, { mode });
|
||||
}
|
||||
42
src/server/routes/models/test.ts
Normal file
42
src/server/routes/models/test.ts
Normal file
@@ -0,0 +1,42 @@
|
||||
import type Database from "bun:sqlite";
|
||||
|
||||
import type { RuntimeMode, TestModelRequest } from "../../../shared/api";
|
||||
|
||||
import { testModelConnection } from "../../ai/registry";
|
||||
import { getProvider } from "../../db/providers";
|
||||
import { createApiError, jsonResponse } from "../../helpers";
|
||||
|
||||
export async function handleTestModelConfig(req: Request, db: Database, mode: RuntimeMode): Promise<Response> {
|
||||
let body: TestModelRequest;
|
||||
try {
|
||||
body = (await req.json()) as TestModelRequest;
|
||||
} catch {
|
||||
return jsonResponse(createApiError("Invalid JSON body", 400), { mode, status: 400 });
|
||||
}
|
||||
|
||||
if (!body.providerId || typeof body.providerId !== "string") {
|
||||
return jsonResponse(createApiError("providerId is required", 400), { mode, status: 400 });
|
||||
}
|
||||
|
||||
if (!body.modelId || typeof body.modelId !== "string") {
|
||||
return jsonResponse(createApiError("modelId is required", 400), { mode, status: 400 });
|
||||
}
|
||||
|
||||
const providerResult = getProvider(db, body.providerId);
|
||||
if ("error" in providerResult) {
|
||||
return jsonResponse(createApiError(providerResult.error, providerResult.status), {
|
||||
mode,
|
||||
status: providerResult.status,
|
||||
});
|
||||
}
|
||||
|
||||
const testResult = await testModelConnection({
|
||||
apiKey: providerResult.provider.apiKey,
|
||||
baseUrl: providerResult.provider.baseUrl,
|
||||
modelId: body.modelId,
|
||||
name: providerResult.provider.name,
|
||||
type: providerResult.provider.type,
|
||||
});
|
||||
|
||||
return jsonResponse({ modelTestResponse: testResult }, { mode });
|
||||
}
|
||||
@@ -34,6 +34,12 @@ export async function handleUpdateModel(req: Request, db: Database, mode: Runtim
|
||||
}
|
||||
}
|
||||
|
||||
const numberError = validateOptionalPositiveInteger("contextLength", body.contextLength);
|
||||
if (numberError) return jsonResponse(createApiError(numberError, 400), { mode, status: 400 });
|
||||
|
||||
const tokenError = validateOptionalPositiveInteger("maxOutputTokens", body.maxOutputTokens);
|
||||
if (tokenError) return jsonResponse(createApiError(tokenError, 400), { mode, status: 400 });
|
||||
|
||||
const result = updateModel(db, validated.id, body);
|
||||
if ("error" in result) {
|
||||
return jsonResponse(createApiError(result.error, result.status), { mode, status: result.status });
|
||||
@@ -41,3 +47,9 @@ export async function handleUpdateModel(req: Request, db: Database, mode: Runtim
|
||||
|
||||
return jsonResponse(result, { mode });
|
||||
}
|
||||
|
||||
function validateOptionalPositiveInteger(field: string, value: null | number | undefined): null | string {
|
||||
if (value === undefined || value === null) return null;
|
||||
if (!Number.isInteger(value) || value <= 0) return `${field} must be a positive integer`;
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
import type Database from "bun:sqlite";
|
||||
|
||||
import type { RuntimeMode } from "../../../shared/api";
|
||||
|
||||
import { disableProvider } from "../../db/providers";
|
||||
import { createApiError, jsonResponse } from "../../helpers";
|
||||
import { validateIdParam } from "../../middleware";
|
||||
|
||||
export function handleDisableProvider(req: Request, db: Database, mode: RuntimeMode): Response {
|
||||
const url = new URL(req.url);
|
||||
const idStr = url.pathname.split("/")[3];
|
||||
|
||||
const validated = validateIdParam(idStr ?? "", mode);
|
||||
if (validated instanceof Response) return validated;
|
||||
|
||||
const result = disableProvider(db, validated.id);
|
||||
if ("error" in result) {
|
||||
return jsonResponse(createApiError(result.error, result.status), { mode, status: result.status });
|
||||
}
|
||||
|
||||
return jsonResponse(result, { mode });
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
import type Database from "bun:sqlite";
|
||||
|
||||
import type { RuntimeMode } from "../../../shared/api";
|
||||
|
||||
import { enableProvider } from "../../db/providers";
|
||||
import { createApiError, jsonResponse } from "../../helpers";
|
||||
import { validateIdParam } from "../../middleware";
|
||||
|
||||
export function handleEnableProvider(req: Request, db: Database, mode: RuntimeMode): Response {
|
||||
const url = new URL(req.url);
|
||||
const idStr = url.pathname.split("/")[3];
|
||||
|
||||
const validated = validateIdParam(idStr ?? "", mode);
|
||||
if (validated instanceof Response) return validated;
|
||||
|
||||
const result = enableProvider(db, validated.id);
|
||||
if ("error" in result) {
|
||||
return jsonResponse(createApiError(result.error, result.status), { mode, status: result.status });
|
||||
}
|
||||
|
||||
return jsonResponse(result, { mode });
|
||||
}
|
||||
10
src/server/routes/providers/options.ts
Normal file
10
src/server/routes/providers/options.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import type Database from "bun:sqlite";
|
||||
|
||||
import type { RuntimeMode } from "../../../shared/api";
|
||||
|
||||
import { listProviderOptions } from "../../db/providers";
|
||||
import { jsonResponse } from "../../helpers";
|
||||
|
||||
export function handleListProviderOptions(db: Database, mode: RuntimeMode): Response {
|
||||
return jsonResponse({ items: listProviderOptions(db) }, { mode });
|
||||
}
|
||||
@@ -3,35 +3,7 @@ import type Database from "bun:sqlite";
|
||||
import type { CreateProviderRequest, RuntimeMode } from "../../../shared/api";
|
||||
|
||||
import { testProviderConnection } from "../../ai/registry";
|
||||
import { getProvider } from "../../db/providers";
|
||||
import { createApiError, jsonResponse } from "../../helpers";
|
||||
import { validateIdParam } from "../../middleware";
|
||||
|
||||
export async function handleTestProvider(req: Request, db: Database, mode: RuntimeMode): Promise<Response> {
|
||||
const url = new URL(req.url);
|
||||
const idStr = url.pathname.split("/")[3];
|
||||
|
||||
const validated = validateIdParam(idStr ?? "", mode);
|
||||
if (validated instanceof Response) return validated;
|
||||
|
||||
const providerResult = getProvider(db, validated.id);
|
||||
if ("error" in providerResult) {
|
||||
return jsonResponse(createApiError(providerResult.error, providerResult.status), {
|
||||
mode,
|
||||
status: providerResult.status,
|
||||
});
|
||||
}
|
||||
|
||||
const provider = providerResult.provider;
|
||||
const testResult = await testProviderConnection({
|
||||
apiKey: provider.apiKey,
|
||||
baseUrl: provider.baseUrl,
|
||||
name: provider.name,
|
||||
type: provider.type,
|
||||
});
|
||||
|
||||
return jsonResponse({ providerTestResponse: testResult }, { mode });
|
||||
}
|
||||
|
||||
export async function handleTestProviderConfig(req: Request, _db: Database, mode: RuntimeMode): Promise<Response> {
|
||||
const validated = await readProviderConfig(req, mode);
|
||||
|
||||
@@ -67,16 +67,10 @@ export function startServer(options: StartServerOptions) {
|
||||
return handleUpdateModel(req, db, mode);
|
||||
},
|
||||
},
|
||||
"/api/models/:id/disable": {
|
||||
"/api/models/test": {
|
||||
POST: async (req) => {
|
||||
const { handleDisableModel } = await import("./routes/models/disable");
|
||||
return handleDisableModel(req, db, mode);
|
||||
},
|
||||
},
|
||||
"/api/models/:id/enable": {
|
||||
POST: async (req) => {
|
||||
const { handleEnableModel } = await import("./routes/models/enable");
|
||||
return handleEnableModel(req, db, mode);
|
||||
const { handleTestModelConfig } = await import("./routes/models/test");
|
||||
return handleTestModelConfig(req, db, mode);
|
||||
},
|
||||
},
|
||||
"/api/projects": {
|
||||
@@ -139,22 +133,10 @@ export function startServer(options: StartServerOptions) {
|
||||
return handleUpdateProvider(req, db, mode);
|
||||
},
|
||||
},
|
||||
"/api/providers/:id/disable": {
|
||||
POST: async (req) => {
|
||||
const { handleDisableProvider } = await import("./routes/providers/disable");
|
||||
return handleDisableProvider(req, db, mode);
|
||||
},
|
||||
},
|
||||
"/api/providers/:id/enable": {
|
||||
POST: async (req) => {
|
||||
const { handleEnableProvider } = await import("./routes/providers/enable");
|
||||
return handleEnableProvider(req, db, mode);
|
||||
},
|
||||
},
|
||||
"/api/providers/:id/test": {
|
||||
POST: async (req) => {
|
||||
const { handleTestProvider } = await import("./routes/providers/test");
|
||||
return handleTestProvider(req, db, mode);
|
||||
"/api/providers/options": {
|
||||
GET: async () => {
|
||||
const { handleListProviderOptions } = await import("./routes/providers/options");
|
||||
return handleListProviderOptions(db, mode);
|
||||
},
|
||||
},
|
||||
"/api/providers/test": {
|
||||
|
||||
Reference in New Issue
Block a user