Sumi/src/routes/+server.ts

62 lines
1.8 KiB
TypeScript

import { fail } from '@sveltejs/kit';
import type { RequestHandler } from './$types';
import { RecursiveCharacterTextSplitter } from 'langchain/text_splitter';
import { OpenAI } from 'langchain/llms';
import { loadSummarizationChain } from 'langchain/chains';
import { Readability } from '@mozilla/readability';
const parseSite = async (url: string) => {
const jsdom = await import('jsdom');
const { JSDOM } = jsdom;
const response = await fetch(url, {
method: 'GET',
mode: 'cors'
});
const html = await response.text();
const dom = new JSDOM(html);
const article = new Readability(dom.window.document).parse();
return article?.textContent;
};
export const POST = (async ({ request, url }) => {
try {
const form = await request.formData();
const url = form.get('url');
const file = form.get('file');
if (!file && !url) throw new Error('No prompt found in the request.');
let text: string;
if (url) {
const article = await parseSite(url as string);
if (!article) throw new Error('Could not parse site');
text = article;
} else if (file) {
text = await (file as Blob).text();
} else {
throw new Error('Unknown error has occurred.');
}
const model = new OpenAI({ temperature: 0 });
const textSplitter = new RecursiveCharacterTextSplitter({ chunkSize: 1000 });
const docs = await textSplitter.createDocuments([text]);
// This convenience function creates a document chain prompted to summarize a set of documents.
const chain = loadSummarizationChain(model);
const response = await chain.call({
input_documents: docs
});
return new Response(JSON.stringify({ response: response.text }), {
headers: {
'Content-Type': 'application/json'
}
});
} catch (err) {
console.log(err);
const appError = err as App.Error;
console.log(appError.message);
throw fail(500, { err: err });
}
}) satisfies RequestHandler;