UNPKG

ai-commit-cli

Version:

A Reactive CLI that generates git commit messages with various AI

72 lines (56 loc) 68.7 kB
#!/usr/bin/env node import{createRequire as C1}from"node:module";var v1=C1(import.meta.url);import{cli as f2}from"cleye";var M$="ai-commit-cli",i="0.0.0-semantic-release",T$="A Reactive CLI that generates git commit messages with various AI";import _1 from"node:fs";import b1 from"node:path";import{execa as w1}from"execa";import D1 from"inquirer";import q2 from"ora";import Z$ from"chalk";import{catchError as Z1,from as V$,mergeMap as J$,of as W$}from"rxjs";class w{static create($,z){return new $(z)}}import g1 from"@anthropic-ai/sdk";import p$ from"chalk";import{catchError as n$,concatMap as d$,from as g$,map as l$,of as l1}from"rxjs";import{fromPromise as m$}from"rxjs/internal/observable/innerFrom";import C$ from"chalk";var k$=M$,A$=i;class _ extends Error{}var w$=" ",F=($)=>{if(!($ instanceof Error))return;if(!($ instanceof _)){if($.stack)console.error(C$.dim($.stack.split(` `).slice(1).join(` `)));console.error(` ${w$}${C$.dim(`${k$} v${A$}`)}`),console.error(` ${w$}Please open a Bug report with the information above:`),console.error(`${w$}https://github.com/rdwz/ai-commit-cli/issues/new/choose`)}};import p from"fs";import c1 from"os";import u$ from"path";import{xxh64 as y1}from"@pacote/xxhash";var D$=u$.join(c1.homedir(),".aicommit2_log"),f1=new Date,q=($,z,Y,B,X)=>{let Z=`[${$}]`,G=P1(f1,z,X),V=`${D$}/${G}`,J=`- System Prompt ${Y}`,W=`- Response ${B}`,j=`[Git Diff] ${z}`;if(p.existsSync(V)){let U=p.readFileSync(V,"utf-8");v$(V,`${Z} ${W} ${J} ${U}`);return}v$(V,`${Z} ${W} ${J} ${j}`)},P1=($,z,Y)=>{let{year:B,month:X,day:Z,hours:G,minutes:V,seconds:J}=i1($),j=y1(0).update(z).digest("hex");if(Y==="review")return`aic2_review_${B}-${X}-${Z}_${G}-${V}-${J}_${j}.log`;return`aic2_${B}-${X}-${Z}_${G}-${V}-${J}_${j}.log`},v$=($,z="")=>{p.mkdirSync(u$.dirname($),{recursive:!0}),p.writeFileSync($,z,"utf-8")},i1=($)=>{let z=$.getFullYear().toString(),Y=($.getMonth()+1).toString().padStart(2,"0"),B=$.getDate().toString().padStart(2,"0"),X=$.getHours().toString().padStart(2,"0"),Z=$.getMinutes().toString().padStart(2,"0"),G=$.getSeconds().toString().padStart(2,"0");return{year:z,month:Y,day:B,hours:X,minutes:Z,seconds:G}};import y$ from"fs";import f$ from"path";var D={locale:"en",maxLength:50,type:"conventional",generate:1,systemPrompt:"",systemPromptPath:"",codeReviewPromptPath:""};var p1={"":"<commit message>",conventional:`<type>(<optional scope>): <description> [optional body] [optional footer(s)]`,gitmoji:`:<emoji>:(<optional scope>): <description> [optional body] [optional footer(s)]`};var n1={"":"",gitmoji:` ${Object.entries({":sparkles:":"Introduce new features.",":bug:":"Fix a bug.",":memo:":"Add or update documentation.",":art:":"Improve structure / format of the code.",":zap:":"Improve performance.",":fire:":"Remove code or files.",":ambulance:":"Critical hotfix.",":white_check_mark:":"Add, update, or pass tests.",":lock:":"Fix security or privacy issues.",":rocket:":"Deploy stuff.",":lipstick:":"Add or update the UI and style files.",":tada:":"Begin a project.",":recycle:":"Refactor code.",":wrench:":"Add or update configuration files.",":bulb:":"Add or update comments in source code.",":twisted_rightwards_arrows:":"Merge branches."}).map(([$,z])=>` - ${$}: ${z}`).join(` `)}`,conventional:` ${Object.entries({docs:"Documentation only changes",style:"Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc)",refactor:"A code change that neither fixes a bug nor adds a feature",perf:"A code change that improves performance",test:"Adding missing tests or correcting existing tests",build:"Changes that affect the build system or external dependencies",ci:"Changes to CI configuration files, scripts",chore:"Other changes that don't modify src or test files",revert:"Reverts a previous commit",feat:"A new feature",fix:"A bug fix"}).map(([$,z])=>` - ${$}: ${z}`).join(` `)}`},P$=($,z)=>{return $.replace(/{(\w+)}/g,(Y,B)=>{return z[B]?.toString()||D[B]?.toString()})},c$=($)=>{let{type:z,maxLength:Y,generate:B,locale:X}=$;return[`You are a helpful assistant specializing in writing clear and informative Git commit messages using the ${z} style`,`Based on the given code changes or context, generate exactly ${B} ${z} Git commit message${B!==1?"s":""} based on the following guidelines.`,`1. Message Language: ${X}`,`2. Format: follow the ${z} Commits format:`,`${p1[z]}`,`3. Types: use one of the following types:${n1[z]}`,"4. Exclude anything unnecessary such as translation. Your entire response will be passed directly into git commit."].filter(Boolean).join(` `)},n=($,z)=>{let Y=(B)=>{if(B==="conventional")return`${Array(z).fill(null).map((X,Z)=>` { "subject": "fix: fix bug in user authentication process", "body": "- Update login function to handle edge cases\\n- Add additional error logging for debugging", "footer": "" }`).join(",")}`;return`${Array(z).fill(null).map((X,Z)=>` { "subject": "\uD83D\uDDBC️ Add profile picture upload feature", "body": "- Implement server-side handling of file uploads\\n- Add client-side image preview and cropping", "footer": "" }`).join(",")}`};return[` Lastly, Provide your response as a JSON array containing exactly ${z} object${z!==1?"s":""}, each with the following keys:`,`- "subject": The main commit message using the ${$} style. It should be a concise summary of the changes.`,'- "body": An optional detailed explanation of the changes. If not needed, use an empty string.','- "footer": An optional footer for metadata like BREAKING CHANGES. If not needed, use an empty string.',`The array must always contain ${z} element${z!==1?"s":""}, no more and no less.`,`Example response format: [${Y($)} ]`,`Ensure you generate exactly ${z} commit message${z!==1?"s":""}, even if it requires creating slightly varied versions for similar changes.`,"The response should be valid JSON that can be parsed without errors."].filter(Boolean).join(` `)},R=($)=>{let{systemPrompt:z,systemPromptPath:Y,type:B,generate:X}=$;if(z)return`${z} ${n(B,X)}`;if(!Y)return`${c$($)} ${n(B,X)}`;try{let Z=y$.readFileSync(f$.resolve(Y),"utf-8");return`${P$(Z,$)} ${n(B,X)}`}catch(Z){return`${c$($)} ${n(B,X)}`}};var O=($)=>{let{codeReviewPromptPath:z,locale:Y}=$,B=`I'll give you the output of the "git diff" command as an input. Please review the following code and provide your feedback in Markdown format. Focus on: 1. Language: ${Y} 2. Code quality and best practices 3. Potential bugs or errors 4. Performance improvements 5. Readability and maintainability Please structure your response with appropriate Markdown headings, code blocks, and bullet points.`;if(!z)return B;try{let X=y$.readFileSync(f$.resolve(z),"utf-8");return`${P$(X,$)}`}catch(X){return B}};import{of as d1}from"rxjs";var E$=($)=>$?`${$[0].toUpperCase()}${$.slice(1)}`:$,A=($,z)=>{let Y=Math.ceil($),B=Math.floor(z);return Math.floor(Math.random()*(B-Y+1))+Y};var i$=($,z)=>{if($.disabled&&!z.disabled)return 1;if(!$.disabled&&z.disabled)return-1;return 0};var C=($)=>{return $.reduce((z,Y)=>Array.isArray(Y)?z.concat(C(Y)):z.concat(Y),[])},q$=($,z=5)=>{return $.replace(/[\n\r]/g,"").split(" ").slice(0,z).join(" ")};class E{serviceName;errorPrefix;colors;constructor($){this.serviceName="AI",this.errorPrefix="ERROR",this.colors={primary:""}}handleError$=($)=>{let z="An error occurred";if($.message)z=$.message;return d1({name:`${this.errorPrefix} ${z}`,value:z,isError:!0,disabled:!0})};parseMessage($,z,Y){try{let X=JSON.parse($).map((Z)=>this.extractMessageAsType(Z,z)).map((Z)=>{return{title:`${Z.subject}`,value:`${Z.subject}${Z.body?` ${Z.body}`:""}${Z.footer?` ${Z.footer}`:""}`}});if(X.length>Y)return X.slice(0,Y);return X}catch(B){let X=/\[[\s\S]*?\]/;try{let Z=$.match(X);if(!Z)return[];let G=Z[0],J=JSON.parse(G).map((W)=>this.extractMessageAsType(W,z)).map((W)=>{return{title:`${W.subject}`,value:`${W.subject}${W.body?` ${W.body}`:""}${W.footer?` ${W.footer}`:""}`}});if(J.length>Y)return J.slice(0,Y);return J}catch(Z){return[]}}}extractMessageAsType($,z){switch(z){case"conventional":let Y=/(\w+)(?:\(.*?\))?:\s*(.*)/,B=$.subject.match(Y),X=B?B[0]:$.subject;return{...$,subject:this.normalizeCommitMessage(X)};case"gitmoji":let Z=/:\w*:\s*(.*)/,G=$.subject.match(Z);return{...$,subject:G?G[0].toLowerCase():$.subject};default:return $}}normalizeCommitMessage($){let z=/^(\w+)(\(.*?\))?:\s(.*)$/,Y=$.match(z);if(Y){let[,B,X,Z]=Y,G=B.toLowerCase(),V=Z.charAt(0).toLowerCase()+Z.slice(1);$=`${G}${X||""}: ${V}`}return $}sanitizeResponse($){if(typeof $==="string")try{return[{title:`${q$($)}...`,value:$}]}catch(z){return[]}return $.map((z)=>{try{return{title:`${q$(z)}...`,value:z}}catch(Y){return{title:"",value:""}}})}}class d extends E{params;anthropic;constructor($){super($);this.params=$;this.colors={primary:"#AE5630",secondary:"#fff"},this.serviceName=p$.bgHex(this.colors.primary).hex(this.colors.secondary).bold("[Anthropic]"),this.errorPrefix=p$.red.bold("[Anthropic]"),this.anthropic=new g1({apiKey:this.params.config.key})}generateCommitMessage$(){return m$(this.generateMessage("commit")).pipe(d$(($)=>g$($)),l$(($)=>({name:`${this.serviceName} ${$.title}`,short:$.title,value:this.params.config.includeBody?$.value:$.title,description:this.params.config.includeBody?$.value:"",isError:!1})),n$(this.handleError$))}generateCodeReview$(){return m$(this.generateMessage("review")).pipe(d$(($)=>g$($)),l$(($)=>({name:`${this.serviceName} ${$.title}`,short:$.title,value:$.value,description:$.value,isError:!1})),n$(this.handleError$))}async generateMessage($){try{let z=this.params.stagedDiff.diff,{systemPrompt:Y,systemPromptPath:B,codeReviewPromptPath:X,logging:Z,temperature:G,locale:V,generate:J,type:W,maxLength:j,maxTokens:U,topP:H,model:b}=this.params.config,L={...D,locale:V,maxLength:j,type:W,generate:J,systemPrompt:Y,systemPromptPath:B,codeReviewPromptPath:X},K=$==="review"?O(L):R(L),I={max_tokens:U,temperature:G,system:K,messages:[{role:"user",content:`Here is the diff: ${z}`}],top_p:H,model:b},K$=(await this.anthropic.messages.create(I)).content.map(({text:A1})=>A1).join("");if(Z&&q("Anthropic",z,K,K$,$),$==="review")return this.sanitizeResponse(K$);return this.parseMessage(K$,W,J)}catch(z){let Y=z;if(Y.code==="ENOTFOUND")throw new _(`Error connecting to ${Y.hostname} (${Y.syscall})`);throw Y}}handleError$=($)=>{let z=$.error?.error?.message?.replace(/(\r\n|\n|\r)/gm,"")||"An error occurred";return l1({name:`${this.errorPrefix} ${z}`,value:z,isError:!0,disabled:!0})}}import t$ from"chalk";import{catchError as o$,concatMap as s$,from as r$,map as a$,of as t1}from"rxjs";import{fromPromise as e$}from"rxjs/internal/observable/innerFrom";import m1 from"axios";class h{axiosInstance;config;constructor($={}){if(!$.method)throw new Error("method should be defined!");if(!$.baseURL)throw new Error("baseURL should be defined!");this.config={...$},this.axiosInstance=m1.create(this.config)}setHeaders($){return this.config.headers=$,this}setParams($){return this.config.params=$,this}setBody($){return this.config.data=$,this}addBody($){return this.config.data={...this.config.data,...$},this}setMethod($){return this.config.method=$,this}async execute(){try{return await this.axiosInstance.request(this.config)}catch($){throw $}}}class g extends E{params;host="https://codestral.mistral.ai";apiKey="";constructor($){super($);this.params=$;this.colors={primary:"#e28c58",secondary:"#fff"},this.serviceName=t$.bgHex(this.colors.primary).hex(this.colors.secondary).bold("[Codestral]"),this.errorPrefix=t$.red.bold("[Codestral]"),this.apiKey=this.params.config.key}generateCommitMessage$(){return e$(this.generateMessage("commit")).pipe(s$(($)=>r$($)),a$(($)=>({name:`${this.serviceName} ${$.title}`,short:$.title,value:this.params.config.includeBody?$.value:$.title,description:this.params.config.includeBody?$.value:"",isError:!1})),o$(this.handleError$))}generateCodeReview$(){return e$(this.generateMessage("review")).pipe(s$(($)=>r$($)),a$(($)=>({name:`${this.serviceName} ${$.title}`,short:$.title,value:$.value,description:$.value,isError:!1})),o$(this.handleError$))}async generateMessage($){try{let z=this.params.stagedDiff.diff,{systemPrompt:Y,systemPromptPath:B,codeReviewPromptPath:X,logging:Z,locale:G,generate:V,type:J,maxLength:W}=this.params.config,j={...D,locale:G,maxLength:W,type:J,generate:V,systemPrompt:Y,systemPromptPath:B,codeReviewPromptPath:X},U=$==="review"?O(j):R(j);this.checkAvailableModels();let H=await this.createChatCompletions(U,$);if(Z&&q("Codestral",z,U,H,$),$==="review")return this.sanitizeResponse(H);return this.parseMessage(H,J,V)}catch(z){let Y=z;if(Y.code==="ENOTFOUND")throw new _(`Error connecting to ${Y.hostname} (${Y.syscall})`);throw Y}}handleError$=($)=>{let z=$.message?.replace(/(\r\n|\n|\r)/gm,"")||"An error occurred";return t1({name:`${this.errorPrefix} ${z}`,value:z,isError:!0,disabled:!0})};checkAvailableModels(){if(["codestral-latest","codestral-2405"].includes(this.params.config.model))return!0;throw new Error("Invalid model type of Codestral AI")}async createChatCompletions($,z){let Y=new h({method:"POST",baseURL:`${this.host}/v1/chat/completions`,timeout:this.params.config.timeout}).setHeaders({Authorization:`Bearer ${this.apiKey}`,"content-type":"application/json"}).setBody({model:this.params.config.model,messages:[{role:"system",content:$},{role:"user",content:`Here is the diff: ${this.params.stagedDiff.diff}`}],temperature:this.params.config.temperature,top_p:this.params.config.topP,max_tokens:this.params.config.maxTokens,stream:!1,safe_prompt:!1,random_seed:A(10,1000)});if(z==="commit")Y.addBody({response_format:{type:"json_object"}});let X=(await Y.execute()).data;if(!X.choices||X.choices.length===0||!X.choices[0].message?.content)throw new Error("No Content on response. Please open a Bug report");return X.choices[0].message.content}}import $0 from"chalk";import{CohereClient as o1,CohereTimeoutError as s1}from"cohere-ai";import{catchError as z0,concatMap as Y0,from as B0,map as Q0,of as r1}from"rxjs";import{fromPromise as X0}from"rxjs/internal/observable/innerFrom";class l extends E{params;cohere;constructor($){super($);this.params=$;this.colors={primary:"#D18EE2",secondary:"#fff"},this.serviceName=$0.bgHex(this.colors.primary).hex(this.colors.secondary).bold("[Cohere]"),this.errorPrefix=$0.red.bold("[Cohere]"),this.cohere=new o1({token:this.params.config.key})}generateCommitMessage$(){return X0(this.generateMessage("commit")).pipe(Y0(($)=>B0($)),Q0(($)=>({name:`${this.serviceName} ${$.title}`,short:$.title,value:this.params.config.includeBody?$.value:$.title,description:this.params.config.includeBody?$.value:"",isError:!1})),z0(this.handleError$))}generateCodeReview$(){return X0(this.generateMessage("review")).pipe(Y0(($)=>B0($)),Q0(($)=>({name:`${this.serviceName} ${$.title}`,short:$.title,value:$.value,description:$.value,isError:!1})),z0(this.handleError$))}async generateMessage($){try{let z=this.params.stagedDiff.diff,{systemPrompt:Y,systemPromptPath:B,codeReviewPromptPath:X,logging:Z,temperature:G,locale:V,generate:J,type:W,maxLength:j,maxTokens:U,topP:H,model:b}=this.params.config,L={...D,locale:V,maxLength:j,type:W,generate:J,systemPrompt:Y,systemPromptPath:B,codeReviewPromptPath:X},K=$==="review"?O(L):R(L),I=await this.cohere.chat({chatHistory:K?[{role:"SYSTEM",message:K}]:[],message:`Here is the diff: ${z}`,connectors:[{id:"web-search"}],maxTokens:U,temperature:G,model:this.params.config.model,seed:A(10,1000),p:this.params.config.topP});if(Z&&q("Cohere",z,K,I.text,$),$==="review")return this.sanitizeResponse(I.text);return this.parseMessage(I.text,W,J)}catch(z){let Y=z;if(Y instanceof s1)throw new _("Request timed out error!");throw Y}}handleError$=($)=>{let z=/"message":\s*"([^"]*)"/,Y=$.message.match(z),B=$?.body?.message;if(Y?.[1])B=Y[1];let X=`${$.statusCode} ${B}`;return r1({name:`${this.errorPrefix} ${X}`,value:B,isError:!0,disabled:!0})}}import Z0 from"chalk";import a1 from"openai";import{catchError as V0,concatMap as J0,from as W0,map as G0,of as e1}from"rxjs";import{fromPromise as U0}from"rxjs/internal/observable/innerFrom";class m extends E{params;host="https://api.deepseek.com";deepSeek;constructor($){super($);this.params=$;this.colors={primary:"#53a3f9",secondary:"#fff"},this.serviceName=Z0.bgHex(this.colors.primary).hex(this.colors.secondary).bold("[DeepSeek]"),this.errorPrefix=Z0.red.bold("[DeepSeek]"),this.deepSeek=new a1({baseURL:this.host,apiKey:this.params.config.key})}generateCommitMessage$(){return U0(this.generateMessage("commit")).pipe(J0(($)=>W0($)),G0(($)=>({name:`${this.serviceName} ${$.title}`,short:$.title,value:this.params.config.includeBody?$.value:$.title,description:this.params.config.includeBody?$.value:"",isError:!1})),V0(this.handleError$))}generateCodeReview$(){return U0(this.generateMessage("review")).pipe(J0(($)=>W0($)),G0(($)=>({name:`${this.serviceName} ${$.title}`,short:$.title,value:$.value,description:$.value,isError:!1})),V0(this.handleError$))}async generateMessage($){try{let z=this.params.stagedDiff.diff,{systemPrompt:Y,systemPromptPath:B,codeReviewPromptPath:X,logging:Z,locale:G,generate:V,type:J,maxLength:W}=this.params.config,j={...D,locale:G,maxLength:W,type:J,generate:V,systemPrompt:Y,systemPromptPath:B,codeReviewPromptPath:X},U=$==="review"?O(j):R(j);this.checkAvailableModels();let H=await this.createChatCompletions(U,$);if(Z&&q("DeepSeek",z,U,H,$),$==="review")return this.sanitizeResponse(H);return this.parseMessage(H,J,V)}catch(z){let Y=z;if(Y.code==="ENOTFOUND")throw new _(`Error connecting to ${Y.hostname} (${Y.syscall})`);throw Y}}handleError$=($)=>{let z=$.message?.replace(/(\r\n|\n|\r)/gm,"")||"An error occurred";return e1({name:`${this.errorPrefix} ${z}`,value:z,isError:!0,disabled:!0})};checkAvailableModels(){if(["deepseek-coder","deepseek-chat"].includes(this.params.config.model))return!0;throw new Error("Invalid model type of DeepSeek")}async createChatCompletions($,z){return(await this.deepSeek.chat.completions.create({messages:[{role:"system",content:$},{role:"user",content:`Here is the diff: ${this.params.stagedDiff.diff}`}],model:this.params.config.model,max_tokens:this.params.config.maxTokens,top_p:this.params.config.topP,temperature:this.params.config.temperature},{timeout:this.params.config.timeout})).choices[0].message.content||""}}import{GoogleGenerativeAI as $2,HarmBlockThreshold as t,HarmCategory as o}from"@google/generative-ai";import H0 from"chalk";import{catchError as j0,concatMap as L0,from as _0,map as b0,of as z2}from"rxjs";import{fromPromise as K0}from"rxjs/internal/observable/innerFrom";class s extends E{params;genAI;constructor($){super($);this.params=$;this.colors={primary:"#0077FF",secondary:"#fff"},this.serviceName=H0.bgHex(this.colors.primary).hex(this.colors.secondary).bold("[Gemini]"),this.errorPrefix=H0.red.bold("[Gemini]"),this.genAI=new $2(this.params.config.key)}generateCommitMessage$(){return K0(this.generateMessage("commit")).pipe(L0(($)=>_0($)),b0(($)=>({name:`${this.serviceName} ${$.title}`,short:$.title,value:this.params.config.includeBody?$.value:$.title,description:this.params.config.includeBody?$.value:"",isError:!1})),j0(this.handleError$))}generateCodeReview$(){return K0(this.generateMessage("review")).pipe(L0(($)=>_0($)),b0(($)=>({name:`${this.serviceName} ${$.title}`,short:$.title,value:$.value,description:$.value,isError:!1})),j0(this.handleError$))}async generateMessage($){try{let z=this.params.stagedDiff.diff,{systemPrompt:Y,systemPromptPath:B,logging:X,locale:Z,codeReviewPromptPath:G,generate:V,type:J,maxLength:W}=this.params.config,j=this.params.config.maxTokens,U={...D,locale:Z,maxLength:W,type:J,generate:V,systemPrompt:Y,systemPromptPath:B,codeReviewPromptPath:G},H=$==="review"?O(U):R(U),b={maxOutputTokens:j,temperature:this.params.config.temperature,topP:this.params.config.topP},k=(await this.genAI.getGenerativeModel({model:this.params.config.model,systemInstruction:H,generationConfig:b,safetySettings:[{category:o.HARM_CATEGORY_HATE_SPEECH,threshold:t.BLOCK_LOW_AND_ABOVE},{category:o.HARM_CATEGORY_SEXUALLY_EXPLICIT,threshold:t.BLOCK_LOW_AND_ABOVE},{category:o.HARM_CATEGORY_HARASSMENT,threshold:t.BLOCK_LOW_AND_ABOVE},{category:o.HARM_CATEGORY_DANGEROUS_CONTENT,threshold:t.BLOCK_LOW_AND_ABOVE}]}).generateContent(`Here is the diff: ${z}`)).response.text();if(X&&q("Gemini",z,H,k,$),$==="review")return this.sanitizeResponse(k);return this.parseMessage(k,J,V)}catch(z){let Y=z;if(Y.code==="ENOTFOUND")throw new _(`Error connecting to ${Y.hostname} (${Y.syscall})`);throw Y}}handleError$=($)=>{let z=$.message||$.toString(),Y=/(\[.*?\]\s*[^[]*)/g,B=[...z.matchAll(Y)],X=[];B.forEach((G)=>X.push(G[1]));let Z=X[1]||"An error occurred";return z2({name:`${this.errorPrefix} ${Z}`,value:Z,isError:!0,disabled:!0})}}import N0 from"chalk";import w0 from"groq-sdk";import{catchError as D0,concatMap as E0,from as q0,map as R0,of as Y2}from"rxjs";import{fromPromise as O0}from"rxjs/internal/observable/innerFrom";class r extends E{params;groq;constructor($){super($);this.params=$;this.colors={primary:"#f55036",secondary:"#fff"},this.serviceName=N0.bgHex(this.colors.primary).hex(this.colors.secondary).bold("[Groq]"),this.errorPrefix=N0.red.bold("[Groq]"),this.groq=new w0({apiKey:this.params.config.key})}generateCommitMessage$(){return O0(this.generateMessage("commit")).pipe(E0(($)=>q0($)),R0(($)=>({name:`${this.serviceName} ${$.title}`,short:$.title,value:this.params.config.includeBody?$.value:$.title,description:this.params.config.includeBody?$.value:"",isError:!1})),D0(this.handleError$))}generateCodeReview$(){return O0(this.generateMessage("review")).pipe(E0(($)=>q0($)),R0(($)=>({name:`${this.serviceName} ${$.title}`,short:$.title,value:$.value,description:$.value,isError:!1})),D0(this.handleError$))}async generateMessage($){try{let z=this.params.stagedDiff.diff,{systemPrompt:Y,systemPromptPath:B,codeReviewPromptPath:X,logging:Z,locale:G,temperature:V,generate:J,type:W,maxLength:j}=this.params.config,U=this.params.config.maxTokens,H={...D,locale:G,maxLength:j,type:W,generate:J,systemPrompt:Y,systemPromptPath:B,codeReviewPromptPath:X},b=$==="review"?O(H):R(H),K=(await this.groq.chat.completions.create({messages:[{role:"system",content:b},{role:"user",content:`Here is the diff: ${z}`}],model:this.params.config.model,max_tokens:U,top_p:this.params.config.topP,temperature:V},{timeout:this.params.config.timeout})).choices[0].message.content||"";if(Z&&q("Groq",z,b,K,$),$==="review")return this.sanitizeResponse(K);return this.parseMessage(K,W,J)}catch(z){throw z}}handleError$=($)=>{let z="N/A",Y="An error occurred";if($ instanceof w0.APIError)z=`${$.status}`,Y=$.name;let B=`${z} ${Y}`;return Y2({name:`${this.errorPrefix} ${B}`,value:Y,isError:!0,disabled:!0})}}import I0 from"chalk";import{catchError as S0,concatMap as x0,from as F0,map as h0}from"rxjs";import{fromPromise as M0}from"rxjs/internal/observable/innerFrom";class a extends E{params;headers={accept:"*/*","accept-language":"en-US,en;q=0.9","sec-ch-ua":'"Chromium";v="116", "Not)A;Brand";v="24", "Google Chrome";v="116"',"sec-ch-ua-mobile":"?0","sec-ch-ua-platform":'"Windows"',"sec-fetch-dest":"empty","sec-fetch-mode":"cors","sec-fetch-site":"same-origin",origin:"https://huggingface.co","Referrer-Policy":"strict-origin-when-cross-origin"};models=[];currentModel;currentModelId=null;currentConversation=void 0;currentConversionID=void 0;cookie="";constructor($){super($);this.params=$;this.colors={primary:"#FED21F",secondary:"#000"},this.serviceName=I0.bgHex(this.colors.primary).hex(this.colors.secondary).bold("[HuggingFace]"),this.errorPrefix=I0.red.bold("[HuggingFace]"),this.cookie=this.params.config.cookie}generateCommitMessage$(){return M0(this.generateMessage("commit")).pipe(x0(($)=>F0($)),h0(($)=>({name:`${this.serviceName} ${$.title}`,short:$.title,value:this.params.config.includeBody?$.value:$.title,description:this.params.config.includeBody?$.value:"",isError:!1})),S0(this.handleError$))}generateCodeReview$(){return M0(this.generateMessage("review")).pipe(x0(($)=>F0($)),h0(($)=>({name:`${this.serviceName} ${$.title}`,short:$.title,value:$.value,description:$.value,isError:!1})),S0(this.handleError$))}async generateMessage($){try{await this.intialize();let z=this.params.stagedDiff.diff,{systemPrompt:Y,systemPromptPath:B,codeReviewPromptPath:X,logging:Z,locale:G,generate:V,type:J,maxLength:W}=this.params.config,j={...D,locale:G,maxLength:W,type:J,generate:V,systemPrompt:Y,systemPromptPath:B,codeReviewPromptPath:X},U=$==="review"?O(j):R(j),H=await this.getNewChat(U),L=await(await this.sendMessage(`Here is the diff: ${z}`,H.id)).completeResponsePromise();if(await this.deleteConversation(H.id),Z&&q("HuggingFace",z,U,L,$),$==="review")return this.sanitizeResponse(L);return this.parseMessage(L,J,V)}catch(z){let Y=z;if(Y.code==="ENOTFOUND")throw new _(`Error connecting to ${Y.hostname} (${Y.syscall})`);throw Y}}async intialize(){let $=await this.getRemoteLlms(),z=$.find((Y)=>Y.name?.toLowerCase()===this.params.config.model.toLowerCase());if(z){this.currentModel=z,this.currentModelId=z.id;return}this.currentModel=$[0],this.currentModelId=$[0].id}async getRemoteLlms(){let $=await fetch("https://huggingface.co/chat/__data.json",{headers:{...this.headers,cookie:this.cookie},body:null,method:"GET"});if($.status!==200)throw new Error(`Failed to get remote LLMs with status code: ${$.status}`);let Y=(await $.json()).nodes[0].data,B=Y[Y[0].models],X=[],Z=(G)=>G===-1?null:Y[G];for(let G of B){let V=Y[G];if(Y[V.unlisted])continue;let J={id:Z(V.id),name:Z(V.name),displayName:Z(V.displayName),preprompt:Z(V.preprompt),promptExamples:[],websiteUrl:Z(V.websiteUrl),description:Z(V.description),datasetName:Z(V.datasetName),datasetUrl:Z(V.datasetUrl),modelUrl:Z(V.modelUrl),parameters:{}},W=Z(V.promptExamples);if(W!==null){let H=W.map((b)=>Z(b));J.promptExamples=H.map((b)=>({title:Y[b.title],prompt:Y[b.prompt]}))}let j=Z(V.parameters),U={};for(let[H,b]of Object.entries(j)){if(b===-1){U[H]=null;continue}if(Array.isArray(Y[b])){U[H]=Y[b].map((L)=>Y[L]);continue}U[H]=Y[b]}J.parameters=U,X.push(J)}return this.models=X,X}async getNewChat($){let z={model:this.currentModelId,preprompt:$},Y=0;while(Y<5){let B=await fetch("https://huggingface.co/chat/conversation",{headers:{...this.headers,"content-type":"application/json",cookie:this.cookie,Referer:"https://huggingface.co/chat/"},body:JSON.stringify(z),method:"POST"}),{conversationId:X}=await B.json();if(X){this.currentConversionID=X;break}else Y++}if(!this.currentConversionID)throw new Error("Failed to create new conversion");return await this.getConversationHistory(this.currentConversionID)}async getConversationHistory($){if(!$)throw new Error("conversationId is required for getConversationHistory");let z=await fetch(`https://huggingface.co/chat/conversation/${$}/__data.json`,{headers:{...this.headers,cookie:this.cookie,Referer:"https://huggingface.co/chat/"},body:null,method:"GET"});if(z.status!==200)throw new Error(`Unable get conversation details ${z}`);let Y=await z.json();return this.metadataParser(Y,$)}metadataParser($,z){let Y={id:"",model:"",systemPrompt:"",title:"",history:[]},B=$.nodes[1].data,X=B[B[0].model],Z=B[B[0].preprompt],G=B[B[0].title],V=B[B[0].messages],J=[];for(let W of V){let j=B[W],U=new Date(B[j.createdAt][1]).getTime()/1000,H=new Date(B[j.updatedAt][1]).getTime()/1000;J.push({id:B[j.id],role:B[j.from],content:B[j.content],createdAt:U,updatedAt:H})}return Y.id=z,Y.model=X,Y.systemPrompt=Z,Y.title=G,Y.history=J,this.currentConversation=Y,Y}async sendMessage($,z){if($==="")throw new Error("the prompt can not be empty.");if(!z&&!this.currentConversionID)await this.getNewChat();else if(z)this.currentConversionID=z,await this.getConversationHistory(z);else if(this.currentConversionID)await this.getConversationHistory(this.currentConversionID);if(!this.currentConversation)throw new Error("Failed to create new conversion");let Y={inputs:$,id:this.currentConversation.history[this.currentConversation.history.length-1].id,is_retry:!1,is_continue:!1,web_search:!1,tools:[]},B=new FormData;B.append("data",JSON.stringify(Y));let X=await fetch(`https://huggingface.co/chat/conversation/${this.currentConversionID}`,{headers:{...this.headers,cookie:this.cookie,Referer:`https://huggingface.co/chat/conversation/${this.currentConversionID}`},body:B,method:"POST"});function Z(U){try{let H=U.split(` `),b=[];for(let L of H)if(L.trim())b.push(JSON.parse(L));return b}catch(H){return[{}]}}let G=new TextDecoder,V="",J=new TransformStream({async transform(U,H){let b=G.decode(U);try{let L=Z(b);for(let K of L)if(K.type==="finalAnswer")V=K?.text||"",H.terminate();else if(K.type==="stream")H.enqueue(K?.token||"")}catch{throw new Error("Error during parsing response")}}}),W=X.body?.pipeThrough(J);async function j(){return new Promise(async(U,H)=>{try{if(!W)H("ModifiedStream undefined");else{let b=W.getReader();while(!0){let{done:L,value:K}=await b.read();if(L){U(V);break}}}}catch(b){H(b)}})}return{id:this.currentConversionID,stream:W,completeResponsePromise:j}}async deleteConversation($){return(await fetch(`https://huggingface.co/chat/conversation/${$}`,{headers:{...this.headers,cookie:this.cookie,Referer:"https://huggingface.co/chat/"},body:null,method:"DELETE"})).json()}}import T0 from"chalk";import{catchError as k0,concatMap as A0,from as C0,map as v0,of as B2}from"rxjs";import{fromPromise as u0}from"rxjs/internal/observable/innerFrom";class e extends E{params;host="https://api.mistral.ai";apiKey="";constructor($){super($);this.params=$;this.colors={primary:"#ff7000",secondary:"#fff"},this.serviceName=T0.bgHex(this.colors.primary).hex(this.colors.secondary).bold("[MistralAI]"),this.errorPrefix=T0.red.bold("[MistralAI]"),this.apiKey=this.params.config.key}generateCommitMessage$(){return u0(this.generateMessage("commit")).pipe(A0(($)=>C0($)),v0(($)=>({name:`${this.serviceName} ${$.title}`,short:$.title,value:this.params.config.includeBody?$.value:$.title,description:this.params.config.includeBody?$.value:"",isError:!1})),k0(this.handleError$))}generateCodeReview$(){return u0(this.generateMessage("review")).pipe(A0(($)=>C0($)),v0(($)=>({name:`${this.serviceName} ${$.title}`,short:$.title,value:$.value,description:$.value,isError:!1})),k0(this.handleError$))}async generateMessage($){try{let z=this.params.stagedDiff.diff,{systemPrompt:Y,systemPromptPath:B,codeReviewPromptPath:X,logging:Z,locale:G,generate:V,type:J,maxLength:W}=this.params.config,j={...D,locale:G,maxLength:W,type:J,generate:V,systemPrompt:Y,systemPromptPath:B,codeReviewPromptPath:X},U=$==="review"?O(j):R(j);await this.checkAvailableModels();let H=await this.createChatCompletions(U,`Here is the diff: ${z}`);if(Z&&q("MistralAI",z,U,H,$),$==="review")return this.sanitizeResponse(H);return this.parseMessage(H,J,V)}catch(z){let Y=z;if(Y.code==="ENOTFOUND")throw new _(`Error connecting to ${Y.hostname} (${Y.syscall})`);throw Y}}handleError$=($)=>{let z=$.message?.replace(/(\r\n|\n|\r)/gm,"")||"An error occurred";return B2({name:`${this.errorPrefix} ${z}`,value:z,isError:!0,disabled:!0})};async checkAvailableModels(){if((await this.getAvailableModels()).includes(this.params.config.model))return!0;throw new Error(`Invalid model type of Mistral AI: ${this.params.config.model}`)}async getAvailableModels(){return(await new h({method:"GET",baseURL:`${this.host}/v1/models`,timeout:this.params.config.timeout}).setHeaders({Authorization:`Bearer ${this.apiKey}`,"content-type":"application/json"}).execute()).data.data.filter((z)=>z.object==="model").map((z)=>z.id)}async createChatCompletions($,z){let B=(await new h({method:"POST",baseURL:`${this.host}/v1/chat/completions`,timeout:this.params.config.timeout}).setHeaders({Authorization:`Bearer ${this.apiKey}`,"content-type":"application/json"}).setBody({model:this.params.config.model,messages:[{role:"system",content:$},{role:"user",content:z}],temperature:this.params.config.temperature,top_p:this.params.config.topP,max_tokens:this.params.config.maxTokens,stream:!1,safe_prompt:!1,random_seed:A(10,1000)}).execute()).data;if(!B.choices||B.choices.length===0||!B.choices[0].message?.content)throw new Error("No Content on response. Please open a Bug report");return B.choices[0].message.content}}import{Ollama as G2}from"@tak-bro/ollama";import f0 from"chalk";import{catchError as P0,concatMap as i0,from as p0,map as n0,of as d0}from"rxjs";import{fromPromise as g0}from"rxjs/internal/observable/innerFrom";import X2 from"node:os";import Z2 from"node:path";import R$ from"node:fs/promises";import O$ from"ini";import Q2 from"fs/promises";var $$=($)=>Q2.lstat($).then(()=>!0,()=>!1);var V2=["","conventional","gitmoji"],Y$="http://localhost:11434",{hasOwnProperty:J2}=Object.prototype,y=($,z)=>J2.call($,z),u=["OPENAI","OLLAMA","HUGGINGFACE","GEMINI","ANTHROPIC","MISTRAL","CODESTRAL","COHERE","GROQ","PERPLEXITY","DEEPSEEK"],N=($,z,Y)=>{if(!z)throw new _(`Invalid config property ${$}: ${Y}`)},Q={systemPrompt($){if(!$)return"";return $},systemPromptPath($){if(!$)return"";return $},codeReviewPromptPath($){if(!$)return"";return $},timeout($){if(!$)return 1e4;N("timeout",/^\d+$/.test($),"Must be an integer");let z=Number($);return N("timeout",z>=500,"Must be greater than 500ms"),z},temperature($){if(!$)return 0.7;N("temperature",/^(2|\d)(\.\d{1,2})?$/.test($),"Must be decimal between 0 and 2");let z=Number($);return N("temperature",z>0,"Must be greater than 0"),N("temperature",z<=2,"Must be less than or equal to 2"),z},maxTokens($){if(!$)return 1024;return N("maxTokens",/^\d+$/.test($),"Must be an integer"),Number($)},logging($){if(typeof $==="boolean")return $;if($===void 0||$===null)return!0;return N("logging",/^(?:true|false)$/.test($),"Must be a boolean(true or false)"),$==="true"},locale($){if(!$)return"en";return N("locale",$,"Cannot be empty"),N("locale",/^[a-z-]+$/i.test($),"Must be a valid locale (letters and dashes/underscores). You can consult the list of codes in: https://wikipedia.org/wiki/List_of_ISO_639-1_codes"),$},generate($){if(!$)return 1;N("generate",/^\d+$/.test($),"Must be an integer");let z=Number($);return N("generate",z>0,"Must be greater than 0"),N("generate",z<=5,"Must be less or equal to 5"),z},type($){if(!$)return"conventional";return N("type",V2.includes($),"Invalid commit type"),$},maxLength($){if(!$)return 50;N("maxLength",/^\d+$/.test($),"Must be an integer");let z=Number($);return N("maxLength",z>=20,"Must be greater than 20 characters"),z},includeBody($){if(typeof $==="boolean")return $;if($===void 0||$===null)return!1;return N("includeBody",/^(?:true|false)$/.test($),"Must be a boolean(true or false)"),$==="true"},exclude:($)=>{if(!$)return[];return(typeof $==="string"?$?.split(","):$).map((Y)=>Y.trim()).filter((Y)=>!!Y&&Y.length>0)},topP:($)=>{if(!$)return 0.9;N("topP",/^(1|\d)(\.\d{1,2})?$/.test($),"Must be decimal between 0 and 1");let z=Number($);return N("topP",z>0,"Must be greater than 0"),N("topP",z<=1,"Must be less than or equal to 1"),z},codeReview($){if(typeof $==="boolean")return $;if($===void 0||$===null)return!1;return N("codeReview",/^(?:true|false)$/.test($),"Must be a boolean(true or false)"),$==="true"},disabled($){if(typeof $==="boolean")return $;if($===void 0||$===null)return!1;return N("disabled",/^(?:true|false)$/.test($),"Must be a boolean(true or false)"),$==="true"}},v={OPENAI:{key:($)=>$||"",model:($)=>$||"gpt-4o-mini",url:($)=>{if(!$)return"https://api.openai.com";return N("OPENAI.url",/^https?:\/\//.test($),"Must be a valid URL"),$},path:($)=>$||"/v1/chat/completions",proxy:($)=>$||"",topP:Q.topP,systemPrompt:Q.systemPrompt,systemPromptPath:Q.systemPromptPath,codeReviewPromptPath:Q.codeReviewPromptPath,timeout:Q.timeout,temperature:Q.temperature,maxTokens:Q.maxTokens,logging:Q.logging,locale:Q.locale,generate:Q.generate,type:Q.type,maxLength:Q.maxLength,includeBody:Q.includeBody,codeReview:Q.codeReview,disabled:Q.disabled},HUGGINGFACE:{cookie:($)=>$||"",model:($)=>{if(!$)return"CohereForAI/c4ai-command-r-plus";return N("HUGGINGFACE.model",["CohereForAI/c4ai-command-r-plus","meta-llama/Meta-Llama-3-70B-Instruct","HuggingFaceH4/zephyr-orpo-141b-A35b-v0.1","mistralai/Mixtral-8x7B-Instruct-v0.1","NousResearch/Nous-Hermes-2-Mixtral-8x7B-DPO","01-ai/Yi-1.5-34B-Chat","mistralai/Mistral-7B-Instruct-v0.2","microsoft/Phi-3-mini-4k-instruct"].includes($),"Invalid model type of HuggingFace chat"),$},systemPrompt:Q.systemPrompt,systemPromptPath:Q.systemPromptPath,codeReviewPromptPath:Q.codeReviewPromptPath,logging:Q.logging,locale:Q.locale,generate:Q.generate,type:Q.type,maxLength:Q.maxLength,includeBody:Q.includeBody,codeReview:Q.codeReview,disabled:Q.disabled},GEMINI:{key:($)=>$||"",model:($)=>{if(!$||$.length===0)return"gemini-1.5-pro";return N("GEMINI.model",["gemini-1.5-flash","gemini-1.5-pro","gemini-1.5-pro-exp-0801"].includes($),"Invalid model type of Gemini"),$},systemPrompt:Q.systemPrompt,systemPromptPath:Q.systemPromptPath,codeReviewPromptPath:Q.codeReviewPromptPath,temperature:Q.temperature,maxTokens:Q.maxTokens,logging:Q.logging,locale:Q.locale,generate:Q.generate,type:Q.type,maxLength:Q.maxLength,includeBody:Q.includeBody,topP:Q.topP,codeReview:Q.codeReview,disabled:Q.disabled},ANTHROPIC:{key:($)=>$||"",model:($)=>{if(!$||$.length===0)return"claude-3-haiku-20240307";return N("ANTHROPIC.model",["claude-3-haiku-20240307","claude-3-sonnet-20240229","claude-3-opus-20240229","claude-3-opus-latest","claude-3-5-sonnet-20240620","claude-3-5-sonnet-20241022","claude-3-5-sonnet-latest"].includes($),"Invalid model type of Anthropic"),$},systemPrompt:Q.systemPrompt,systemPromptPath:Q.systemPromptPath,codeReviewPromptPath:Q.codeReviewPromptPath,temperature:Q.temperature,maxTokens:Q.maxTokens,logging:Q.logging,locale:Q.locale,generate:Q.generate,type:Q.type,maxLength:Q.maxLength,includeBody:Q.includeBody,topP:Q.topP,codeReview:Q.codeReview,disabled:Q.disabled},MISTRAL:{key:($)=>$||"",model:($)=>{if(!$||$.length===0)return"mistral-tiny";return N("MISTRAL.model",["open-mistral-7b","mistral-tiny-2312","mistral-tiny","open-mixtral-8x7b","mistral-small-2312","mistral-small","mistral-small-2402","mistral-small-latest","mistral-medium-latest","mistral-medium-2312","mistral-medium","mistral-large-latest","mistral-large-2402","mistral-embed"].includes($),"Invalid model type of Mistral AI"),$},systemPrompt:Q.systemPrompt,systemPromptPath:Q.systemPromptPath,codeReviewPromptPath:Q.codeReviewPromptPath,timeout:Q.timeout,temperature:Q.temperature,maxTokens:Q.maxTokens,logging:Q.logging,locale:Q.locale,generate:Q.generate,type:Q.type,maxLength:Q.maxLength,includeBody:Q.includeBody,topP:Q.topP,codeReview:Q.codeReview,disabled:Q.disabled},CODESTRAL:{key:($)=>$||"",model:($)=>{if(!$||$.length===0)return"codestral-latest";return N("CODESTRAL.model",["codestral-latest","codestral-2405"].includes($),"Invalid model type of Codestral"),$},topP:Q.topP,systemPrompt:Q.systemPrompt,systemPromptPath:Q.systemPromptPath,codeReviewPromptPath:Q.codeReviewPromptPath,timeout:Q.timeout,temperature:Q.temperature,maxTokens:Q.maxTokens,logging:Q.logging,locale:Q.locale,generate:Q.generate,type:Q.type,maxLength:Q.maxLength,includeBody:Q.includeBody,codeReview:Q.codeReview,disabled:Q.disabled},OLLAMA:{model:($)=>{if(!$)return[];return(typeof $==="string"?$?.split(","):$).map((Y)=>Y.trim()).filter((Y)=>!!Y&&Y.length>0)},host:($)=>{if(!$)return Y$;return N("OLLAMA.host",/^https?:\/\//.test($),"Must be a valid URL"),$},timeout:($)=>{if(!$)return 1e5;N("OLLAMA.timeout",/^\d+$/.test($),"Must be an integer");let z=Number($);return N("OLLAMA.timeout",z>=500,"Must be greater than 500ms"),z},auth:($)=>$||"",key:($)=>$||"",numCtx:($)=>{if(!$)return 2048;N("OLLAMA.numCtx",/^\d+$/.test($),"Must be an integer");let z=Number($);return N("OLLAMA.numCtx",z>=2048,"Must be greater than 2048"),z},systemPrompt:Q.systemPrompt,systemPromptPath:Q.systemPromptPath,codeReviewPromptPath:Q.codeReviewPromptPath,temperature:Q.temperature,logging:Q.logging,locale:Q.locale,generate:Q.generate,type:Q.type,maxLength:Q.maxLength,includeBody:Q.includeBody,topP:Q.topP,codeReview:Q.codeReview,disabled:Q.disabled},COHERE:{key:($)=>$||"",model:($)=>{if(!$||$.length===0)return"command";return N("COHERE.model",["command","command-nightly","command-light","command-light-nightly"].includes($),"Invalid model type of Cohere"),$},systemPrompt:Q.systemPrompt,systemPromptPath:Q.systemPromptPath,codeReviewPromptPath:Q.codeReviewPromptPath,temperature:Q.temperature,maxTokens:Q.maxTokens,logging:Q.logging,locale:Q.locale,generate:Q.generate,type:Q.type,maxLength:Q.maxLength,includeBody:Q.includeBody,topP:Q.topP,codeReview:Q.codeReview,disabled:Q.disabled},GROQ:{key:($)=>$||"",model:($)=>{if(!$||$.length===0)return"gemma2-9b-it";return N("GROQ.model",["llama3-groq-70b-8192-tool-use-preview","distil-whisper-large-v3-en","llama3-70b-8192","llama-3.2-11b-vision-preview","whisper-large-v3-turbo","gemma-7b-it","llama3-groq-8b-8192-tool-use-preview","llama-3.2-1b-preview","llama-3.1-8b-instant","mixtral-8x7b-32768","llama-3.2-90b-text-preview","llama3-8b-8192","llama-guard-3-8b","llama-3.2-90b-vision-preview","llama-3.2-11b-text-preview","llama-3.2-3b-preview","llava-v1.5-7b-4096-preview","whisper-large-v3","llama-3.1-70b-versatile","gemma2-9b-it"].includes($),"Invalid model type of Groq"),$},systemPrompt:Q.systemPrompt,systemPromptPath:Q.systemPromptPath,codeReviewPromptPath:Q.codeReviewPromptPath,timeout:Q.timeout,temperature:Q.temperature,maxTokens:Q.maxTokens,logging:Q.logging,locale:Q.locale,generate:Q.generate,type:Q.type,maxLength:Q.maxLength,includeBody:Q.includeBody,topP:Q.topP,codeReview:Q.codeReview,disabled:Q.disabled},PERPLEXITY:{key:($)=>$||"",model:($)=>{if(!$||$.length===0)return"llama-3.1-sonar-small-128k-chat";return N("PERPLEXITY.model",["llama-3.1-sonar-small-128k-online","llama-3.1-sonar-small-128k-chat","llama-3.1-sonar-large-128k-online","llama-3.1-sonar-large-128k-chat","llama-3.1-8b-instruct","llama-3.1-70b-instruct"].includes($),"Invalid model type of Perplexity"),$},topP:Q.topP,systemPrompt:Q.systemPrompt,systemPromptPath:Q.systemPromptPath,codeReviewPromptPath:Q.codeReviewPromptPath,timeout:Q.timeout,temperature:Q.temperature,maxTokens:Q.maxTokens,logging:Q.logging,locale:Q.locale,generate:Q.generate,type:Q.type,maxLength:Q.maxLength,includeBody:Q.includeBody,codeReview:Q.codeReview,disabled:Q.disabled},DEEPSEEK:{key:($)=>$||"",model:($)=>{if(!$||$.length===0)return"deepseek-coder";return N("DEEPSEEK.model",["deepseek-coder","deepseek-chat"].includes($),"Invalid model type of DeepSeek"),$},topP:Q.topP,systemPrompt:Q.systemPrompt,systemPromptPath:Q.systemPromptPath,codeReviewPromptPath:Q.codeReviewPromptPath,timeout:Q.timeout,temperature:Q.temperature,maxTokens:Q.maxTokens,logging:Q.logging,locale:Q.locale,generate:Q.generate,type:Q.type,maxLength:Q.maxLength,includeBody:Q.includeBody,codeReview:Q.codeReview,disabled:Q.disabled}},z$=Z2.join(X2.homedir(),".aicommit2"),W2=($=[])=>{let z={};for(let Y of $)if(Y.startsWith("--")){let[B,X]=Y.slice(2).split("="),[Z,G]=B.split(".");if(Z&&G&&Z in v){if(!z[Z])z[Z]={};z[Z][G]=X}else z[B]=X}return z},I$=async()=>{if(!await $$(z$))return Object.create(null);let z=await R$.readFile(z$,"utf8"),Y=O$.parse(z);if(y(Y,"OLLAMA")&&y(Y.OLLAMA,"model"))Y={...Y,OLLAMA:{...Y.OLLAMA,model:typeof Y.OLLAMA.model==="string"?[Y.OLLAMA.model]:Y.OLLAMA.model}};if(y(Y,"exclude"))Y={...Y,exclude:typeof Y.exclude==="string"?[Y.exclude]:Y.exclude};return Y},c=async($,z=[])=>{let Y=await I$(),B=W2(z),X={...$,...B},Z={},G=(V,J)=>{let W=X[`${V}.${J}`]??X[V]?.[J],j=Y[V]?.[J],U=X[J]??Y[J];return W!==void 0?W:j!==void 0?j:U};for(let[V,J]of Object.entries(Q)){let W=X[V]??Y[V];Z[V]=J(W)}for(let[V,J]of Object.entries(v)){Z[V]={};for(let[W,j]of Object.entries(J)){let U=G(V,W);Z[V][W]=j(U)}}return Z},c0=async($)=>{let z=await I$();for(let[Y,B]of $){let[X,Z]=Y.split(".");if(X in v){if(!z[X])z[X]={};let G=v[X][Z];if(!G)throw new _(`Invalid config property: ${Y}`);z[X][Z]=G(B)}else{let G=Q[Y];if(!G)throw new _(`Invalid config property: ${Y}`);z[Y]=G(B)}}await R$.writeFile(z$,O$.stringify(z),"utf8")},y0=async($)=>{let z=await I$();for(let[Y,B]of $){let[X,Z]=Y.split(".");if(X in v){if(!z[X])z[X]={};let G=X==="OLLAMA"&&Z==="model",V=v[X][Z];if(!V||!G)throw new _(`Invalid config property: ${Y}. Only supports OLLAMA.model`);let J=z[X][Z]||[];z[X][Z]=C([...J,V(B)])}else throw new _(`Invalid config property: ${Y}. Only supports OLLAMA.model`)}await R$.writeFile(z$,O$.stringify(z),"utf8")};class B$ extends E{params;host=Y$;model="";key="";ollama;constructor($){super($);this.params=$;this.colors={primary:"#FFF",secondary:"#000"},this.model=this.params.keyName,this.serviceName=f0.bgHex(this.colors.primary).hex(this.colors.secondary).bold(`[${E$(this.model)}]`),this.errorPrefix=f0.red.bold(`[${E$(this.model)}]`),this.host=this.params.config.host||Y$,this.auth=this.params.config.auth||"Bearer",this.key=this.params.config.key||"",this.ollama=new G2({host:this.host,...this.key&&{headers:{Authorization:`${this.auth} ${this.key}`}}})}generateCommitMessage$(){return g0(this.generateMessage("commit")).pipe(i0(($)=>p0($)),n0(($)=>({name:`${this.serviceName} ${$.title}`,short:$.title,value:this.params.config.includeBody?$.value:$.title,description:this.params.config.includeBody?$.value:"",isError:!1})),P0(this.handleError$))}generateCodeReview$(){return g0(this.generateMessage("review")).pipe(i0(($)=>p0($)),n0(($)=>({name:`${this.serviceName} ${$.title}`,short:$.title,value:$.value,description:$.value,isError:!1})),P0(this.handleError$))}handleError$=($)=>{if(!!$.response&&$.response.data?.error)return d0({name:`${this.errorPrefix} ${$.response.data?.error}`,value:$.response.data?.error,isError:!0,disabled:!0});let z=$.message?.replace(/(\r\n|\n|\r)/gm,"")||"An error occurred";return d0({name:`${this.errorPrefix} ${z}`,value:z,isError:!0,disabled:!0})};async generateMessage($){try{let z=this.params.stagedDiff.diff,{systemPrompt:Y,systemPromptPath:B,codeReviewPromptPath:X,logging:Z,locale:G,generate:V,type:J,maxLength:W}=this.params.config,j={...D,locale:G,maxLength:W,type:J,generate:V,systemPrompt:Y,systemPromptPath:B,codeReviewPromptPath:X},U=$==="review"?O(j):R(j);await this.checkIsAvailableOllama();let H=await this.createChatCompletions(U,`Here is the diff: ${z}`);if(Z&&q(`Ollama_${this.model}`,z,U,H,$),$==="review")return this.sanitizeResponse(H);return this.parseMessage(H,J,V)}catch(z){let Y=z;if(Y.code==="ENOTFOUND")throw new _(`Error connecting to ${Y.hostname} (${Y.syscall})`);throw Y}}async checkIsAvailableOllama(){try{let $=new h({method:"GET",baseURL:`${this.host}`,timeout:this.params.config.timeout});if(this.key)$.setHeaders({Authorization:`${this.auth} ${this.key}`});return(await $.execute()).data}catch($){if($.code==="ECONNREFUSED")throw new _(`Error connecting to ${this.host}. Please run Ollama or check host`);throw $}}async createChatCompletions($,z){return(await this.ollama.chat({model:this.model,messages:[{role:"system",content:$},{role:"user",content:z}],stream:!1,options:{num_ctx:this.params.config.numCtx,temperature:this.params.config.temperature,top_p:this.params.config.topP,seed:A(10,1000)}})).message.content}}import t0 from"chalk";import{catchError as o0,concatMap as s0,from as r0,map as a0,of as b2}from"rxjs";import{fromPromise as e0}from"rxjs/internal/observable/innerFrom";import U2 from"http";import H2 from"https";import j2 from"https-proxy-agent";var L2=async($,z,Y,B,X,Z,G)=>new Promise((V,J)=>{let W=JSON.stringify(B),U=($.protocol.includes("https")?H2:U2).request({port:G?G:void 0,hostname:$.hostname,path:z,method:"POST",headers:{"Content-Type":"application/json","Content-Length":Buffer.byteLength(W),...Y},timeout:X,agent:Z?j2(Z):void 0},(H)=>{let b=[];H.on("data",(L)=>b.push(L)),H.on("end",()=>{V({request:U,response:H,data:Buffer.concat(b).toString()})})});U.on("error",J),U.on("timeout",()=>{U.destroy(),J(new _(`Time out error: request took over ${X}ms. Try increasing the \`timeout\` config`))}),U.write(W),U.end()}),_2=async($,z,Y,B,X,Z)=>{let G=new URL($),{response:V,data:J}=await L2(G,z,{Authorization:`Bearer ${Y}`},B,X,Z);if(!V.statusCode||V.statusCode<200||V.statusCode>299){let W=`OpenAI API Error: ${V.statusCode} - ${V.statusMessage}`;if(J)W+=` ${J}`;if(V.statusCode===500)W+=` Check the API status: https://status.openai.com`;throw new _(W)}return JSON.parse(J)},l0=($)=>$.trim(),m0=async($,z,Y,B,X,Z,G,V,J,W,j,U,H)=>{try{let b={model:B,messages:[{role:"system",content:W},{role:"user",content:`Here is the diff: ${X}`}],temperature:V,max_tokens:G,stream:!1,n:1,top_p:J,frequency_penalty:0,presence_penalty:0},L=await _2($,z,Y,b,Z,H),K=L.choices.filter((I)=>I.message?.content).map((I)=>l0(I.message.content)).join();return j&&q("OPENAI",X,W,K,U),L.choices.filter((I)=>I.message?.content).map((I)=>l0(I.message.content))}catch(b){let L=b;if(L.code==="ENOTFOUND")throw new _(`Error connecting to ${L.hostname} (${L.syscall})`);throw L}};class Q$ extends E{params;constructor($){super($);this.params=$;this.colors={primary:"#74AA9C",secondary:"#FFF"},this.serviceName=t0.bgHex(this.colors.primary).hex(this.colors.secondary).bold("[ChatGPT]"),this.errorPrefix=t0.red.bold("[ChatGPT]")}generateCommitMessage$(){return e0(this.generateMessage("commit")).pipe(s0(($)=>r0($)),a0(($)=>({name:`${this.serviceName} ${$.title}`,short:$.title,value:this.params.config.includeBody?$.value:$.title,description:this.params.config.includeBody?$.value:"",isError:!1})),o0(this.handleError$))}generateCodeReview$(){return e0(this.generateMessage("review")).pipe(s0(($)=>r0($)),a0(($)=>({name:`${this.serviceName} ${$.title}`,short:$.title,value:$.value,description:$.value,isError:!1})),o0(this.handleError$))}handleError$=($)=>{let z="An error occurred";if($.message){z=$.message.split(` `)[0];let Y=this.extractJSONFromError($.message);z+=`: ${Y.error.message}`}return b2({name:`${this.errorPrefix} ${z}`,value:z,isError:!0,disabled:!0})};extractJSONFromError($){let z=/[{[]{1}([,:{}[\]0-9.\-+Eaeflnr-u \n\r\t]|".*?")+[}\]]{1}/gis,Y=$.match(z);if(Y)return Object.assign({},...Y.map((B)=>JSON.parse(B)));return{error:{message:"Unknow