add the budget to the models on the provider

This commit is contained in:
Owen
2026-08-10 15:09:39 -04:00
parent e76377d3c7
commit e012063f5b
3 changed files with 76 additions and 22 deletions
+4 -1
View File
@@ -1820,7 +1820,10 @@
"aiProviderModelsSourceAll": "Matches every model key", "aiProviderModelsSourceAll": "Matches every model key",
"aiProviderModelsBudgetConfigured": "Budget configured", "aiProviderModelsBudgetConfigured": "Budget configured",
"aiProviderModelsEditTitle": "Edit Model", "aiProviderModelsEditTitle": "Edit Model",
"aiProviderModelsEditDescription": "Update the model key. Additional settings such as budgets will appear here later.", "aiProviderModelsEditDescription": "Update the model key or configure its inference budget.",
"aiProviderModelsBudgetTab": "Inference Budget",
"aiProviderModelsBudgetDescription": "Configure how this model restricts usage based on spending or token limits",
"aiProviderModelsBudgetUnsaved": "Save this model first to configure its inference budget.",
"aiProviderModelsKeyLabel": "Model Key", "aiProviderModelsKeyLabel": "Model Key",
"aiProviderModelsKeyRequired": "Enter a model key", "aiProviderModelsKeyRequired": "Enter a model key",
"aiProviderModelsKeyDuplicate": "This model key is already on a list", "aiProviderModelsKeyDuplicate": "This model key is already on a list",
@@ -235,6 +235,7 @@ export default function AiProviderModelsPage() {
<div className="space-y-2"> <div className="space-y-2">
<Label>{t("aiProviderModelsAllow")}</Label> <Label>{t("aiProviderModelsAllow")}</Label>
<AiProviderModelListEditor <AiProviderModelListEditor
orgId={provider.orgId}
listType="allow" listType="allow"
items={allowItems} items={allowItems}
onChange={setAllowItems} onChange={setAllowItems}
@@ -254,6 +255,7 @@ export default function AiProviderModelsPage() {
<div className="space-y-2"> <div className="space-y-2">
<Label>{t("aiProviderModelsBlock")}</Label> <Label>{t("aiProviderModelsBlock")}</Label>
<AiProviderModelListEditor <AiProviderModelListEditor
orgId={provider.orgId}
listType="block" listType="block"
items={blockItems} items={blockItems}
onChange={setBlockItems} onChange={setBlockItems}
+70 -21
View File
@@ -42,6 +42,8 @@ import {
} from "@app/components/ui/tooltip"; } from "@app/components/ui/tooltip";
import { cn } from "@app/lib/cn"; import { cn } from "@app/lib/cn";
import { isModelKeyPattern } from "@server/lib/aiModelKeyMatch"; import { isModelKeyPattern } from "@server/lib/aiModelKeyMatch";
import { HorizontalTabs } from "@app/components/HorizontalTabs";
import { BudgetsEditor } from "@app/components/BudgetsEditor";
import { zodResolver } from "@hookform/resolvers/zod"; import { zodResolver } from "@hookform/resolvers/zod";
import { import {
Asterisk, Asterisk,
@@ -75,6 +77,7 @@ export type AiProviderModelListItem = {
}; };
export type AiProviderModelListEditorProps = { export type AiProviderModelListEditorProps = {
orgId: string;
listType: ModelListType; listType: ModelListType;
items: AiProviderModelListItem[]; items: AiProviderModelListItem[];
catalogModels: string[]; catalogModels: string[];
@@ -146,6 +149,7 @@ function useModelGridColumns(): number {
} }
export function AiProviderModelListEditor({ export function AiProviderModelListEditor({
orgId,
listType, listType,
items, items,
catalogModels, catalogModels,
@@ -632,6 +636,7 @@ export function AiProviderModelListEditor({
{editing && ( {editing && (
<EditModelCredenza <EditModelCredenza
orgId={orgId}
item={editing} item={editing}
open={editingClientId !== null} open={editingClientId !== null}
onOpenChange={(open) => { onOpenChange={(open) => {
@@ -772,12 +777,14 @@ type EditFormValues = {
}; };
function EditModelCredenza({ function EditModelCredenza({
orgId,
item, item,
open, open,
onOpenChange, onOpenChange,
existingKeys, existingKeys,
onSave onSave
}: { }: {
orgId: string;
item: AiProviderModelListItem; item: AiProviderModelListItem;
open: boolean; open: boolean;
onOpenChange: (open: boolean) => void; onOpenChange: (open: boolean) => void;
@@ -835,27 +842,69 @@ function EditModelCredenza({
id="ai-provider-model-edit-form" id="ai-provider-model-edit-form"
onSubmit={form.handleSubmit(handleSubmit)} onSubmit={form.handleSubmit(handleSubmit)}
> >
<CredenzaBody className="space-y-4"> <CredenzaBody>
<FormField <HorizontalTabs
control={form.control} clientSide={true}
name="modelKey" defaultTab={0}
render={({ field }) => ( items={[
<FormItem> { title: t("general"), href: "#" },
<FormLabel> {
{t("aiProviderModelsKeyLabel")} title: t(
</FormLabel> "aiProviderModelsBudgetTab"
<FormControl> ),
<Input href: "#"
{...field} }
autoComplete="off" ]}
spellCheck={false} >
className="font-mono" <div className="space-y-4 mt-4">
/> <FormField
</FormControl> control={form.control}
<FormMessage /> name="modelKey"
</FormItem> render={({ field }) => (
)} <FormItem>
/> <FormLabel>
{t(
"aiProviderModelsKeyLabel"
)}
</FormLabel>
<FormControl>
<Input
{...field}
autoComplete="off"
spellCheck={false}
className="font-mono"
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
</div>
<div className="space-y-4 mt-4">
{item.modelId !== undefined ? (
<BudgetsEditor
orgId={orgId}
scope={{
type: "model",
id: item.modelId
}}
hideCardHeader={true}
title={t(
"aiProviderModelsBudgetTab"
)}
description={t(
"aiProviderModelsBudgetDescription"
)}
/>
) : (
<p className="text-sm text-muted-foreground">
{t(
"aiProviderModelsBudgetUnsaved"
)}
</p>
)}
</div>
</HorizontalTabs>
</CredenzaBody> </CredenzaBody>
</form> </form>
</Form> </Form>