UNPKG

aicommit2

Version:

A Reactive CLI that generates commit messages for Git and Jujutsu with various AI

2 lines (1 loc) 5.15 kB
import P from"chalk";import B from"openai";import{concatMap as v,from as $,map as w,catchError as x}from"rxjs";import{fromPromise as M}from"rxjs/internal/observable/innerFrom";import{A as F,l as S,a as _,b,c as N,d as O,e as R}from"./ai.service-d8e94c3a.mjs";import{i as E}from"./openai-5eabc0ae.mjs";import{g as D,a as H,c as T,b as K}from"./cli-8ee62906.mjs";import"fs";import"path";import"@pacote/xxhash";import"winston";import"http";import"https";import"net";import"tls";import"url";import"assert";import"tty";import"util";import"os";import"events";import"cleye";import"module";import"crypto";import"node:buffer";import"node:path";import"node:child_process";import"node:process";import"child_process";import"node:url";import"node:os";import"node:fs";import"buffer";import"stream";import"node:util";import"inquirer";import"fs/promises";import"readline";import"figlet";import"gradient-string";import"ora";import"inquirer-reactive-list-prompt";import"winston-daily-rotate-file";import"axios";import"node:fs/promises";import"chokidar";import"rxjs/operators";class U extends F{constructor(t){super(t),this.params=t,this.generateStreamingCommitMessage$=()=>{const{generate:o,type:r}=this.params.config;return this.createStreamingCommitMessages$(i=>{this.streamChunks(i).catch(m=>i.error(m))},r,o)},this.streamChunks=async o=>{const r=this.params.stagedDiff.diff,{logging:i,temperature:m,timeout:u}=this.params.config,c=this.params.config.maxTokens,p=D(this.buildPromptOptions()),l=`Here is the diff: ${r}`,s=this.params.keyName||"OpenAI-Compatible",n=`${this.params.config.url}${this.params.config.path}`,k={Authorization:`Bearer ${this.params.config.key}`,"Content-Type":"application/json"};S(r,"commit",s,this.params.config.model,n,k,i),_(r,"commit",s,p,l,i);const y=E(this.params.config.model),g={messages:[{role:"system",content:p},{role:"user",content:l}],model:this.params.config.model,stream:!0,...y?{max_completion_tokens:c,temperature:1}:{max_tokens:c,top_p:this.params.config.topP,temperature:m}};b(r,"commit",s,g,i);const f=Date.now();let h="";try{const d=await this.openAI.chat.completions.create(g,{timeout:u});for await(const I of d){const L=I.choices?.[0]?.delta?.content||"",z=I.choices?.[0]?.delta?.reasoning_content||"",C=`${L}${z}`;C&&(h+=C,o.next(C))}const A=Date.now()-f;N(r,"commit",s,{streamed:!0,totalLength:h.length},i),O(r,"commit",s,A,h,i),o.complete()}catch(a){R(r,"commit",s,a,i),o.error(a)}};const e=this.params.keyName||"OPENAI_COMPATIBLE";this.colors=H(e),this.serviceName=P.bgHex(this.colors.primary).hex(this.colors.secondary).bold(`[${T(e)}]`),this.errorPrefix=P.red.bold(`[${T(e)}]`),this.openAI=new B({apiKey:this.params.config.key,baseURL:`${this.params.config.url}${this.params.config.path}`})}getServiceSpecificErrorMessage(t){const e=t.message||"";return e.includes("API key")||e.includes("api_key")?"Invalid API key. Check your OpenAI-compatible API key in configuration":e.includes("rate_limit")||e.includes("Rate limit")?"Rate limit exceeded. Wait a moment and try again, or check your service limits":e.includes("model")||e.includes("Model")?"Model not found or not accessible. Check if the model name is correct":e.includes("network")||e.includes("connection")?"Network error. Check your internet connection and API endpoint":e.includes("quota")||e.includes("usage")?"API quota exceeded. Check your usage limits":e.includes("403")||e.includes("Forbidden")?"Access denied. Your API key may not have permission for this model":e.includes("404")||e.includes("Not Found")?"Model or endpoint not found. Check your API configuration":e.includes("500")||e.includes("Internal Server Error")?"Server error. Try again later":e.includes("overloaded")||e.includes("capacity")?"Service is overloaded. Try again in a few minutes":null}generateCommitMessage$(){return this.params.config.stream||!1?this.generateStreamingCommitMessage$():M(this.generateMessage("commit")).pipe(v(e=>$(e)),w(this.formatAsChoice),x(this.handleError$))}generateCodeReview$(){return M(this.generateMessage("review")).pipe(v(t=>$(t)),w(this.formatCodeReviewAsChoice),x(this.handleError$))}async generateMessage(t){const e=this.params.stagedDiff.diff,{logging:o,temperature:r,generate:i,type:m,timeout:u}=this.params.config,c=this.params.config.maxTokens,p=this.buildPromptOptions(),l=t==="review"?K(p):D(p),s=`Here is the diff: ${e}`,n=this.params.keyName||"OpenAI-Compatible",k=`${this.params.config.url}${this.params.config.path}`,y={Authorization:`Bearer ${this.params.config.key}`,"Content-Type":"application/json"};S(e,t,n,this.params.config.model,k,y,o),_(e,t,n,l,s,o);const g=E(this.params.config.model),f={messages:[{role:"system",content:l},{role:"user",content:s}],model:this.params.config.model,stream:!1,...g?{max_completion_tokens:c,temperature:1}:{max_tokens:c,top_p:this.params.config.topP,temperature:r}};b(e,t,n,f,o);const h=Date.now();try{const a=await this.openAI.chat.completions.create(f,{timeout:u}),d=a.choices?.[0]?.message.content||"",A=Date.now()-h;return N(e,t,n,a,o),O(e,t,n,A,d,o),t==="review"?this.parseCodeReview(d):this.parseMessage(d,m,i)}catch(a){throw R(e,t,n,a,o),a}}}export{U as OpenAICompatibleService};