add basic ui for private inference resource

This commit is contained in:
miloschwartz
2026-08-04 16:54:23 -04:00
parent c085de1e9e
commit 7759d87835
19 changed files with 828 additions and 208 deletions
@@ -331,10 +331,6 @@ async function providerMatchesModel(
requestedModel: string,
allowedModelIds: number[]
): Promise<boolean> {
if (attachment.modelAccessMode === "passthrough") {
return true;
}
const [matchedModel] = await db
.select({
modelId: aiModels.modelId,
@@ -366,26 +362,7 @@ async function selectProvider(
allowedModelIds: number[],
requestedModel: string | undefined
): Promise<ProviderSelection> {
const passthroughAttachments = attachments.filter(
(a) => a.modelAccessMode === "passthrough"
);
const hasRestricted = attachments.some(
(a) =>
a.modelAccessMode === "catalog" || a.modelAccessMode === "allowlist"
);
if (!requestedModel) {
if (hasRestricted) {
return {
ok: false,
status: HttpCode.FORBIDDEN,
message:
"This resource restricts access to specific models; a model must be specified"
};
}
if (passthroughAttachments.length === 1) {
return { ok: true, provider: passthroughAttachments[0].provider };
}
return {
ok: false,
status: HttpCode.FORBIDDEN,
@@ -395,10 +372,6 @@ async function selectProvider(
const candidates: ProviderAttachment[] = [];
for (const attachment of attachments) {
if (attachment.modelAccessMode === "passthrough") {
candidates.push(attachment);
continue;
}
if (
await providerMatchesModel(
attachment,
@@ -422,11 +395,6 @@ async function selectProvider(
};
}
// Zero candidates: fall back to a single passthrough attachment if present
if (passthroughAttachments.length === 1) {
return { ok: true, provider: passthroughAttachments[0].provider };
}
return {
ok: false,
status: HttpCode.FORBIDDEN,
+2 -4
View File
@@ -109,7 +109,7 @@ const createHttpResourceSchema = z
.array(resourceAiProviderAttachmentSchema)
.optional()
.describe(
"For inference-mode resources: AI providers to attach. Each entry may set modelAccessMode (passthrough, catalog, or allowlist); defaults to passthrough. At most one passthrough provider is allowed."
"For inference-mode resources: AI providers to attach. Each entry may set modelAccessMode (catalog or allowlist); defaults to catalog. Model keys must be unique across attached catalog providers."
)
})
.refine(
@@ -397,9 +397,7 @@ async function createHttpResource(
requireAtLeastOne: true
});
if (isInferenceFieldsError(resolved)) {
return next(
createHttpError(HttpCode.BAD_REQUEST, resolved.error)
);
return next(createHttpError(HttpCode.BAD_REQUEST, resolved.error));
}
providerAttachments = resolved;
} else if (aiProviderInputs && aiProviderInputs.length > 0) {
@@ -27,7 +27,7 @@ registry.registerPath({
method: "post",
path: "/resource/{resourceId}/ai-providers",
description:
"Replace the AI providers attached to an inference resource. At least one provider is required. At most one may use passthrough mode.",
"Replace the AI providers attached to an inference resource. At least one provider is required. Model keys must be unique across attached catalog providers.",
tags: [OpenAPITags.PublicResource],
request: {
params: setResourceAiProvidersParamsSchema,
@@ -116,7 +116,9 @@ export async function setResourceAiProviders(
requireAtLeastOne: true
});
if (isInferenceFieldsError(attachments)) {
return next(createHttpError(HttpCode.BAD_REQUEST, attachments.error));
return next(
createHttpError(HttpCode.BAD_REQUEST, attachments.error)
);
}
await setPublicResourceAiProviders(resourceId, attachments);
@@ -90,7 +90,7 @@ const createSiteResourceSchema = z
.array(resourceAiProviderAttachmentSchema)
.optional()
.describe(
"For inference-mode site resources: AI providers to attach. Each entry may set modelAccessMode (passthrough, catalog, or allowlist); defaults to passthrough. At most one passthrough provider is allowed."
"For inference-mode site resources: AI providers to attach. Each entry may set modelAccessMode (catalog or allowlist); defaults to catalog. Model keys must be unique across attached catalog providers."
)
})
.strict()
@@ -27,7 +27,7 @@ registry.registerPath({
method: "post",
path: "/site-resource/{siteResourceId}/ai-providers",
description:
"Replace the AI providers attached to an inference site resource. At least one provider is required. At most one may use passthrough mode.",
"Replace the AI providers attached to an inference site resource. At least one provider is required. Model keys must be unique across attached catalog providers.",
tags: [OpenAPITags.PrivateResource],
request: {
params: setSiteResourceAiProvidersParamsSchema,
@@ -118,7 +118,9 @@ export async function setSiteResourceAiProviders(
requireAtLeastOne: true
});
if (isInferenceFieldsError(attachments)) {
return next(createHttpError(HttpCode.BAD_REQUEST, attachments.error));
return next(
createHttpError(HttpCode.BAD_REQUEST, attachments.error)
);
}
await replaceAttachments(siteResourceId, attachments);