Fix DB schema (#135)
This commit is contained in:
@@ -8,8 +8,9 @@ CREATE TABLE `language_model_providers` (
|
|||||||
);
|
);
|
||||||
--> statement-breakpoint
|
--> statement-breakpoint
|
||||||
CREATE TABLE `language_models` (
|
CREATE TABLE `language_models` (
|
||||||
`id` text PRIMARY KEY NOT NULL,
|
`id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
|
||||||
`name` text NOT NULL,
|
`display_name` text NOT NULL,
|
||||||
|
`api_name` text NOT NULL,
|
||||||
`provider_id` text NOT NULL,
|
`provider_id` text NOT NULL,
|
||||||
`description` text,
|
`description` text,
|
||||||
`max_output_tokens` integer,
|
`max_output_tokens` integer,
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"version": "6",
|
"version": "6",
|
||||||
"dialect": "sqlite",
|
"dialect": "sqlite",
|
||||||
"id": "f2ef6f83-09f5-4932-b7a0-4b205ba542ec",
|
"id": "424973e5-a102-4b71-8d5d-6160f1609b8c",
|
||||||
"prevId": "ceedb797-6aa3-4a50-b42f-bc85ee08b3df",
|
"prevId": "ceedb797-6aa3-4a50-b42f-bc85ee08b3df",
|
||||||
"tables": {
|
"tables": {
|
||||||
"apps": {
|
"apps": {
|
||||||
@@ -191,13 +191,20 @@
|
|||||||
"columns": {
|
"columns": {
|
||||||
"id": {
|
"id": {
|
||||||
"name": "id",
|
"name": "id",
|
||||||
"type": "text",
|
"type": "integer",
|
||||||
"primaryKey": true,
|
"primaryKey": true,
|
||||||
"notNull": true,
|
"notNull": true,
|
||||||
|
"autoincrement": true
|
||||||
|
},
|
||||||
|
"display_name": {
|
||||||
|
"name": "display_name",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
"autoincrement": false
|
"autoincrement": false
|
||||||
},
|
},
|
||||||
"name": {
|
"api_name": {
|
||||||
"name": "name",
|
"name": "api_name",
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"primaryKey": false,
|
"primaryKey": false,
|
||||||
"notNull": true,
|
"notNull": true,
|
||||||
|
|||||||
@@ -40,8 +40,8 @@
|
|||||||
{
|
{
|
||||||
"idx": 5,
|
"idx": 5,
|
||||||
"version": "6",
|
"version": "6",
|
||||||
"when": 1747087890389,
|
"when": 1747091036229,
|
||||||
"tag": "0005_hesitant_sister_grimm",
|
"tag": "0005_superb_lady_mastermind",
|
||||||
"breakpoints": true
|
"breakpoints": true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -27,8 +27,8 @@ export function CreateCustomModelDialog({
|
|||||||
onSuccess,
|
onSuccess,
|
||||||
providerId,
|
providerId,
|
||||||
}: CreateCustomModelDialogProps) {
|
}: CreateCustomModelDialogProps) {
|
||||||
const [id, setId] = useState("");
|
const [apiName, setApiName] = useState("");
|
||||||
const [name, setName] = useState("");
|
const [displayName, setDisplayName] = useState("");
|
||||||
const [description, setDescription] = useState("");
|
const [description, setDescription] = useState("");
|
||||||
const [maxOutputTokens, setMaxOutputTokens] = useState<string>("");
|
const [maxOutputTokens, setMaxOutputTokens] = useState<string>("");
|
||||||
const [contextWindow, setContextWindow] = useState<string>("");
|
const [contextWindow, setContextWindow] = useState<string>("");
|
||||||
@@ -38,8 +38,8 @@ export function CreateCustomModelDialog({
|
|||||||
const mutation = useMutation({
|
const mutation = useMutation({
|
||||||
mutationFn: async () => {
|
mutationFn: async () => {
|
||||||
const params = {
|
const params = {
|
||||||
id,
|
apiName,
|
||||||
name,
|
displayName,
|
||||||
providerId,
|
providerId,
|
||||||
description: description || undefined,
|
description: description || undefined,
|
||||||
maxOutputTokens: maxOutputTokens
|
maxOutputTokens: maxOutputTokens
|
||||||
@@ -48,8 +48,9 @@ export function CreateCustomModelDialog({
|
|||||||
contextWindow: contextWindow ? parseInt(contextWindow, 10) : undefined,
|
contextWindow: contextWindow ? parseInt(contextWindow, 10) : undefined,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!params.id) throw new Error("Model ID is required");
|
if (!params.apiName) throw new Error("Model API name is required");
|
||||||
if (!params.name) throw new Error("Model Name is required");
|
if (!params.displayName)
|
||||||
|
throw new Error("Model display name is required");
|
||||||
if (maxOutputTokens && isNaN(params.maxOutputTokens ?? NaN))
|
if (maxOutputTokens && isNaN(params.maxOutputTokens ?? NaN))
|
||||||
throw new Error("Max Output Tokens must be a valid number");
|
throw new Error("Max Output Tokens must be a valid number");
|
||||||
if (contextWindow && isNaN(params.contextWindow ?? NaN))
|
if (contextWindow && isNaN(params.contextWindow ?? NaN))
|
||||||
@@ -69,8 +70,8 @@ export function CreateCustomModelDialog({
|
|||||||
});
|
});
|
||||||
|
|
||||||
const resetForm = () => {
|
const resetForm = () => {
|
||||||
setId("");
|
setApiName("");
|
||||||
setName("");
|
setDisplayName("");
|
||||||
setDescription("");
|
setDescription("");
|
||||||
setMaxOutputTokens("");
|
setMaxOutputTokens("");
|
||||||
setContextWindow("");
|
setContextWindow("");
|
||||||
@@ -105,9 +106,9 @@ export function CreateCustomModelDialog({
|
|||||||
</Label>
|
</Label>
|
||||||
<Input
|
<Input
|
||||||
id="model-id"
|
id="model-id"
|
||||||
value={id}
|
value={apiName}
|
||||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
|
onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
|
||||||
setId(e.target.value)
|
setApiName(e.target.value)
|
||||||
}
|
}
|
||||||
className="col-span-3"
|
className="col-span-3"
|
||||||
placeholder="This must match the model expected by the API"
|
placeholder="This must match the model expected by the API"
|
||||||
@@ -121,9 +122,9 @@ export function CreateCustomModelDialog({
|
|||||||
</Label>
|
</Label>
|
||||||
<Input
|
<Input
|
||||||
id="model-name"
|
id="model-name"
|
||||||
value={name}
|
value={displayName}
|
||||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
|
onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
|
||||||
setName(e.target.value)
|
setDisplayName(e.target.value)
|
||||||
}
|
}
|
||||||
className="col-span-3"
|
className="col-span-3"
|
||||||
placeholder="Human-friendly name for the model"
|
placeholder="Human-friendly name for the model"
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ export function ModelsSection({ providerId }: ModelsSectionProps) {
|
|||||||
<div className="mt-4 space-y-3">
|
<div className="mt-4 space-y-3">
|
||||||
{models.map((model) => (
|
{models.map((model) => (
|
||||||
<div
|
<div
|
||||||
key={model.name}
|
key={model.apiName}
|
||||||
className="p-4 bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg shadow-sm"
|
className="p-4 bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg shadow-sm"
|
||||||
>
|
>
|
||||||
<div className="flex justify-between items-center">
|
<div className="flex justify-between items-center">
|
||||||
@@ -56,7 +56,7 @@ export function ModelsSection({ providerId }: ModelsSectionProps) {
|
|||||||
{/* Optional: Add an edit/delete button here later */}
|
{/* Optional: Add an edit/delete button here later */}
|
||||||
</div>
|
</div>
|
||||||
<p className="text-sm text-gray-500 dark:text-gray-400 italic">
|
<p className="text-sm text-gray-500 dark:text-gray-400 italic">
|
||||||
{model.name}
|
{model.apiName}
|
||||||
</p>
|
</p>
|
||||||
{model.description && (
|
{model.description && (
|
||||||
<p className="text-sm text-gray-600 dark:text-gray-300 mt-1">
|
<p className="text-sm text-gray-600 dark:text-gray-300 mt-1">
|
||||||
|
|||||||
@@ -82,8 +82,9 @@ export const language_model_providers = sqliteTable(
|
|||||||
);
|
);
|
||||||
|
|
||||||
export const language_models = sqliteTable("language_models", {
|
export const language_models = sqliteTable("language_models", {
|
||||||
id: text("id").primaryKey(),
|
id: integer("id").primaryKey({ autoIncrement: true }),
|
||||||
name: text("name").notNull(),
|
displayName: text("display_name").notNull(),
|
||||||
|
apiName: text("api_name").notNull(),
|
||||||
provider_id: text("provider_id")
|
provider_id: text("provider_id")
|
||||||
.notNull()
|
.notNull()
|
||||||
.references(() => language_model_providers.id, { onDelete: "cascade" }),
|
.references(() => language_model_providers.id, { onDelete: "cascade" }),
|
||||||
|
|||||||
@@ -87,8 +87,8 @@ export function registerLanguageModelHandlers() {
|
|||||||
params: CreateCustomLanguageModelParams,
|
params: CreateCustomLanguageModelParams,
|
||||||
): Promise<void> => {
|
): Promise<void> => {
|
||||||
const {
|
const {
|
||||||
id,
|
apiName,
|
||||||
name,
|
displayName,
|
||||||
providerId,
|
providerId,
|
||||||
description,
|
description,
|
||||||
maxOutputTokens,
|
maxOutputTokens,
|
||||||
@@ -96,11 +96,11 @@ export function registerLanguageModelHandlers() {
|
|||||||
} = params;
|
} = params;
|
||||||
|
|
||||||
// Validation
|
// Validation
|
||||||
if (!id) {
|
if (!apiName) {
|
||||||
throw new Error("Model ID is required");
|
throw new Error("Model API name is required");
|
||||||
}
|
}
|
||||||
if (!name) {
|
if (!displayName) {
|
||||||
throw new Error("Model name is required");
|
throw new Error("Model display name is required");
|
||||||
}
|
}
|
||||||
if (!providerId) {
|
if (!providerId) {
|
||||||
throw new Error("Provider ID is required");
|
throw new Error("Provider ID is required");
|
||||||
@@ -117,21 +117,10 @@ export function registerLanguageModelHandlers() {
|
|||||||
throw new Error(`Provider with ID "${providerId}" not found`);
|
throw new Error(`Provider with ID "${providerId}" not found`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if model ID already exists
|
|
||||||
const existingModel = db
|
|
||||||
.select()
|
|
||||||
.from(languageModelsSchema)
|
|
||||||
.where(eq(languageModelsSchema.id, id))
|
|
||||||
.get();
|
|
||||||
|
|
||||||
if (existingModel) {
|
|
||||||
throw new Error(`A model with ID "${id}" already exists`);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Insert the new model
|
// Insert the new model
|
||||||
await db.insert(languageModelsSchema).values({
|
await db.insert(languageModelsSchema).values({
|
||||||
id,
|
displayName,
|
||||||
name,
|
apiName,
|
||||||
provider_id: providerId,
|
provider_id: providerId,
|
||||||
description: description || null,
|
description: description || null,
|
||||||
max_output_tokens: maxOutputTokens || null,
|
max_output_tokens: maxOutputTokens || null,
|
||||||
|
|||||||
@@ -144,16 +144,26 @@ export interface LanguageModelProvider {
|
|||||||
type: "custom" | "local" | "cloud";
|
type: "custom" | "local" | "cloud";
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface LanguageModel {
|
export type LanguageModel =
|
||||||
id: string;
|
| {
|
||||||
name: string;
|
id: number;
|
||||||
|
apiName: string;
|
||||||
displayName: string;
|
displayName: string;
|
||||||
description: string;
|
description: string;
|
||||||
tag?: string;
|
tag?: string;
|
||||||
maxOutputTokens?: number;
|
maxOutputTokens?: number;
|
||||||
contextWindow?: number;
|
contextWindow?: number;
|
||||||
type: "local" | "cloud" | "custom";
|
type: "custom";
|
||||||
}
|
}
|
||||||
|
| {
|
||||||
|
apiName: string;
|
||||||
|
displayName: string;
|
||||||
|
description: string;
|
||||||
|
tag?: string;
|
||||||
|
maxOutputTokens?: number;
|
||||||
|
contextWindow?: number;
|
||||||
|
type: "local" | "cloud";
|
||||||
|
};
|
||||||
|
|
||||||
export interface CreateCustomLanguageModelProviderParams {
|
export interface CreateCustomLanguageModelProviderParams {
|
||||||
id: string;
|
id: string;
|
||||||
@@ -163,8 +173,8 @@ export interface CreateCustomLanguageModelProviderParams {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface CreateCustomLanguageModelParams {
|
export interface CreateCustomLanguageModelParams {
|
||||||
id: string;
|
apiName: string;
|
||||||
name: string;
|
displayName: string;
|
||||||
providerId: string;
|
providerId: string;
|
||||||
description?: string;
|
description?: string;
|
||||||
maxOutputTokens?: number;
|
maxOutputTokens?: number;
|
||||||
|
|||||||
@@ -157,7 +157,7 @@ export async function getLanguageModels(obj: {
|
|||||||
const models = MODEL_OPTIONS[providerId as RegularModelProvider] || [];
|
const models = MODEL_OPTIONS[providerId as RegularModelProvider] || [];
|
||||||
return models.map((model) => ({
|
return models.map((model) => ({
|
||||||
...model,
|
...model,
|
||||||
id: model.name,
|
apiName: model.name,
|
||||||
type: "cloud",
|
type: "cloud",
|
||||||
}));
|
}));
|
||||||
} else {
|
} else {
|
||||||
@@ -174,7 +174,8 @@ export async function getLanguageModels(obj: {
|
|||||||
.select({
|
.select({
|
||||||
id: languageModelsSchema.id,
|
id: languageModelsSchema.id,
|
||||||
// Map DB columns to LanguageModel fields
|
// Map DB columns to LanguageModel fields
|
||||||
name: languageModelsSchema.name,
|
displayName: languageModelsSchema.displayName,
|
||||||
|
apiName: languageModelsSchema.apiName,
|
||||||
// No display_name in DB, use name instead
|
// No display_name in DB, use name instead
|
||||||
description: languageModelsSchema.description,
|
description: languageModelsSchema.description,
|
||||||
// No tag in DB
|
// No tag in DB
|
||||||
@@ -186,7 +187,6 @@ export async function getLanguageModels(obj: {
|
|||||||
|
|
||||||
return customModelsDb.map((model) => ({
|
return customModelsDb.map((model) => ({
|
||||||
...model,
|
...model,
|
||||||
displayName: model.name, // Use name as displayName for custom models
|
|
||||||
// Ensure possibly null fields are handled, provide defaults or undefined if needed
|
// Ensure possibly null fields are handled, provide defaults or undefined if needed
|
||||||
description: model.description ?? "",
|
description: model.description ?? "",
|
||||||
tag: undefined, // No tag for custom models from DB
|
tag: undefined, // No tag for custom models from DB
|
||||||
|
|||||||
Reference in New Issue
Block a user