GPTcord/src/funcitonManager.ts

107 lines
2.8 KiB
TypeScript
Raw Normal View History

2023-07-30 01:51:40 +02:00
import { ChatCompletionFunctions, ChatCompletionRequestMessage, ChatCompletionRequestMessageFunctionCall } from "openai";
import config from "./config";
type parameterMap = {
string: string,
number: number,
};
type nameTypeMap = {[name: string]: keyof parameterMap} | Record<string, never>;
type OpenAIFunctionRequestData<T extends nameTypeMap> = {
[name in keyof T]: T[name];
};
/**
* Represents the function that can be ran by the OpenAI model
*/
export interface OpenAIFunction<T extends nameTypeMap = nameTypeMap> {
name: string,
description?: string,
parameters: {
type: "object",
properties: T extends Record<string, never> ? Record<string, never> : {
[name in T[string]]: {
type: T[name],
description?: string,
}
},
required?: Array<keyof T>,
},
}
export abstract class OpenAIFunction<T extends nameTypeMap = nameTypeMap> {
getSettings(): ChatCompletionFunctions {
return {
name: this.name,
description: this.description,
parameters: this.parameters,
};
}
abstract execute(data: OpenAIFunctionRequestData<T>): string;
}
/*
* Manages functions for the OpenAI
**/
export default class FunctionManager {
store = new Map<string, OpenAIFunction>();
constructor() {
this.store.set("getTime", new GetTime());
}
public getFunctions(): ChatCompletionFunctions[] {
const rvalue: ChatCompletionFunctions[] = [];
for (const [, value] of this.store) {
rvalue.push(value.getSettings());
}
return rvalue;
}
2023-07-30 01:51:40 +02:00
public handleFunction(request: ChatCompletionRequestMessageFunctionCall): ChatCompletionRequestMessage {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
let parsedArguments: any;
2023-07-30 01:51:40 +02:00
const functionToRun = this.store.get(request.name ?? "");
// check if the function is registered
if (!functionToRun) {
return {
role: "system",
content: "Only use functions that were provided to you",
};
}
try {
parsedArguments = JSON.parse(request.arguments ?? "");
}
catch (e) {
console.error("Function arguments raw: " + request.arguments);
throw new Error(`Failed to parse the function JSON arguments when running function [${request.name}]`, {cause: e});
}
2023-07-30 01:51:40 +02:00
return {
role: "function",
name: request.name,
content: functionToRun.execute(parsedArguments),
};
}
}
// buildins
class GetTime extends OpenAIFunction<Record<string, never>> {
name = "getTime";
description = "Gets current date and time with a timezone attached";
parameters = {
type: "object" as const,
properties: {} as Record<string, never>,
};
execute(): string {
return `${Intl.DateTimeFormat().resolvedOptions().timeZone}): ${new Date().toLocaleString("en-US", config.calendarConfig)}`;
}
}