177 lines
5.3 KiB
TypeScript
177 lines
5.3 KiB
TypeScript
import { nanoid } from 'nanoid';
|
|
import * as schema from '~~/drizzle/schema';
|
|
|
|
export type Model = typeof schema.models.$inferSelect;
|
|
export type Provider = typeof schema.providers.$inferSelect;
|
|
|
|
export type ProviderWithModels = Provider & {
|
|
models: Model[];
|
|
};
|
|
|
|
export type ModelWithProvider = Model & {
|
|
provider: Provider;
|
|
};
|
|
|
|
export const useModels = async () => {
|
|
const providers = useState<ProviderWithModels[]>('models_state', () => []);
|
|
const loaded = useState('models_loaded', () => false);
|
|
|
|
const { refresh } = await useFetch<ProviderWithModels[]>('/api/providers', {
|
|
key: 'models_request',
|
|
immediate: !loaded.value,
|
|
onRequest() {
|
|
loaded.value = true;
|
|
},
|
|
onResponse({ response }) {
|
|
if (response.ok) {
|
|
providers.value = response._data ?? [];
|
|
}
|
|
}
|
|
});
|
|
|
|
const allModels = computed<ModelWithProvider[]>(() => {
|
|
const result: ModelWithProvider[] = [];
|
|
for (const provider of providers.value) {
|
|
if (!provider.enabled) continue;
|
|
for (const model of provider.models || []) {
|
|
if (!model.enabled) continue;
|
|
result.push({ ...model, provider });
|
|
}
|
|
}
|
|
return result;
|
|
});
|
|
|
|
const getModel = (id: string): ModelWithProvider | undefined => {
|
|
return allModels.value.find((model) => model.id === id);
|
|
};
|
|
|
|
const getProvider = (id: string): ProviderWithModels | undefined => {
|
|
return providers.value.find((provider) => provider.id === id);
|
|
};
|
|
|
|
const getFirstAvailableModel = () => {
|
|
return allModels.value[0] ?? null;
|
|
};
|
|
|
|
const createModel = async (model: Model) => {
|
|
model.id = nanoid();
|
|
await $fetch(`/api/model`, {
|
|
method: 'POST',
|
|
body: model,
|
|
onRequest() {
|
|
providers.value = providers.value.map(p => ({
|
|
...p,
|
|
models: p.id === model.providerId ? [...p.models, model] : p.models
|
|
}));
|
|
},
|
|
onResponseError() {
|
|
providers.value = providers.value.map(p => ({
|
|
...p,
|
|
models: p.id === model.providerId ? p.models.filter(m => m.id !== model.id) : p.models
|
|
}));
|
|
},
|
|
});
|
|
}
|
|
|
|
const updateModel = async (id: string, updates: Partial<Model>) => {
|
|
const model = providers.value.find(p => p.models.find(m => m.id === id));
|
|
if (!model) return;
|
|
|
|
const original = model;
|
|
|
|
await $fetch(`/api/model/${id}`, {
|
|
method: 'PATCH',
|
|
body: updates,
|
|
onRequest() {
|
|
providers.value = providers.value.map(p => ({
|
|
...p,
|
|
models: p.models.map(m =>
|
|
m.id === id ? { ...m, ...updates } : m
|
|
)
|
|
}));
|
|
},
|
|
onRequestError() {
|
|
providers.value = providers.value.map(p => ({
|
|
...p,
|
|
models: p.models.map(m =>
|
|
m.id === id ? original : m
|
|
)
|
|
}) as ProviderWithModels);
|
|
},
|
|
onResponseError() {
|
|
providers.value = providers.value.map(p => ({
|
|
...p,
|
|
models: p.models.map(m =>
|
|
m.id === id ? original : m
|
|
)
|
|
}) as ProviderWithModels);
|
|
},
|
|
// async onResponse() {
|
|
// await refresh();
|
|
// }
|
|
});
|
|
};
|
|
|
|
const deleteModel = async (id: string) => {
|
|
const model = providers.value.find(p => p.models.find(m => m.id === id));
|
|
if (!model) return;
|
|
|
|
await $fetch(`/api/model/${id}`, {
|
|
method: 'DELETE',
|
|
onRequest() {
|
|
providers.value = providers.value.map(p => ({
|
|
...p,
|
|
models: p.models.filter(m => m.id !== id)
|
|
}));
|
|
},
|
|
onResponseError() {
|
|
providers.value.push(model);
|
|
},
|
|
async onResponse() {
|
|
await refresh();
|
|
}
|
|
});
|
|
}
|
|
|
|
const updateProvider = async (id: string, updates: Partial<Provider>) => {
|
|
const provider = providers.value.find(p => p.id === id);
|
|
if (!provider) return;
|
|
|
|
const original = provider;
|
|
|
|
await $fetch(`/api/provider/${id}`, {
|
|
method: 'PATCH',
|
|
body: updates,
|
|
onRequest() {
|
|
providers.value = providers.value.map(p =>
|
|
p.id === id ? { ...p, ...updates } : p
|
|
);
|
|
},
|
|
onRequestError() {
|
|
providers.value = providers.value.map(p =>
|
|
p.id === id ? original : p
|
|
);
|
|
},
|
|
onResponseError() {
|
|
providers.value = providers.value.map(p =>
|
|
p.id === id ? original : p
|
|
);
|
|
},
|
|
async onResponse() {
|
|
await refresh();
|
|
}
|
|
});
|
|
};
|
|
|
|
return {
|
|
providers,
|
|
allModels,
|
|
getModel,
|
|
getProvider,
|
|
getFirstAvailableModel,
|
|
createModel,
|
|
updateModel,
|
|
updateProvider,
|
|
deleteModel
|
|
};
|
|
} |