45aed936b1
- Fix inconsistent indentation across multiple engine files - Remove trailing whitespace and add missing newlines - Improve code formatting in prompt generation functions - Break long lines for better readability - Standardize spacing and brackets placement
78 lines
2.1 KiB
TypeScript
78 lines
2.1 KiB
TypeScript
import axios from 'axios';
|
|
import { OpenAI } from 'openai';
|
|
import { GenerateCommitMessageErrorEnum } from '../generateCommitMessageFromGitDiff';
|
|
import { parseCustomHeaders } from '../utils/engine';
|
|
import { removeContentTags } from '../utils/removeContentTags';
|
|
import { tokenCount } from '../utils/tokenCount';
|
|
import { AiEngine, AiEngineConfig } from './Engine';
|
|
|
|
export interface OpenAiConfig extends AiEngineConfig {}
|
|
|
|
export class OpenAiEngine implements AiEngine {
|
|
config: OpenAiConfig;
|
|
client: OpenAI;
|
|
|
|
constructor(config: OpenAiConfig) {
|
|
this.config = config;
|
|
|
|
const clientOptions: OpenAI.ClientOptions = {
|
|
apiKey: config.apiKey
|
|
};
|
|
|
|
if (config.baseURL) {
|
|
clientOptions.baseURL = config.baseURL;
|
|
}
|
|
|
|
if (config.customHeaders) {
|
|
const headers = parseCustomHeaders(config.customHeaders);
|
|
if (Object.keys(headers).length > 0) {
|
|
clientOptions.defaultHeaders = headers;
|
|
}
|
|
}
|
|
|
|
this.client = new OpenAI(clientOptions);
|
|
}
|
|
|
|
public generateCommitMessage = async (
|
|
messages: Array<OpenAI.Chat.Completions.ChatCompletionMessageParam>
|
|
): Promise<string | null> => {
|
|
const params = {
|
|
model: this.config.model,
|
|
messages,
|
|
temperature: 0,
|
|
top_p: 0.1,
|
|
max_tokens: this.config.maxTokensOutput
|
|
};
|
|
|
|
try {
|
|
const REQUEST_TOKENS = messages
|
|
.map((msg) => tokenCount(msg.content as string) + 4)
|
|
.reduce((a, b) => a + b, 0);
|
|
|
|
if (
|
|
REQUEST_TOKENS >
|
|
this.config.maxTokensInput - this.config.maxTokensOutput
|
|
)
|
|
throw new Error(GenerateCommitMessageErrorEnum.tooMuchTokens);
|
|
|
|
const completion = await this.client.chat.completions.create(params);
|
|
|
|
const message = completion.choices[0].message;
|
|
let content = message?.content;
|
|
return removeContentTags(content, 'think');
|
|
} catch (error) {
|
|
const err = error as Error;
|
|
if (
|
|
axios.isAxiosError<{ error?: { message: string } }>(error) &&
|
|
error.response?.status === 401
|
|
) {
|
|
const openAiError = error.response.data.error;
|
|
|
|
if (openAiError) throw new Error(openAiError.message);
|
|
}
|
|
|
|
throw err;
|
|
}
|
|
};
|
|
}
|