UNPKG

@websolutespa/payload-plugin-bowl-llm

Version:

LLM plugin for Bowl PayloadCms plugin

126 lines (125 loc) 4.13 kB
import { ResponseSuccess } from '@websolutespa/payload-utils/server'; import fs from 'fs'; import OpenAI from 'openai'; import path from 'path'; import { addDataAndFileToRequest } from 'payload'; import { options } from '../options'; import { appHandler } from './app.handler'; import { errorHandler } from './error.handler'; const setLlmAppCurrentJobId = async (payload, app, jobId)=>{ await payload.update({ collection: options.slug.llmApp, id: app.id, data: { settings: { fineTuning: { currentJobId: jobId } } }, overrideAccess: true }); }; const createFineTuningJob = async (payload, app, jsonlFilePath)=>{ const openai = new OpenAI({ apiKey: app.settings.llmConfig.secrets.openAIApiKey }); const file = await openai.files.create({ file: fs.createReadStream(jsonlFilePath), purpose: 'fine-tune' }); const job = await openai.fineTuning.jobs.create({ training_file: file.id, model: 'gpt-3.5-turbo-1106', suffix: app.settings?.fineTuning?.modelNameSuffix ?? '' }); return job; }; const writeFineTuningJsonlFile = async (payload, app)=>{ const response = await payload.find({ collection: options.slug.llmFineTuning, where: { llmApp: { equals: app.id } }, overrideAccess: true }); const systemMessage = app.settings.llmConfig.prompt.prompt?.systemMessage || app.settings.llmConfig.prompt.systemMessage || ''; let jsonl = ''; for (const doc of response.docs){ const json = { messages: [ { role: 'system', content: systemMessage }, { role: 'user', content: doc.question }, { role: 'assistant', content: doc.answer } ] }; jsonl = jsonl.concat(JSON.stringify(json) + '\n'); } const fineTuningPath = path.join(process.cwd(), 'lib', 'fine-tuning'); fs.mkdirSync(fineTuningPath, { recursive: true }); const dest = path.join(fineTuningPath, 'finetuning.jsonl'); fs.writeFileSync(dest, jsonl); return dest; }; export async function fineTuningJobsHandler(payload) { const result = await payload.find({ collection: options.slug.llmApp, where: { 'settings.fineTuning.currentJobId': { not_equals: null } }, overrideAccess: true }); for (const app of result.docs){ const jobId = app.settings.fineTuning.currentJobId; if (jobId) { const openai = new OpenAI({ apiKey: app.settings.llmConfig.secrets.openAIApiKey }); const fineTune = await openai.fineTuning.jobs.retrieve(jobId); if (fineTune.status === 'succeeded') { await payload.update({ collection: options.slug.llmApp, id: app.id, data: { settings: { fineTuning: { currentJobId: null, fineTunedModelName: fineTune.fine_tuned_model } } }, overrideAccess: true }); } } } } export const fineTuningHandler = async (req)=>{ try { await addDataAndFileToRequest(req); const app = await appHandler(req); const { payload } = req; const jsonlFilePath = await writeFineTuningJsonlFile(payload, app); const job = await createFineTuningJob(payload, app, jsonlFilePath); await setLlmAppCurrentJobId(payload, app, job.id); return ResponseSuccess(job); } catch (error) { return errorHandler(error); } }; //# sourceMappingURL=fineTuning.handler.js.map