Spaces:
Sleeping
Sleeping
File size: 5,799 Bytes
c40c75a |
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 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 |
import React, { useState, useEffect } from "react";
import { Form, Input, Select } from "antd";
import { Button, TextInput } from "@tremor/react";
import { KeyResponse } from "./key_team_helpers/key_list";
import { fetchTeamModels } from "../components/create_key_button";
import { modelAvailableCall } from "./networking";
import NumericalInput from "./shared/numerical_input";
interface KeyEditViewProps {
keyData: KeyResponse;
onCancel: () => void;
onSubmit: (values: any) => Promise<void>;
teams?: any[] | null;
accessToken: string | null;
userID: string | null;
userRole: string | null;
}
// Add this helper function
const getAvailableModelsForKey = (keyData: KeyResponse, teams: any[] | null): string[] => {
// If no teams data is available, return empty array
console.log("getAvailableModelsForKey:", teams);
if (!teams || !keyData.team_id) {
return [];
}
// Find the team that matches the key's team_id
const keyTeam = teams.find(team => team.team_id === keyData.team_id);
// If team found and has models, return those models
if (keyTeam?.models) {
return keyTeam.models;
}
return [];
};
export function KeyEditView({
keyData,
onCancel,
onSubmit,
teams,
accessToken,
userID,
userRole }: KeyEditViewProps) {
const [form] = Form.useForm();
const [userModels, setUserModels] = useState<string[]>([]);
const team = teams?.find(team => team.team_id === keyData.team_id);
const [availableModels, setAvailableModels] = useState<string[]>([]);
useEffect(() => {
const fetchModels = async () => {
if (!userID || !userRole || !accessToken) return;
try {
if (keyData.team_id === null) {
// Fetch user models if no team
const model_available = await modelAvailableCall(
accessToken,
userID,
userRole
);
const available_model_names = model_available["data"].map(
(element: { id: string }) => element.id
);
setAvailableModels(available_model_names);
} else if (team?.team_id) {
// Fetch team models if team exists
const models = await fetchTeamModels(userID, userRole, accessToken, team.team_id);
setAvailableModels(Array.from(new Set([...team.models, ...models])));
}
} catch (error) {
console.error("Error fetching models:", error);
}
};
fetchModels();
}, [userID, userRole, accessToken, team, keyData.team_id]);
// Convert API budget duration to form format
const getBudgetDuration = (duration: string | null) => {
if (!duration) return null;
const durationMap: Record<string, string> = {
"24h": "daily",
"7d": "weekly",
"30d": "monthly"
};
return durationMap[duration] || null;
};
// Set initial form values
const initialValues = {
...keyData,
budget_duration: getBudgetDuration(keyData.budget_duration),
metadata: keyData.metadata ? JSON.stringify(keyData.metadata, null, 2) : "",
guardrails: keyData.metadata?.guardrails || []
};
return (
<Form
form={form}
onFinish={onSubmit}
initialValues={initialValues}
layout="vertical"
>
<Form.Item label="Key Alias" name="key_alias">
<TextInput />
</Form.Item>
<Form.Item label="Models" name="models">
<Select
mode="multiple"
placeholder="Select models"
style={{ width: "100%" }}
>
{/* Only show All Team Models if team has models */}
{availableModels.length > 0 && (
<Select.Option value="all-team-models">All Team Models</Select.Option>
)}
{/* Show available team models */}
{availableModels.map(model => (
<Select.Option key={model} value={model}>
{model}
</Select.Option>
))}
</Select>
</Form.Item>
<Form.Item label="Max Budget (USD)" name="max_budget">
<NumericalInput step={0.01} style={{ width: "100%" }} placeholder="Enter a numerical value"/>
</Form.Item>
<Form.Item label="Reset Budget" name="budget_duration">
<Select placeholder="n/a">
<Select.Option value="daily">Daily</Select.Option>
<Select.Option value="weekly">Weekly</Select.Option>
<Select.Option value="monthly">Monthly</Select.Option>
</Select>
</Form.Item>
<Form.Item label="TPM Limit" name="tpm_limit">
<NumericalInput min={0}/>
</Form.Item>
<Form.Item label="RPM Limit" name="rpm_limit">
<NumericalInput min={0}/>
</Form.Item>
<Form.Item label="Max Parallel Requests" name="max_parallel_requests">
<NumericalInput min={0}/>
</Form.Item>
<Form.Item label="Model TPM Limit" name="model_tpm_limit">
<Input.TextArea rows={4} placeholder='{"gpt-4": 100, "claude-v1": 200}'/>
</Form.Item>
<Form.Item label="Model RPM Limit" name="model_rpm_limit">
<Input.TextArea rows={4} placeholder='{"gpt-4": 100, "claude-v1": 200}'/>
</Form.Item>
<Form.Item label="Guardrails" name="guardrails">
<Select
mode="tags"
style={{ width: "100%" }}
placeholder="Select or enter guardrails"
/>
</Form.Item>
<Form.Item label="Metadata" name="metadata">
<Input.TextArea rows={10} />
</Form.Item>
{/* Hidden form field for token */}
<Form.Item name="token" hidden>
<Input />
</Form.Item>
<div className="flex justify-end gap-2 mt-6">
<Button variant="light" onClick={onCancel}>
Cancel
</Button>
<Button>
Save Changes
</Button>
</div>
</Form>
);
} |