From 482f72a4d12f85815f99eb0de89f132eb67185b3 Mon Sep 17 00:00:00 2001 From: Wroclaw Date: Fri, 26 Apr 2024 04:03:34 +0200 Subject: [PATCH] execution: factor out chat completion process --- src/execution.ts | 65 +++++++++++++++++++++++++++++------------------- 1 file changed, 40 insertions(+), 25 deletions(-) diff --git a/src/execution.ts b/src/execution.ts index 63679fa..4010b51 100644 --- a/src/execution.ts +++ b/src/execution.ts @@ -219,7 +219,6 @@ function logUsedTokens( async function executeFromQueue(channel: string) { const channelQueue = channelsRunning.get(channel) as ChannelsRunningValue; const message = channelQueue.at(0) as RequestMessage; - let functionRanCounter = 0; let OpenAImessages: ChatCompletionMessageParam[] = []; // ignore if we can't even send anything to reply @@ -247,30 +246,7 @@ async function executeFromQueue(channel: string) { }); OpenAImessages = toOpenAIMessages(messages.values()); - let generatedMessage: ChatCompletionMessage | undefined = undefined; - let answer: Awaited>; - - do { - answer = await openai.chat.completions.create({ - ...config.chatCompletionParams, - messages: OpenAImessages, - // FIXME: don't use new instance of FunctionManager - tools: new FunctionManager().getToolsForOpenAi(), - }); - - functionRanCounter += answer.choices[0].message?.tool_calls?.length ?? 0; - logUsedTokens(answer, message, ++functionRanCounter); - - generatedMessage = answer.choices[0].message; - if (!generatedMessage) throw new Error("Empty message received"); - - // handle tool calls - if (generatedMessage.tool_calls !== undefined && generatedMessage.tool_calls.length > 0) { - OpenAImessages.push(generatedMessage); - // FIXME: don't use new instance of FunctionManager - OpenAImessages.push(...(await new FunctionManager().handleToolCalls(generatedMessage.tool_calls))); - } - } while (generatedMessage.tool_calls !== undefined && generatedMessage.tool_calls.length > 0); + const answer = await executeChatCompletion(OpenAImessages, message); channelQueue.stopTyping(); @@ -349,3 +325,42 @@ async function executeFromQueue(channel: string) { else return executeFromQueue(channel); } + +/** + * Executes the chat completion process. + * + * @param OpenAImessages An array of ChatCompletionMessageParam objects representing the messages for chat completion. + * @param message An optional RequestMessage object representing the request message, used for logging. + * @returns A Promise that resolves to the answer from the chat completion process. + */ +async function executeChatCompletion( + OpenAImessages: ChatCompletionMessageParam[], + message: RequestMessage | undefined, +) { + let generatedMessage: ChatCompletionMessage | undefined = undefined; + let answer: Awaited>; + let functionRanCounter = 0; + + do { + answer = await openai.chat.completions.create({ + ...config.chatCompletionParams, + messages: OpenAImessages, + // FIXME: don't use new instance of FunctionManager + tools: new FunctionManager().getToolsForOpenAi(), + }); + + functionRanCounter += answer.choices[0].message?.tool_calls?.length ?? 0; + logUsedTokens(answer, message, ++functionRanCounter); + + generatedMessage = answer.choices[0].message; + if (!generatedMessage) throw new Error("Empty message received"); + + // handle tool calls + if (generatedMessage.tool_calls !== undefined && generatedMessage.tool_calls.length > 0) { + OpenAImessages.push(generatedMessage); + // FIXME: don't use new instance of FunctionManager + OpenAImessages.push(...(await new FunctionManager().handleToolCalls(generatedMessage.tool_calls))); + } + } while (generatedMessage.tool_calls !== undefined && generatedMessage.tool_calls.length > 0); + return answer; +}