feat: add better provider support, icons, regen, and a lot more
This commit is contained in:
@@ -0,0 +1,19 @@
|
||||
import { cancelPendingRename } from '~~/server/utils/renames';
|
||||
import { assert } from '~~/utils/assert';
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
await protectRoute(event);
|
||||
|
||||
const { renameId } = event.context.params!;
|
||||
assert(renameId);
|
||||
|
||||
if (cancelPendingRename(renameId)) {
|
||||
return {
|
||||
success: true,
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
success: false,
|
||||
};
|
||||
});
|
||||
@@ -0,0 +1,93 @@
|
||||
import * as z from 'zod';
|
||||
import { httpClient } from '~~/server/lib/triplit';
|
||||
import { renamePrompt } from '~~/prompts';
|
||||
import { schema } from '~~/triplit/schema';
|
||||
import { type Entity } from '@triplit/client';
|
||||
import { generateText } from 'ai';
|
||||
import { getGateway, type ModelGateway } from '~~/server/utils/ai-provider';
|
||||
import { addPendingRename } from '~~/server/utils/renames';
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
await protectRoute(event);
|
||||
|
||||
const userId = event.context.user!.id;
|
||||
|
||||
const result = await readValidatedBody(event, (body) =>
|
||||
z
|
||||
.object({
|
||||
modelId: z.string(),
|
||||
topicId: z.string(),
|
||||
prompt: z.string(),
|
||||
providerApiKey: z.string().optional(),
|
||||
})
|
||||
.safeParse(body),
|
||||
);
|
||||
if (!result.success) {
|
||||
throw createError({
|
||||
statusCode: 400,
|
||||
message: result.error.issues[0]!.message,
|
||||
});
|
||||
}
|
||||
|
||||
const { modelId, topicId, prompt, providerApiKey } = result.data;
|
||||
|
||||
const model = await httpClient.fetchOne(httpClient.query('models').Where('id', '=', modelId).Include('provider'));
|
||||
if (model === null || model.providerId !== model.providerId || model.userId !== userId) {
|
||||
throw createError({
|
||||
statusCode: 400,
|
||||
message: 'Invalid model',
|
||||
});
|
||||
}
|
||||
|
||||
const { gateway, textTransformer } = await getGateway(model.provider!, model, providerApiKey);
|
||||
const [renameId, abortController] = addPendingRename();
|
||||
event.waitUntil(autoRename(topicId, abortController, { gateway, model }, textTransformer, prompt));
|
||||
|
||||
return {
|
||||
success: true,
|
||||
renameId,
|
||||
};
|
||||
});
|
||||
|
||||
const autoRename = async (
|
||||
topicId: string,
|
||||
abortController: AbortController,
|
||||
model: {
|
||||
gateway: ModelGateway,
|
||||
model: Entity<typeof schema, 'models'>,
|
||||
},
|
||||
textTransformer: ((text: string) => string) | ((text: string) => string)[] | undefined,
|
||||
prompt: string,
|
||||
) => {
|
||||
try {
|
||||
const response = await generateText({
|
||||
model: model.gateway(model.model.externalId),
|
||||
system: renamePrompt,
|
||||
prompt,
|
||||
timeout: 90 * 1000,
|
||||
abortSignal: abortController.signal,
|
||||
})
|
||||
|
||||
let text = response.text;
|
||||
|
||||
if (textTransformer !== undefined) {
|
||||
if (Array.isArray(textTransformer)) {
|
||||
for (const transformer of textTransformer) {
|
||||
text = transformer(text);
|
||||
}
|
||||
} else {
|
||||
text = textTransformer(text);
|
||||
}
|
||||
}
|
||||
|
||||
await httpClient.update('topics', topicId, {
|
||||
name: text,
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Failed to auto-rename:', error);
|
||||
} finally {
|
||||
await httpClient.update('topics', topicId, {
|
||||
renaming: false
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user