| 14 | interface AnthropicConfig extends AiEngineConfig {} |
| 15 | |
| 16 | export class AnthropicEngine implements AiEngine { |
| 17 | config: AnthropicConfig; |
| 18 | client: AnthropicClient; |
| 19 | |
| 20 | constructor(config) { |
| 21 | this.config = config; |
| 22 | const clientOptions: any = { apiKey: this.config.apiKey }; |
| 23 | |
| 24 | const proxy = config.proxy; |
| 25 | if (proxy) { |
| 26 | clientOptions.httpAgent = new HttpsProxyAgent(proxy); |
| 27 | } |
| 28 | |
| 29 | this.client = new AnthropicClient(clientOptions); |
| 30 | } |
| 31 | |
| 32 | public generateCommitMessage = async ( |
| 33 | messages: Array<OpenAI.Chat.Completions.ChatCompletionMessageParam> |
| 34 | ): Promise<string | undefined> => { |
| 35 | const systemMessage = messages.find((msg) => msg.role === 'system') |
| 36 | ?.content as string; |
| 37 | const restMessages = messages.filter( |
| 38 | (msg) => msg.role !== 'system' |
| 39 | ) as MessageParam[]; |
| 40 | |
| 41 | const params: MessageCreateParamsNonStreaming = { |
| 42 | model: this.config.model, |
| 43 | system: systemMessage, |
| 44 | messages: restMessages, |
| 45 | temperature: 0, |
| 46 | max_tokens: this.config.maxTokensOutput |
| 47 | }; |
| 48 | |
| 49 | // Anthropic rejects simultaneous temperature and top_p on Claude 4.5+ |
| 50 | if (!/claude.*-4-(?:5|[6-9])/.test(params.model)) { |
| 51 | params.top_p = 0.1; |
| 52 | } |
| 53 | |
| 54 | try { |
| 55 | const REQUEST_TOKENS = messages |
| 56 | .map((msg) => tokenCount(msg.content as string) + 4) |
| 57 | .reduce((a, b) => a + b, 0); |
| 58 | |
| 59 | if ( |
| 60 | REQUEST_TOKENS > |
| 61 | this.config.maxTokensInput - this.config.maxTokensOutput |
| 62 | ) { |
| 63 | throw new Error(GenerateCommitMessageErrorEnum.tooMuchTokens); |
| 64 | } |
| 65 | |
| 66 | const data = await this.client.messages.create(params); |
| 67 | |
| 68 | const message = data?.content[0].text; |
| 69 | let content = message; |
| 70 | return removeContentTags(content, 'think'); |
| 71 | } catch (error) { |
| 72 | throw normalizeEngineError(error, 'anthropic', this.config.model); |
| 73 | } |
nothing calls this directly
no test coverage detected
searching dependent graphs…