aicommit2 1.7.2 → 1.7.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.mjs +2 -2
- package/package.json +1 -1
package/dist/cli.mjs
CHANGED
|
@@ -31,7 +31,7 @@ ${JSON.stringify({docs:"Documentation only changes",style:"Changes that do not a
|
|
|
31
31
|
Please just generate ${r} commit messages in numbered list format without explanation.
|
|
32
32
|
Here are git diff:
|
|
33
33
|
${n}`}extractCommitMessageFromRawText(t,n){switch(t){case"conventional":const r=new RegExp(/(build|chore|ci|docs|feat|fix|perf|refactor|revert|style|test)(\(.*\))?: .*$/),o=n.match(r);return o?o[0].replace(/: (\w)/,(a,i)=>`: ${i.toLowerCase()}`):"";case"gitmoji":const u=new RegExp(/\:\w+\: (.*)$/),s=n.match(u);return s?s[0]:"";default:return n}}sanitizeMessage(t,n,r){const o=t.split(`
|
|
34
|
-
`).map(u=>u.trim().replace(/^\d+\.\s/,"")).map(u=>u.replace(/`/g,"")).map(u=>this.extractCommitMessageFromRawText(n,u)).filter(u=>!!u);return o.length>r?o.slice(0,r):o}}var Nr="1.7.
|
|
34
|
+
`).map(u=>u.trim().replace(/^\d+\.\s/,"")).map(u=>u.replace(/`/g,"")).map(u=>this.extractCommitMessageFromRawText(n,u)).filter(u=>!!u);return o.length>r?o.slice(0,r):o}}var Nr="1.7.3",ri="A Reactive CLI that generates git commit messages with various AI";class y extends Error{}const ft=" ",ve=e=>{e instanceof Error&&(e instanceof y||(e.stack&&console.error(g.dim(e.stack.split(`
|
|
35
35
|
`).slice(1).join(`
|
|
36
36
|
`))),console.error(`
|
|
37
37
|
${ft}${g.dim(`aicommit2 v${Nr}`)}`),console.error(`
|
|
@@ -52,7 +52,7 @@ ${a}`),s.statusCode===500&&(i+=`
|
|
|
52
52
|
|
|
53
53
|
Check the API status: https://status.openai.com`),new y(i)}return JSON.parse(a)},Pi=e=>e.trim().replace(/[\n\r]/g,"").replace(/(\w)\.$/,"$1"),z=e=>Array.from(new Set(e)),_i=async(e,t,n,r,o,u,s,a,i,l,f,D,c)=>{try{const p=await Mi(e,t,{model:n,messages:[{role:"system",content:lt(r,s,a,D)},{role:"user",content:o}],temperature:f,top_p:1,frequency_penalty:0,presence_penalty:0,max_tokens:l,stream:!1,n:u},i,c);return z(p.choices.filter(d=>d.message?.content).map(d=>Pi(d.message.content)).map(d=>{if(a==="conventional"){const m=/: (\w)/;return d.replace(m,(h,C)=>`: ${C.toLowerCase()}`)}return d}).filter(d=>{switch(a){case"gitmoji":return ti(d);case"conventional":return ei(d);case"":default:return!0}}))}catch(p){const d=p;throw d.code==="ENOTFOUND"?new y(`Error connecting to ${d.hostname} (${d.syscall})`):d}};class Ti extends q{constructor(t){super(t),this.params=t,this.handleError$=n=>{const r=n.error?.error?.message?.replace(/(\r\n|\n|\r)/gm,"")||"An error occurred";return T({name:`${this.errorPrefix} ${r}`,value:r,isError:!0})},this.colors={primary:"#AE5630",secondary:"#fff"},this.serviceName=g.bgHex(this.colors.primary).hex(this.colors.secondary).bold("[Anthropic]"),this.errorPrefix=g.red.bold("[Anthropic]"),this.anthropic=new Re({apiKey:this.params.config.ANTHROPIC_KEY})}generateCommitMessage$(){return G(this.generateMessage()).pipe(k(t=>N(t)),L(t=>({name:`${this.serviceName} ${t}`,value:t,isError:!1})),j(this.handleError$))}async generateMessage(){try{const t=this.params.stagedDiff.diff,{locale:n,generate:r,type:o,prompt:u}=this.params.config,s=this.params.config["max-length"],a=this.buildPrompt(n,t,r,s,o,u),l=(await this.anthropic.completions.create({model:this.params.config.ANTHROPIC_MODEL,max_tokens_to_sample:this.params.config["max-tokens"],temperature:this.params.config.temperature,prompt:`${Re.HUMAN_PROMPT} ${a}${Re.AI_PROMPT}`})).completion;return z(this.sanitizeMessage(l,this.params.config.type,r))}catch(t){const n=t;throw n.code==="ENOTFOUND"?new y(`Error connecting to ${n.hostname} (${n.syscall})`):n}}}const{hasOwnProperty:vt}=Object.prototype,$e=typeof process<"u"&&process.platform==="win32"?`\r
|
|
54
54
|
`:`
|
|
55
|
-
`,Bt=(e,t)=>{const n=[];let r="";typeof t=="string"?t={section:t,whitespace:!1}:(t=t||Object.create(null),t.whitespace=t.whitespace===!0);const o=t.whitespace?" = ":"=";for(const u of Object.keys(e)){const s=e[u];if(s&&Array.isArray(s))for(const a of s)r+=ne(u+"[]")+o+ne(a)+$e;else s&&typeof s=="object"?n.push(u):r+=ne(u)+o+ne(s)+$e}t.section&&r.length&&(r="["+ne(t.section)+"]"+$e+r);for(const u of n){const s=Yr(u).join("\\."),a=(t.section?t.section+".":"")+s,{whitespace:i}=t,l=Bt(e[u],{section:a,whitespace:i});r.length&&l.length&&(r+=$e),r+=l}return r},Yr=e=>e.replace(/\1/g,"LITERAL\\1LITERAL").replace(/\\\./g,"").split(/\./).map(t=>t.replace(/\1/g,"\\.").replace(/\2LITERAL\\1LITERAL\2/g,"")),Wr=e=>{const t=Object.create(null);let n=t,r=null;const o=/^\[([^\]]*)\]$|^([^=]+)(=(.*))?$/i,u=e.split(/[\r\n]+/g);for(const a of u){if(!a||a.match(/^\s*[;#]/))continue;const i=a.match(o);if(!i)continue;if(i[1]!==void 0){if(r=xe(i[1]),r==="__proto__"){n=Object.create(null);continue}n=t[r]=t[r]||Object.create(null);continue}const l=xe(i[2]),f=l.length>2&&l.slice(-2)==="[]",D=f?l.slice(0,-2):l;if(D==="__proto__")continue;const c=i[3]?xe(i[4]):!0,p=c==="true"||c==="false"||c==="null"?JSON.parse(c):c;f&&(vt.call(n,D)?Array.isArray(n[D])||(n[D]=[n[D]]):n[D]=[]),Array.isArray(n[D])?n[D].push(p):n[D]=p}const s=[];for(const a of Object.keys(t)){if(!vt.call(t,a)||typeof t[a]!="object"||Array.isArray(t[a]))continue;const i=Yr(a);n=t;const l=i.pop(),f=l.replace(/\\\./g,".");for(const D of i)D!=="__proto__"&&((!vt.call(n,D)||typeof n[D]!="object")&&(n[D]=Object.create(null)),n=n[D]);n===t&&f===l||(n[f]=t[a],s.push(a))}for(const a of s)delete t[a];return t},Vr=e=>e.startsWith('"')&&e.endsWith('"')||e.startsWith("'")&&e.endsWith("'"),ne=e=>typeof e!="string"||e.match(/[=\r\n]/)||e.match(/^\[/)||e.length>1&&Vr(e)||e!==e.trim()?JSON.stringify(e):e.split(";").join("\\;").split("#").join("\\#"),xe=(e,t)=>{if(e=(e||"").trim(),Vr(e)){e.charAt(0)==="'"&&(e=e.slice(1,-1));try{e=JSON.parse(e)}catch{}}else{let n=!1,r="";for(let o=0,u=e.length;o<u;o++){const s=e.charAt(o);if(n)"\\;#".indexOf(s)!==-1?r+=s:r+="\\"+s,n=!1;else{if(";#".indexOf(s)!==-1)break;s==="\\"?n=!0:r+=s}}return n&&(r+="\\"),r.trim()}return e};var Ni={parse:Wr,decode:Wr,stringify:Bt,encode:Bt,safe:ne,unsafe:xe},Xr=X(Ni);const Jr=e=>$.lstat(e).then(()=>!0,()=>!1),Li=["","conventional","gitmoji"],{hasOwnProperty:Ri}=Object.prototype,Y=(e,t)=>Ri.call(e,t),E=(e,t,n)=>{if(!t)throw new y(`Invalid config property ${e}: ${n}`)},Oe={OPENAI_KEY(e){return e||""},OPENAI_MODEL(e){return!e||e.length===0?"gpt-3.5-turbo":e},OPENAI_HOST(e){return e?(E("OPENAI_HOST",/^https?:\/\//.test(e),"Must be a valid URL"),e):"https://api.openai.com"},HUGGING_COOKIE(e){return e||""},HUGGING_MODEL(e){return!e||e.length===0?"mistralai/Mixtral-8x7B-Instruct-v0.1":(E("HUGGING_MODEL",["mistralai/Mixtral-8x7B-Instruct-v0.1","meta-llama/Llama-2-70b-chat-hf","NousResearch/Nous-Hermes-2-Mixtral-8x7B-DPO","codellama/CodeLlama-70b-Instruct-hf","mistralai/Mistral-7B-Instruct-v0.2","openchat/openchat-3.5-0106"].includes(e),"Invalid model type of hugging"),e)},CLOVAX_COOKIE(e){return e||""},GEMINI_KEY(e){return e||""},GEMINI_MODEL(e){return!e||e.length===0?"gemini-pro":(E("GEMINI_MODEL",["gemini-pro"].includes(e),"Invalid model type of Gemini"),e)},ANTHROPIC_MODEL(e){return!e||e.length===0?"claude-2.1":(E("ANTHROPIC_MODEL",["claude-2.1","claude-2.0","claude-instant-1.2"].includes(e),"Invalid model type of Anthropic"),e)},ANTHROPIC_KEY(e){return e||""},MISTRAL_KEY(e){return e||""},MISTRAL_MODEL(e){return!e||e.length===0?"mistral-tiny":(E("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(e),"Invalid model type of Mistral AI"),e)},OLLAMA_MODEL(e){return e||""},OLLAMA_HOST(e){return e?(E("OLLAMA_HOST",/^https?:\/\//.test(e),"Must be a valid URL"),e):"http://localhost:11434"},OLLAMA_TIMEOUT(e){if(!e)return 1e5;E("OLLAMA_TIMEOUT",/^\d+$/.test(e),"Must be an integer");const t=Number(e);return E("OLLAMA_TIMEOUT",t>=500,"Must be greater than 500ms"),t},confirm(e){return e?typeof e=="boolean"?e:(E("confirm",/^(?:true|false)$/.test(e),"Must be a boolean"),e==="true"):!1},prompt(e){return e||""},locale(e){return e?(E("locale",e,"Cannot be empty"),E("locale",/^[a-z-]+$/i.test(e),"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"),e):"en"},generate(e){if(!e)return 1;E("generate",/^\d+$/.test(e),"Must be an integer");const t=Number(e);return E("generate",t>0,"Must be greater than 0"),E("generate",t<=5,"Must be less or equal to 5"),t},type(e){return e?(E("type",Li.includes(e),"Invalid commit type"),e):"conventional"},proxy(e){if(!(!e||e.length===0))return E("proxy",/^https?:\/\//.test(e),"Must be a valid URL"),e},timeout(e){if(!e)return 1e4;E("timeout",/^\d+$/.test(e),"Must be an integer");const t=Number(e);return E("timeout",t>=500,"Must be greater than 500ms"),t},temperature(e){if(!e)return .7;E("temperature",/^(2|\d)(\.\d{1,2})?$/.test(e),"Must be decimal between 0 and 2");const t=Number(e);return E("temperature",t>0,"Must be greater than 0"),E("temperature",t<=2,"Must be less than or equal to 2"),t},"max-length"(e){if(!e)return 50;E("max-length",/^\d+$/.test(e),"Must be an integer");const t=Number(e);return E("max-length",t>=20,"Must be greater than 20 characters"),t},"max-tokens"(e){return e?(E("max-tokens",/^\d+$/.test(e),"Must be an integer"),Number(e)):200}},$t=V.join(kt.homedir(),".aicommit2"),Zr=async()=>{if(!await Jr($t))return Object.create(null);const t=await $.readFile($t,"utf8");return Xr.parse(t)},xt=async(e,t)=>{const n=await Zr(),r={};for(const o of Object.keys(Oe)){const u=Oe[o],s=e?.[o]??n[o];if(t)try{r[o]=u(s)}catch{}else r[o]=u(s)}return r},ki=async e=>{const t=await Zr();for(const[n,r]of e){if(!Y(Oe,n))throw new y(`Invalid config property: ${n}`);const o=Oe[n](r);t[n]=o}await $.writeFile($t,Xr.stringify(t),"utf8")};class x{constructor(t={}){if(!t.method)throw new Error("method should be defined!");if(!t.baseURL)throw new Error("baseURL should be defined!");this.config={...t},this.axiosInstance=In.create(this.config)}setHeaders(t){return this.config.headers=t,this}setParams(t){return this.config.params=t,this}setBody(t){return this.config.data=t,this}setMethod(t){return this.config.method=t,this}async execute(){try{return await this.axiosInstance.request(this.config)}catch(t){throw t}}}class ji extends q{constructor(t){super(t),this.params=t,this.host="https://clova-x.naver.com",this.cookie="",this.colors={primary:"#00db9b",secondary:"#fff"},this.serviceName=g.bgHex(this.colors.primary).hex(this.colors.secondary).bold("[CLOVA X]"),this.errorPrefix=g.red.bold("[CLOVA X]"),this.cookie=this.params.config.CLOVAX_COOKIE}generateCommitMessage$(){return G(this.generateMessage()).pipe(k(t=>N(t)),L(t=>({name:`${this.serviceName} ${t}`,value:t,isError:!1})),j(this.handleError$))}async generateMessage(){try{const{locale:t,generate:n,type:r,prompt:o}=this.params.config,u=this.params.config["max-length"],s=this.params.stagedDiff.diff,a=this.buildPrompt(t,s,n,u,r,o);await this.getAllConversationIds();const i=await this.sendMessage(a),{conversationId:l,allText:f}=this.parseSendMessageResult(i);return await this.deleteConversation(l),z(this.sanitizeMessage(f,this.params.config.type,n))}catch(t){const n=t;throw n.code==="ENOTFOUND"?new y(`Error connecting to ${n.hostname} (${n.syscall})`):n}}async getAllConversationIds(){const n=(await new x({method:"GET",baseURL:`${this.host}/api/v1/conversations`,timeout:this.params.config.timeout}).setHeaders({Cookie:this.cookie}).setParams({page:0,size:50,sort:"turnUpdatedTime,DESC"}).execute()).data;if(!n||!n.content)throw new Error("No content on conversations ClovaX");return n.content.length===0?[]:n.content.map(o=>o.conversationId||"").filter(o=>!!o)}async sendMessage(t){const n={text:t,action:"new"},r=new xn;return r.set("form",new On([JSON.stringify(n)],{type:"application/json"})),(await new x({method:"POST",baseURL:`${this.host}/api/v1/generate`,timeout:this.params.config.timeout}).setHeaders({"Content-Type":"multipart/form-data","Content-Length":this.getContentLength(r),Cookie:this.cookie}).setBody(r).execute()).data}parseSendMessageResult(t){const n=/data:{(.*)}/g,r=t.match(n);if(!r)throw new Error("Failed to extract object from generated text");const o=r.map(i=>i.trim().replace(/data:/g,""));if(!o||o.length===0)throw new Error("Cannot extract message");let u="",s="",a="";if(o.map(i=>{try{return JSON.parse(i)}catch{return null}}).filter(i=>!!i).forEach(i=>{if(Y(i,"conversationId")){u=i.conversationId;return}if(Y(i,"text")){s+=i.text;return}if(Y(i,"error")){a=`${i.error}: ${i.type||i.message||""}`;return}}),a)throw new Error(a);if(!u)throw new Error("No conversationId!");if(!s)throw new Error("No allText!");return{conversationId:u,allText:s}}async deleteConversation(t){return(await new x({method:"DELETE",baseURL:`${this.host}/api/v1/conversation/${t}`,timeout:this.params.config.timeout}).setHeaders({Cookie:this.cookie}).execute()).data}getContentLength(t){return Array.from(t.entries(),([n,r])=>({[n]:{ContentLength:typeof r=="string"?r.length:r.size}}))}}class Gi extends q{constructor(t){super(t),this.params=t,this.handleError$=n=>{const r=n.message||n.toString(),o=/(\[.*?\]\s*[^[]*)/g,u=[...r.matchAll(o)],s=[];u.forEach(i=>s.push(i[1]));const a=s[1]||"An error occurred";return T({name:`${this.errorPrefix} ${a}`,value:a,isError:!0})},this.colors={primary:"#0077FF",secondary:"#fff"},this.serviceName=g.bgHex(this.colors.primary).hex(this.colors.secondary).bold("[Gemini]"),this.errorPrefix=g.red.bold("[Gemini]"),this.genAI=new Sn(this.params.config.GEMINI_KEY)}generateCommitMessage$(){return G(this.generateMessage()).pipe(k(t=>N(t)),L(t=>({name:`${this.serviceName} ${t}`,value:t,isError:!1})),j(this.handleError$))}async generateMessage(){try{const t=this.params.stagedDiff.diff,{locale:n,generate:r,type:o,prompt:u}=this.params.config,s=this.params.config["max-length"],a=this.buildPrompt(n,t,r,s,o,u),i=this.params.config["max-tokens"],c=(await(await this.genAI.getGenerativeModel({model:this.params.config.GEMINI_MODEL,generationConfig:{maxOutputTokens:i,temperature:this.params.config.temperature}}).generateContent(a)).response).text();return z(this.sanitizeMessage(c,this.params.config.type,r))}catch(t){const n=t;throw n.code==="ENOTFOUND"?new y(`Error connecting to ${n.hostname} (${n.syscall})`):n}}}class Hi extends q{constructor(t){super(t),this.params=t,this.host="https://huggingface.co",this.cookie="",this.colors={primary:"#FED21F",secondary:"#000"},this.serviceName=g.bgHex(this.colors.primary).hex(this.colors.secondary).bold("[HuggingFace]"),this.errorPrefix=g.red.bold("[HuggingFace]"),this.cookie=this.params.config.HUGGING_COOKIE}generateCommitMessage$(){return G(this.generateMessage()).pipe(k(t=>N(t)),L(t=>({name:`${this.serviceName} ${t}`,value:t,isError:!1})),j(this.handleError$))}async generateMessage(){try{const{locale:t,generate:n,type:r,prompt:o}=this.params.config,u=this.params.config["max-length"],s=this.params.stagedDiff.diff,a=this.buildPrompt(t,s,n,u,r,o);await this.prepareNewConversation();const{conversationId:i}=await this.getNewConversationId();await this.prepareConversationEvent(i);const{lastMessageId:l}=await this.getConversationInfo(i),f=await this.sendMessage(i,a,l);return await this.deleteConversation(i),z(this.sanitizeHuggingMessage(f,this.params.config.type,n))}catch(t){const n=t;throw n.code==="ENOTFOUND"?new y(`Error connecting to ${n.hostname} (${n.syscall})`):n}}sanitizeHuggingMessage(t,n,r){const o=/{[^{}]*}/g,u=t.match(o);if(!u)throw new Error("Failed to extract object from generated text");let s=null;if(u.forEach((a,i)=>{try{const l=JSON.parse(a);Y(l,"type")&&l.type==="finalAnswer"&&(s=l)}catch{}}),!s||!Y(s,"text"))throw new Error("Cannot parse finalAnswer");return this.sanitizeMessage(t,n,r)}async prepareNewConversation(){return(await new x({method:"POST",baseURL:`${this.host}/api/event`}).setHeaders({"content-type":"application/json",Cookie:this.cookie}).setBody({d:"huggingface.co",n:"pageview",r:"https://huggingface.co/chat/",u:"https://huggingface.co/chat/"}).execute()).data}async prepareConversationEvent(t){return(await new x({method:"POST",baseURL:`${this.host}/api/event`}).setHeaders({"content-type":"application/json",Cookie:this.cookie}).setBody({d:"huggingface.co",n:"pageview",r:"https://huggingface.co/chat/",u:`https://huggingface.co/chat/conversation/${t}`}).execute()).data}async getNewConversationId(){const t=await new x({method:"POST",baseURL:`${this.host}/chat/conversation`,timeout:this.params.config.timeout}).setHeaders({"content-type":"application/json",Cookie:this.cookie,Accept:"*/*",Connection:"keep-alive",Host:"huggingface.co",Origin:"https://huggingface.co"}).setBody({model:this.params.config.HUGGING_MODEL,preprompt:""}).execute();if(!t.data||!t.data.conversationId)throw new Error("No conversationId on Hugging service");return t.data}async getConversationInfo(t){const r=(await new x({method:"GET",baseURL:`${this.host}/chat/conversation/${t}/__data.json`,timeout:this.params.config.timeout}).setParams({"x-sveltekit-invalidated":"11"}).setHeaders({"Content-Type":"application/json",Cookie:this.cookie,Accept:"*/*",Connection:"keep-alive",Referer:"https://huggingface.co/chat/"}).execute()).data;if(!r||!r.nodes||r.nodes.length===0)throw new Error("No Nodes on conversation info");if(!r.nodes[1]||!r.nodes[1].data||r.nodes[1].data.length===0||!r.nodes[1].data[3])throw new Error("No data on node");const s=r.nodes[1]?.data[3];return{conversationInfo:r,lastMessageId:s}}async deleteConversation(t){return await new x({method:"DELETE",baseURL:`${this.host}/chat/conversation/${t}`,timeout:this.params.config.timeout}).setHeaders({Cookie:this.cookie}).execute(),(await new x({method:"GET",baseURL:`${this.host}/chat/__data.json`,timeout:this.params.config.timeout}).setParams({"x-sveltekit-trailing-slash":"1","x-sveltekit-invalidated":"10"}).setHeaders({"Content-Type":"application/json",Cookie:this.cookie,Accept:"*/*",Connection:"keep-alive",Referer:"https://huggingface.co/chat/"}).execute()).data}async sendMessage(t,n,r){return(await new x({method:"POST",baseURL:`${this.host}/chat/conversation/${t}`,timeout:this.params.config.timeout}).setHeaders({"content-type":"application/json",Cookie:this.cookie,authority:"huggingface.co",accept:"*/*",origin:"https://huggingface.co"}).setBody({files:[],id:r,inputs:n,is_continue:!1,is_retry:!1,use_cache:!1}).execute()).data}}const Ui=(e,t)=>{const n=Math.ceil(e),r=Math.floor(t);return Math.floor(Math.random()*(r-n+1))+n};class Ki extends q{constructor(t){super(t),this.params=t,this.host="https://api.mistral.ai",this.apiKey="",this.handleError$=n=>{const r=n.message?.replace(/(\r\n|\n|\r)/gm,"")||"An error occurred";return T({name:`${this.errorPrefix} ${r}`,value:r,isError:!0})},this.colors={primary:"#FC4A0A",secondary:"#fff"},this.serviceName=g.bgHex(this.colors.primary).hex(this.colors.secondary).bold("[MistralAI]"),this.errorPrefix=g.red.bold("[MistralAI]"),this.apiKey=this.params.config.MISTRAL_KEY}generateCommitMessage$(){return G(this.generateMessage()).pipe(k(t=>N(t)),L(t=>({name:`${this.serviceName} ${t}`,value:t,isError:!1})),j(this.handleError$))}async generateMessage(){try{const t=this.params.stagedDiff.diff,{locale:n,generate:r,type:o,prompt:u}=this.params.config,s=this.params.config["max-length"],a=this.buildPrompt(n,t,r,s,o,u);await this.checkAvailableModels();const i=await this.createChatCompletions(a);return z(this.sanitizeMessage(i,this.params.config.type,r))}catch(t){const n=t;throw n.code==="ENOTFOUND"?new y(`Error connecting to ${n.hostname} (${n.syscall})`):n}}async checkAvailableModels(){if((await this.getAvailableModels()).includes(this.params.config.MISTRAL_MODEL))return!0;throw new Error("Invalid model type of Mistral AI")}async getAvailableModels(){return(await new x({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(n=>n.object==="model").map(n=>n.id)}async createChatCompletions(t){const r=(await new x({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.MISTRAL_MODEL,messages:[{role:"user",content:t}],temperature:this.params.config.temperature,top_p:1,max_tokens:this.params.config["max-tokens"],stream:!1,safe_prompt:!1,random_seed:Ui(10,1e3)}).execute()).data;if(!r.choices||r.choices.length===0||!r.choices[0].message?.content)throw new Error("No Content on response. Please open a Bug report");return r.choices[0].message.content}}class qi extends q{constructor(t){super(t),this.params=t,this.host="http://localhost:11434",this.model="",this.handleError$=n=>{if(n.response.data?.error)return T({name:`${this.errorPrefix} ${n.response.data?.error}`,value:n.response.data?.error,isError:!0});const r=n.message?.replace(/(\r\n|\n|\r)/gm,"")||"An error occurred";return T({name:`${this.errorPrefix} ${r}`,value:r,isError:!0})},this.colors={primary:"#FFF",secondary:"#000"},this.serviceName=g.bgHex(this.colors.primary).hex(this.colors.secondary).bold("[Ollama]"),this.errorPrefix=g.red.bold("[Ollama]"),this.model=this.params.config.OLLAMA_MODEL,this.host=this.params.config.OLLAMA_HOST||"http://localhost:11434",this.ollama=new Mn({host:this.host})}generateCommitMessage$(){return G(this.generateMessage()).pipe(k(t=>N(t)),L(t=>({name:`${this.serviceName} ${t}`,value:t,isError:!1})),j(this.handleError$))}async generateMessage(){try{await this.checkIsAvailableOllama();const t=await this.createChatCompletions();return z(this.sanitizeMessage(t,this.params.config.type,generate))}catch(t){const n=t;throw n.code==="ENOTFOUND"?new y(`Error connecting to ${n.hostname} (${n.syscall})`):n}}async checkIsAvailableOllama(){try{return(await new x({method:"GET",baseURL:`${this.host}`,timeout:this.params.config.OLLAMA_TIMEOUT}).execute()).data}catch(t){throw t.code==="ECONNREFUSED"?new y(`Error connecting to ${this.host}. Please run Ollama or check host`):t}}async createChatCompletions(){const n=`${lt(this.params.config.locale,this.params.config["max-length"],this.params.config.type,this.params.config.prompt)}
|
|
55
|
+
`,Bt=(e,t)=>{const n=[];let r="";typeof t=="string"?t={section:t,whitespace:!1}:(t=t||Object.create(null),t.whitespace=t.whitespace===!0);const o=t.whitespace?" = ":"=";for(const u of Object.keys(e)){const s=e[u];if(s&&Array.isArray(s))for(const a of s)r+=ne(u+"[]")+o+ne(a)+$e;else s&&typeof s=="object"?n.push(u):r+=ne(u)+o+ne(s)+$e}t.section&&r.length&&(r="["+ne(t.section)+"]"+$e+r);for(const u of n){const s=Yr(u).join("\\."),a=(t.section?t.section+".":"")+s,{whitespace:i}=t,l=Bt(e[u],{section:a,whitespace:i});r.length&&l.length&&(r+=$e),r+=l}return r},Yr=e=>e.replace(/\1/g,"LITERAL\\1LITERAL").replace(/\\\./g,"").split(/\./).map(t=>t.replace(/\1/g,"\\.").replace(/\2LITERAL\\1LITERAL\2/g,"")),Wr=e=>{const t=Object.create(null);let n=t,r=null;const o=/^\[([^\]]*)\]$|^([^=]+)(=(.*))?$/i,u=e.split(/[\r\n]+/g);for(const a of u){if(!a||a.match(/^\s*[;#]/))continue;const i=a.match(o);if(!i)continue;if(i[1]!==void 0){if(r=xe(i[1]),r==="__proto__"){n=Object.create(null);continue}n=t[r]=t[r]||Object.create(null);continue}const l=xe(i[2]),f=l.length>2&&l.slice(-2)==="[]",D=f?l.slice(0,-2):l;if(D==="__proto__")continue;const c=i[3]?xe(i[4]):!0,p=c==="true"||c==="false"||c==="null"?JSON.parse(c):c;f&&(vt.call(n,D)?Array.isArray(n[D])||(n[D]=[n[D]]):n[D]=[]),Array.isArray(n[D])?n[D].push(p):n[D]=p}const s=[];for(const a of Object.keys(t)){if(!vt.call(t,a)||typeof t[a]!="object"||Array.isArray(t[a]))continue;const i=Yr(a);n=t;const l=i.pop(),f=l.replace(/\\\./g,".");for(const D of i)D!=="__proto__"&&((!vt.call(n,D)||typeof n[D]!="object")&&(n[D]=Object.create(null)),n=n[D]);n===t&&f===l||(n[f]=t[a],s.push(a))}for(const a of s)delete t[a];return t},Vr=e=>e.startsWith('"')&&e.endsWith('"')||e.startsWith("'")&&e.endsWith("'"),ne=e=>typeof e!="string"||e.match(/[=\r\n]/)||e.match(/^\[/)||e.length>1&&Vr(e)||e!==e.trim()?JSON.stringify(e):e.split(";").join("\\;").split("#").join("\\#"),xe=(e,t)=>{if(e=(e||"").trim(),Vr(e)){e.charAt(0)==="'"&&(e=e.slice(1,-1));try{e=JSON.parse(e)}catch{}}else{let n=!1,r="";for(let o=0,u=e.length;o<u;o++){const s=e.charAt(o);if(n)"\\;#".indexOf(s)!==-1?r+=s:r+="\\"+s,n=!1;else{if(";#".indexOf(s)!==-1)break;s==="\\"?n=!0:r+=s}}return n&&(r+="\\"),r.trim()}return e};var Ni={parse:Wr,decode:Wr,stringify:Bt,encode:Bt,safe:ne,unsafe:xe},Xr=X(Ni);const Jr=e=>$.lstat(e).then(()=>!0,()=>!1),Li=["","conventional","gitmoji"],{hasOwnProperty:Ri}=Object.prototype,Y=(e,t)=>Ri.call(e,t),E=(e,t,n)=>{if(!t)throw new y(`Invalid config property ${e}: ${n}`)},Oe={OPENAI_KEY(e){return e||""},OPENAI_MODEL(e){return!e||e.length===0?"gpt-3.5-turbo":e},OPENAI_HOST(e){return e?(E("OPENAI_HOST",/^https?:\/\//.test(e),"Must be a valid URL"),e):"https://api.openai.com"},HUGGING_COOKIE(e){return e||""},HUGGING_MODEL(e){return!e||e.length===0?"mistralai/Mixtral-8x7B-Instruct-v0.1":(E("HUGGING_MODEL",["mistralai/Mixtral-8x7B-Instruct-v0.1","meta-llama/Llama-2-70b-chat-hf","NousResearch/Nous-Hermes-2-Mixtral-8x7B-DPO","codellama/CodeLlama-70b-Instruct-hf","mistralai/Mistral-7B-Instruct-v0.2","openchat/openchat-3.5-0106"].includes(e),"Invalid model type of hugging"),e)},CLOVAX_COOKIE(e){return e||""},GEMINI_KEY(e){return e||""},GEMINI_MODEL(e){return!e||e.length===0?"gemini-pro":(E("GEMINI_MODEL",["gemini-pro"].includes(e),"Invalid model type of Gemini"),e)},ANTHROPIC_MODEL(e){return!e||e.length===0?"claude-2.1":(E("ANTHROPIC_MODEL",["claude-2.1","claude-2.0","claude-instant-1.2"].includes(e),"Invalid model type of Anthropic"),e)},ANTHROPIC_KEY(e){return e||""},MISTRAL_KEY(e){return e||""},MISTRAL_MODEL(e){return!e||e.length===0?"mistral-tiny":(E("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(e),"Invalid model type of Mistral AI"),e)},OLLAMA_MODEL(e){return e||""},OLLAMA_HOST(e){return e?(E("OLLAMA_HOST",/^https?:\/\//.test(e),"Must be a valid URL"),e):"http://localhost:11434"},OLLAMA_TIMEOUT(e){if(!e)return 1e5;E("OLLAMA_TIMEOUT",/^\d+$/.test(e),"Must be an integer");const t=Number(e);return E("OLLAMA_TIMEOUT",t>=500,"Must be greater than 500ms"),t},confirm(e){return e?typeof e=="boolean"?e:(E("confirm",/^(?:true|false)$/.test(e),"Must be a boolean"),e==="true"):!1},prompt(e){return e||""},locale(e){return e?(E("locale",e,"Cannot be empty"),E("locale",/^[a-z-]+$/i.test(e),"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"),e):"en"},generate(e){if(!e)return 1;E("generate",/^\d+$/.test(e),"Must be an integer");const t=Number(e);return E("generate",t>0,"Must be greater than 0"),E("generate",t<=5,"Must be less or equal to 5"),t},type(e){return e?(E("type",Li.includes(e),"Invalid commit type"),e):"conventional"},proxy(e){if(!(!e||e.length===0))return E("proxy",/^https?:\/\//.test(e),"Must be a valid URL"),e},timeout(e){if(!e)return 1e4;E("timeout",/^\d+$/.test(e),"Must be an integer");const t=Number(e);return E("timeout",t>=500,"Must be greater than 500ms"),t},temperature(e){if(!e)return .7;E("temperature",/^(2|\d)(\.\d{1,2})?$/.test(e),"Must be decimal between 0 and 2");const t=Number(e);return E("temperature",t>0,"Must be greater than 0"),E("temperature",t<=2,"Must be less than or equal to 2"),t},"max-length"(e){if(!e)return 50;E("max-length",/^\d+$/.test(e),"Must be an integer");const t=Number(e);return E("max-length",t>=20,"Must be greater than 20 characters"),t},"max-tokens"(e){return e?(E("max-tokens",/^\d+$/.test(e),"Must be an integer"),Number(e)):200}},$t=V.join(kt.homedir(),".aicommit2"),Zr=async()=>{if(!await Jr($t))return Object.create(null);const t=await $.readFile($t,"utf8");return Xr.parse(t)},xt=async(e,t)=>{const n=await Zr(),r={};for(const o of Object.keys(Oe)){const u=Oe[o],s=e?.[o]??n[o];if(t)try{r[o]=u(s)}catch{}else r[o]=u(s)}return r},ki=async e=>{const t=await Zr();for(const[n,r]of e){if(!Y(Oe,n))throw new y(`Invalid config property: ${n}`);const o=Oe[n](r);t[n]=o}await $.writeFile($t,Xr.stringify(t),"utf8")};class x{constructor(t={}){if(!t.method)throw new Error("method should be defined!");if(!t.baseURL)throw new Error("baseURL should be defined!");this.config={...t},this.axiosInstance=In.create(this.config)}setHeaders(t){return this.config.headers=t,this}setParams(t){return this.config.params=t,this}setBody(t){return this.config.data=t,this}setMethod(t){return this.config.method=t,this}async execute(){try{return await this.axiosInstance.request(this.config)}catch(t){throw t}}}class ji extends q{constructor(t){super(t),this.params=t,this.host="https://clova-x.naver.com",this.cookie="",this.colors={primary:"#00db9b",secondary:"#fff"},this.serviceName=g.bgHex(this.colors.primary).hex(this.colors.secondary).bold("[CLOVA X]"),this.errorPrefix=g.red.bold("[CLOVA X]"),this.cookie=this.params.config.CLOVAX_COOKIE}generateCommitMessage$(){return G(this.generateMessage()).pipe(k(t=>N(t)),L(t=>({name:`${this.serviceName} ${t}`,value:t,isError:!1})),j(this.handleError$))}async generateMessage(){try{const{locale:t,generate:n,type:r,prompt:o}=this.params.config,u=this.params.config["max-length"],s=this.params.stagedDiff.diff,a=this.buildPrompt(t,s,n,u,r,o);await this.getAllConversationIds();const i=await this.sendMessage(a),{conversationId:l,allText:f}=this.parseSendMessageResult(i);return await this.deleteConversation(l),z(this.sanitizeMessage(f,this.params.config.type,n))}catch(t){const n=t;throw n.code==="ENOTFOUND"?new y(`Error connecting to ${n.hostname} (${n.syscall})`):n}}async getAllConversationIds(){const n=(await new x({method:"GET",baseURL:`${this.host}/api/v1/conversations`,timeout:this.params.config.timeout}).setHeaders({Cookie:this.cookie}).setParams({page:0,size:50,sort:"turnUpdatedTime,DESC"}).execute()).data;if(!n||!n.content)throw new Error("No content on conversations ClovaX");return n.content.length===0?[]:n.content.map(o=>o.conversationId||"").filter(o=>!!o)}async sendMessage(t){const n={text:t,action:"new"},r=new xn;return r.set("form",new On([JSON.stringify(n)],{type:"application/json"})),(await new x({method:"POST",baseURL:`${this.host}/api/v1/generate`,timeout:this.params.config.timeout}).setHeaders({"Content-Type":"multipart/form-data","Content-Length":this.getContentLength(r),Cookie:this.cookie}).setBody(r).execute()).data}parseSendMessageResult(t){const n=/data:{(.*)}/g,r=t.match(n);if(!r)throw new Error("Failed to extract object from generated text");const o=r.map(i=>i.trim().replace(/data:/g,""));if(!o||o.length===0)throw new Error("Cannot extract message");let u="",s="",a="";if(o.map(i=>{try{return JSON.parse(i)}catch{return null}}).filter(i=>!!i).forEach(i=>{if(Y(i,"conversationId")){u=i.conversationId;return}if(Y(i,"text")){s+=i.text;return}if(Y(i,"error")){a=`${i.error}: ${i.type||i.message||""}`;return}}),a)throw new Error(a);if(!u)throw new Error("No conversationId!");if(!s)throw new Error("No allText!");return{conversationId:u,allText:s}}async deleteConversation(t){return(await new x({method:"DELETE",baseURL:`${this.host}/api/v1/conversation/${t}`,timeout:this.params.config.timeout}).setHeaders({Cookie:this.cookie}).execute()).data}getContentLength(t){return Array.from(t.entries(),([n,r])=>({[n]:{ContentLength:typeof r=="string"?r.length:r.size}}))}}class Gi extends q{constructor(t){super(t),this.params=t,this.handleError$=n=>{const r=n.message||n.toString(),o=/(\[.*?\]\s*[^[]*)/g,u=[...r.matchAll(o)],s=[];u.forEach(i=>s.push(i[1]));const a=s[1]||"An error occurred";return T({name:`${this.errorPrefix} ${a}`,value:a,isError:!0})},this.colors={primary:"#0077FF",secondary:"#fff"},this.serviceName=g.bgHex(this.colors.primary).hex(this.colors.secondary).bold("[Gemini]"),this.errorPrefix=g.red.bold("[Gemini]"),this.genAI=new Sn(this.params.config.GEMINI_KEY)}generateCommitMessage$(){return G(this.generateMessage()).pipe(k(t=>N(t)),L(t=>({name:`${this.serviceName} ${t}`,value:t,isError:!1})),j(this.handleError$))}async generateMessage(){try{const t=this.params.stagedDiff.diff,{locale:n,generate:r,type:o,prompt:u}=this.params.config,s=this.params.config["max-length"],a=this.buildPrompt(n,t,r,s,o,u),i=this.params.config["max-tokens"],c=(await(await this.genAI.getGenerativeModel({model:this.params.config.GEMINI_MODEL,generationConfig:{maxOutputTokens:i,temperature:this.params.config.temperature}}).generateContent(a)).response).text();return z(this.sanitizeMessage(c,this.params.config.type,r))}catch(t){const n=t;throw n.code==="ENOTFOUND"?new y(`Error connecting to ${n.hostname} (${n.syscall})`):n}}}class Hi extends q{constructor(t){super(t),this.params=t,this.host="https://huggingface.co",this.cookie="",this.colors={primary:"#FED21F",secondary:"#000"},this.serviceName=g.bgHex(this.colors.primary).hex(this.colors.secondary).bold("[HuggingFace]"),this.errorPrefix=g.red.bold("[HuggingFace]"),this.cookie=this.params.config.HUGGING_COOKIE}generateCommitMessage$(){return G(this.generateMessage()).pipe(k(t=>N(t)),L(t=>({name:`${this.serviceName} ${t}`,value:t,isError:!1})),j(this.handleError$))}async generateMessage(){try{const{locale:t,generate:n,type:r,prompt:o}=this.params.config,u=this.params.config["max-length"],s=this.params.stagedDiff.diff,a=this.buildPrompt(t,s,n,u,r,o);await this.prepareNewConversation();const{conversationId:i}=await this.getNewConversationId();await this.prepareConversationEvent(i);const{lastMessageId:l}=await this.getConversationInfo(i),f=await this.sendMessage(i,a,l);return await this.deleteConversation(i),z(this.sanitizeHuggingMessage(f,this.params.config.type,n))}catch(t){const n=t;throw n.code==="ENOTFOUND"?new y(`Error connecting to ${n.hostname} (${n.syscall})`):n}}sanitizeHuggingMessage(t,n,r){const o=/{[^{}]*}/g,u=t.match(o);if(!u)throw new Error("Failed to extract object from generated text");let s=null;if(u.forEach((a,i)=>{try{const l=JSON.parse(a);Y(l,"type")&&l.type==="finalAnswer"&&(s=l)}catch{}}),!s||!Y(s,"text"))throw new Error("Cannot parse finalAnswer");return this.sanitizeMessage(t,n,r)}async prepareNewConversation(){return(await new x({method:"POST",baseURL:`${this.host}/api/event`}).setHeaders({"content-type":"application/json",Cookie:this.cookie}).setBody({d:"huggingface.co",n:"pageview",r:"https://huggingface.co/chat/",u:"https://huggingface.co/chat/"}).execute()).data}async prepareConversationEvent(t){return(await new x({method:"POST",baseURL:`${this.host}/api/event`}).setHeaders({"content-type":"application/json",Cookie:this.cookie}).setBody({d:"huggingface.co",n:"pageview",r:"https://huggingface.co/chat/",u:`https://huggingface.co/chat/conversation/${t}`}).execute()).data}async getNewConversationId(){const t=await new x({method:"POST",baseURL:`${this.host}/chat/conversation`,timeout:this.params.config.timeout}).setHeaders({"content-type":"application/json",Cookie:this.cookie,Accept:"*/*",Connection:"keep-alive",Host:"huggingface.co",Origin:"https://huggingface.co"}).setBody({model:this.params.config.HUGGING_MODEL,preprompt:""}).execute();if(!t.data||!t.data.conversationId)throw new Error("No conversationId on Hugging service");return t.data}async getConversationInfo(t){const r=(await new x({method:"GET",baseURL:`${this.host}/chat/conversation/${t}/__data.json`,timeout:this.params.config.timeout}).setParams({"x-sveltekit-invalidated":"11"}).setHeaders({"Content-Type":"application/json",Cookie:this.cookie,Accept:"*/*",Connection:"keep-alive",Referer:"https://huggingface.co/chat/"}).execute()).data;if(!r||!r.nodes||r.nodes.length===0)throw new Error("No Nodes on conversation info");if(!r.nodes[1]||!r.nodes[1].data||r.nodes[1].data.length===0||!r.nodes[1].data[3])throw new Error("No data on node");const s=r.nodes[1]?.data[3];return{conversationInfo:r,lastMessageId:s}}async deleteConversation(t){return await new x({method:"DELETE",baseURL:`${this.host}/chat/conversation/${t}`,timeout:this.params.config.timeout}).setHeaders({Cookie:this.cookie}).execute(),(await new x({method:"GET",baseURL:`${this.host}/chat/__data.json`,timeout:this.params.config.timeout}).setParams({"x-sveltekit-trailing-slash":"1","x-sveltekit-invalidated":"10"}).setHeaders({"Content-Type":"application/json",Cookie:this.cookie,Accept:"*/*",Connection:"keep-alive",Referer:"https://huggingface.co/chat/"}).execute()).data}async sendMessage(t,n,r){return(await new x({method:"POST",baseURL:`${this.host}/chat/conversation/${t}`,timeout:this.params.config.timeout}).setHeaders({"content-type":"application/json",Cookie:this.cookie,authority:"huggingface.co",accept:"*/*",origin:"https://huggingface.co"}).setBody({files:[],id:r,inputs:n,is_continue:!1,is_retry:!1,use_cache:!1}).execute()).data}}const Ui=(e,t)=>{const n=Math.ceil(e),r=Math.floor(t);return Math.floor(Math.random()*(r-n+1))+n};class Ki extends q{constructor(t){super(t),this.params=t,this.host="https://api.mistral.ai",this.apiKey="",this.handleError$=n=>{const r=n.message?.replace(/(\r\n|\n|\r)/gm,"")||"An error occurred";return T({name:`${this.errorPrefix} ${r}`,value:r,isError:!0})},this.colors={primary:"#FC4A0A",secondary:"#fff"},this.serviceName=g.bgHex(this.colors.primary).hex(this.colors.secondary).bold("[MistralAI]"),this.errorPrefix=g.red.bold("[MistralAI]"),this.apiKey=this.params.config.MISTRAL_KEY}generateCommitMessage$(){return G(this.generateMessage()).pipe(k(t=>N(t)),L(t=>({name:`${this.serviceName} ${t}`,value:t,isError:!1})),j(this.handleError$))}async generateMessage(){try{const t=this.params.stagedDiff.diff,{locale:n,generate:r,type:o,prompt:u}=this.params.config,s=this.params.config["max-length"],a=this.buildPrompt(n,t,r,s,o,u);await this.checkAvailableModels();const i=await this.createChatCompletions(a);return z(this.sanitizeMessage(i,this.params.config.type,r))}catch(t){const n=t;throw n.code==="ENOTFOUND"?new y(`Error connecting to ${n.hostname} (${n.syscall})`):n}}async checkAvailableModels(){if((await this.getAvailableModels()).includes(this.params.config.MISTRAL_MODEL))return!0;throw new Error("Invalid model type of Mistral AI")}async getAvailableModels(){return(await new x({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(n=>n.object==="model").map(n=>n.id)}async createChatCompletions(t){const r=(await new x({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.MISTRAL_MODEL,messages:[{role:"user",content:t}],temperature:this.params.config.temperature,top_p:1,max_tokens:this.params.config["max-tokens"],stream:!1,safe_prompt:!1,random_seed:Ui(10,1e3)}).execute()).data;if(!r.choices||r.choices.length===0||!r.choices[0].message?.content)throw new Error("No Content on response. Please open a Bug report");return r.choices[0].message.content}}class qi extends q{constructor(t){super(t),this.params=t,this.host="http://localhost:11434",this.model="",this.handleError$=n=>{if(n.response.data?.error)return T({name:`${this.errorPrefix} ${n.response.data?.error}`,value:n.response.data?.error,isError:!0});const r=n.message?.replace(/(\r\n|\n|\r)/gm,"")||"An error occurred";return T({name:`${this.errorPrefix} ${r}`,value:r,isError:!0})},this.colors={primary:"#FFF",secondary:"#000"},this.serviceName=g.bgHex(this.colors.primary).hex(this.colors.secondary).bold("[Ollama]"),this.errorPrefix=g.red.bold("[Ollama]"),this.model=this.params.config.OLLAMA_MODEL,this.host=this.params.config.OLLAMA_HOST||"http://localhost:11434",this.ollama=new Mn({host:this.host})}generateCommitMessage$(){return G(this.generateMessage()).pipe(k(t=>N(t)),L(t=>({name:`${this.serviceName} ${t}`,value:t,isError:!1})),j(this.handleError$))}async generateMessage(){try{await this.checkIsAvailableOllama();const t=await this.createChatCompletions();return z(this.sanitizeMessage(t,this.params.config.type,this.params.config.generate))}catch(t){const n=t;throw n.code==="ENOTFOUND"?new y(`Error connecting to ${n.hostname} (${n.syscall})`):n}}async checkIsAvailableOllama(){try{return(await new x({method:"GET",baseURL:`${this.host}`,timeout:this.params.config.OLLAMA_TIMEOUT}).execute()).data}catch(t){throw t.code==="ECONNREFUSED"?new y(`Error connecting to ${this.host}. Please run Ollama or check host`):t}}async createChatCompletions(){const n=`${lt(this.params.config.locale,this.params.config["max-length"],this.params.config.type,this.params.config.prompt)}
|
|
56
56
|
Please just generate ${this.params.config.generate} commit messages in numbered list format without explanation.`;return(await this.ollama.chat({model:this.params.config.OLLAMA_MODEL,messages:[{role:"system",content:n},{role:"user",content:this.params.stagedDiff.diff}],stream:!1})).message.content}}class zi extends q{constructor(t){super(t),this.params=t,this.handleError$=n=>{let r="An error occurred";if(n.message){r=n.message.split(`
|
|
57
57
|
`)[0];const o=this.extractJSONFromError(n.message);r+=`: ${o.error.message}`}return T({name:`${this.errorPrefix} ${r}`,value:r,isError:!0})},this.colors={primary:"#74AA9C",secondary:"#FFF"},this.serviceName=g.bgHex(this.colors.primary).hex(this.colors.secondary).bold("[ChatGPT]"),this.errorPrefix=g.red.bold("[ChatGPT]")}generateCommitMessage$(){return G(_i(this.params.config.OPENAI_HOST,this.params.config.OPENAI_KEY,this.params.config.OPENAI_MODEL,this.params.config.locale,this.params.stagedDiff.diff,this.params.config.generate,this.params.config["max-length"],this.params.config.type,this.params.config.timeout,this.params.config["max-tokens"],this.params.config.temperature,this.params.config.prompt,this.params.config.proxy)).pipe(k(t=>N(t)),L(t=>({name:`${this.serviceName} ${t}`,value:t,isError:!1})),j(this.handleError$))}extractJSONFromError(t){const n=/[{[]{1}([,:{}[\]0-9.\-+Eaeflnr-u \n\r\t]|".*?")+[}\]]{1}/gis,r=t.match(n);return r?Object.assign({},...r.map(o=>JSON.parse(o))):{error:{message:"Unknown error"}}}}class Qr{constructor(t,n){this.config=t,this.stagedDiff=n}createAIRequests$(t){return N(t).pipe(hn(n=>{const r={config:this.config,stagedDiff:this.stagedDiff};switch(n){case R.OPEN_AI:return K.create(zi,r).generateCommitMessage$();case R.GEMINI:return K.create(Gi,r).generateCommitMessage$();case R.ANTHROPIC:return K.create(Ti,r).generateCommitMessage$();case R.HUGGING:return K.create(Hi,r).generateCommitMessage$();case R.CLOVA_X:return K.create(ji,r).generateCommitMessage$();case R.MISTRAL:return K.create(Ki,r).generateCommitMessage$();case R.OLLAMA:return K.create(qi,r).generateCommitMessage$();default:const o=g.red.bold(`[${n}]`);return T({name:o+" Invalid AI type",value:"Invalid AI type",isError:!0})}}))}}const en=async()=>{const{stdout:e,failed:t}=await te("git",["rev-parse","--show-toplevel"],{reject:!1});if(t)throw new y("The current directory must be a Git repository!");return e},Ot=e=>`:(exclude)${e}`,tn=["package-lock.json","pnpm-lock.yaml","*.lock"].map(Ot),rn=async e=>{const t=["diff","--cached","--diff-algorithm=minimal"],{stdout:n}=await te("git",[...t,"--name-only",...tn,...e?e.map(Ot):[]]);if(!n)return null;const{stdout:r}=await te("git",[...t,...tn,...e?e.map(Ot):[]]);return{files:n.split(`
|
|
58
58
|
`),diff:r}},Yi=e=>`Detected ${e.length.toLocaleString()} staged file${e.length>1?"s":""}`;class Ie{constructor(){this.title="aicommit2"}printTitle(){console.log(Pn.textSync(this.title,{font:"Small"}))}displaySpinner(t){return Le(t).start()}stopSpinner(t){t.stop(),t.clear()}printStagedFiles(t){console.log(g.bold.green("\u2714 ")+g.bold(`${Yi(t.files)}:`)),console.log(`${t.files.map(n=>` ${n}`).join(`
|