add crud for adding providers and models to resources

This commit is contained in:
miloschwartz
2026-08-04 15:54:24 -04:00
parent ed8545f8a2
commit e38359c74f
39 changed files with 2343 additions and 438 deletions
+18 -30
View File
@@ -1,13 +1,17 @@
import { Request, Response, NextFunction } from "express";
import { z } from "zod";
import { db, resources, resourceAiModels, aiModels } from "@server/db";
import { eq, and, inArray } from "drizzle-orm";
import { db, resources, resourceAiModels } from "@server/db";
import { eq } from "drizzle-orm";
import response from "@server/lib/response";
import HttpCode from "@server/types/HttpCode";
import createHttpError from "http-errors";
import logger from "@server/logger";
import { fromError } from "zod-validation-error";
import { OpenAPITags, registry } from "@server/openApi";
import {
assertPublicAllowlistApiEligible,
assertModelsBelongToPublicAllowlistProviders
} from "@server/lib/aiInferenceResource";
const setResourceAiModelsBodySchema = z.strictObject({
modelIds: z.array(z.int().positive())
@@ -21,7 +25,7 @@ registry.registerPath({
method: "post",
path: "/resource/{resourceId}/ai-models",
description:
"Set the AI models a resource is restricted to. This replaces all existing restrictions. Pass an empty array to remove the restriction (allow every enabled model on the linked provider).",
"Replace the allowlist of catalog models for an inference resource. Requires at least one attached AI provider in allowlist mode. Models must belong to a provider attached in allowlist mode. An empty array denies all models.",
tags: [OpenAPITags.PublicResource],
request: {
params: setResourceAiModelsParamsSchema,
@@ -95,34 +99,18 @@ export async function setResourceAiModels(
);
}
if (modelIds.length > 0) {
if (!resource.aiProviderId) {
return next(
createHttpError(
HttpCode.BAD_REQUEST,
"Resource has no AI provider linked"
)
);
}
const eligibleError = await assertPublicAllowlistApiEligible(resource);
if (eligibleError) {
return next(createHttpError(HttpCode.BAD_REQUEST, eligibleError));
}
const validModels = await db
.select({ modelId: aiModels.modelId })
.from(aiModels)
.where(
and(
inArray(aiModels.modelId, modelIds),
eq(aiModels.providerId, resource.aiProviderId)
)
);
if (validModels.length !== new Set(modelIds).size) {
return next(
createHttpError(
HttpCode.BAD_REQUEST,
"One or more model IDs do not exist or do not belong to this resource's AI provider"
)
);
}
const modelError = await assertModelsBelongToPublicAllowlistProviders({
orgId: resource.orgId,
resourceId,
modelIds
});
if (modelError) {
return next(createHttpError(HttpCode.BAD_REQUEST, modelError));
}
await db.transaction(async (trx) => {