6500db9c1c
* move index to home folder, create state and context files and barrell folder * Sanity Check Commit: reducer added to home.tsx manual QA all working * WIP: promptBar * fix missing json parse on folders and prompts * split context and add promptbar context * add context to nested prompt componets and componetize Folder componet * remove log * Create buttons folder and componetize sidebar action button * tidy up prompt handlers * componetized sidebar * added back chatbar componet to left side sidebar * monster commit: Componetized the common code between chatbar and promptbar into new componet Sidebar and added context to both bars * add useFetch service * added prettier import sort to keep imports ordered and easier to indentify * added react query and useFetch to work with RQ * added apiService, errorService and reactQuery * add callback and tidy up error service * refactor chat and child componets to useContext * fix extra calls and bad calls to mel endpoint * minor import cleanup --------- Co-authored-by: jc.durbin <jc.durbin@ardanis.com>
64 lines
1.7 KiB
TypeScript
64 lines
1.7 KiB
TypeScript
import { DEFAULT_SYSTEM_PROMPT } from '@/utils/app/const';
|
|
import { OpenAIError, OpenAIStream } from '@/utils/server';
|
|
|
|
import { ChatBody, Message } from '@/types/chat';
|
|
|
|
// @ts-expect-error
|
|
import wasm from '../../node_modules/@dqbd/tiktoken/lite/tiktoken_bg.wasm?module';
|
|
|
|
import tiktokenModel from '@dqbd/tiktoken/encoders/cl100k_base.json';
|
|
import { Tiktoken, init } from '@dqbd/tiktoken/lite/init';
|
|
|
|
export const config = {
|
|
runtime: 'edge',
|
|
};
|
|
|
|
const handler = async (req: Request): Promise<Response> => {
|
|
try {
|
|
const { model, messages, key, prompt } = (await req.json()) as ChatBody;
|
|
|
|
await init((imports) => WebAssembly.instantiate(wasm, imports));
|
|
const encoding = new Tiktoken(
|
|
tiktokenModel.bpe_ranks,
|
|
tiktokenModel.special_tokens,
|
|
tiktokenModel.pat_str,
|
|
);
|
|
|
|
let promptToSend = prompt;
|
|
if (!promptToSend) {
|
|
promptToSend = DEFAULT_SYSTEM_PROMPT;
|
|
}
|
|
|
|
const prompt_tokens = encoding.encode(promptToSend);
|
|
|
|
let tokenCount = prompt_tokens.length;
|
|
let messagesToSend: Message[] = [];
|
|
|
|
for (let i = messages.length - 1; i >= 0; i--) {
|
|
const message = messages[i];
|
|
const tokens = encoding.encode(message.content);
|
|
|
|
if (tokenCount + tokens.length + 1000 > model.tokenLimit) {
|
|
break;
|
|
}
|
|
tokenCount += tokens.length;
|
|
messagesToSend = [message, ...messagesToSend];
|
|
}
|
|
|
|
encoding.free();
|
|
|
|
const stream = await OpenAIStream(model, promptToSend, key, messagesToSend);
|
|
|
|
return new Response(stream);
|
|
} catch (error) {
|
|
console.error(error);
|
|
if (error instanceof OpenAIError) {
|
|
return new Response('Error', { status: 500, statusText: error.message });
|
|
} else {
|
|
return new Response('Error', { status: 500 });
|
|
}
|
|
}
|
|
};
|
|
|
|
export default handler;
|