UNPKG

aicommit2

Version:

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

3 lines (2 loc) 8.45 kB
import y from"chalk";import{concatMap as C,from as b,map as k,catchError as D}from"rxjs";import{fromPromise as E}from"rxjs/internal/observable/innerFrom";import{A as I,l as M,a as A,c as P,d as $,e as H}from"./ai.service-d8e94c3a.mjs";import{b as R,g as S}from"./cli-8ee62906.mjs";import"fs";import"path";import"@pacote/xxhash";import"winston";import"cleye";import"module";import"crypto";import"os";import"node:buffer";import"node:path";import"node:child_process";import"node:process";import"child_process";import"node:url";import"node:os";import"assert";import"events";import"node:fs";import"buffer";import"stream";import"util";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"url";import"node:fs/promises";import"chokidar";import"rxjs/operators";class U extends I{constructor(o){super(o),this.params=o,this.headers={},this.models=[],this.currentModelId=null,this.currentConversation=void 0,this.currentConversionID=void 0,this.cookie="",this.colors={primary:"#FED21F",secondary:"#000"},this.serviceName=y.bgHex(this.colors.primary).hex(this.colors.secondary).bold(`[HuggingFace${this.formatModelSuffix()}]`),this.errorPrefix=y.red.bold(`[HuggingFace${this.formatModelSuffix()}]`),this.cookie=this.params.config.cookie;const e=this.params.config.url||"https://huggingface.co";this.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:e,"Referrer-Policy":"strict-origin-when-cross-origin"}}getServiceSpecificErrorMessage(o){const e=o.message||"";return e.includes("cookie")||e.includes("Cookie")?"Invalid cookie. Check your Hugging Face session cookie in configuration":e.includes("model")||e.includes("Model")?"Model not found or not accessible. Check if the Hugging Face model name is correct":e.includes("conversation")||e.includes("conversion")?"Failed to create conversation. Try again or check your session":e.includes("401")||e.includes("Unauthorized")?"Authentication failed. Your Hugging Face session may have expired":e.includes("403")||e.includes("Forbidden")?"Access denied. You may not have permission to access this model":e.includes("404")||e.includes("Not Found")?"Model not found. Check your Hugging Face model configuration":e.includes("500")||e.includes("Internal Server Error")?"Hugging Face server error. Try again later":e.includes("overloaded")||e.includes("capacity")?"Hugging Face service is overloaded. Try again in a few minutes":null}generateCommitMessage$(){return E(this.generateMessage("commit")).pipe(C(o=>b(o)),k(this.formatAsChoice),D(this.handleError$))}generateCodeReview$(){return E(this.generateMessage("review")).pipe(C(o=>b(o)),k(this.formatCodeReviewAsChoice),D(this.handleError$))}async generateMessage(o){await this.initialize();const e=this.params.stagedDiff.diff,{logging:r,generate:t,type:l,temperature:m,maxTokens:i,topP:g,timeout:s}=this.params.config,p=this.buildPromptOptions(),a=o==="review"?R(p):S(p),w=`Here is the diff: ${e}`,f=`${this.params.config.url||"https://huggingface.co"}/chat/conversation`,n={...this.headers,cookie:this.cookie};M(e,o,"HuggingFace",this.params.config.model,f,n,r),A(e,o,"HuggingFace",a,w,r);const d=Date.now();try{const c=await this.getNewChat(a),u=await(await this.sendMessage(w,c.id)).completeResponsePromise();await this.deleteConversation(c.id);const F=Date.now()-d;return P(e,o,"HuggingFace",{response:u},r),$(e,o,"HuggingFace",F,u,r),o==="review"?this.parseCodeReview(u):this.parseMessage(u,l,t)}catch(c){throw H(e,o,"HuggingFace",c,r),c}}async initialize(){const o=await this.getRemoteLlms(),e=o.find(r=>r.name?.toLowerCase()===this.params.config.model.toLowerCase());if(e){this.currentModel=e,this.currentModelId=e.id;return}this.currentModel=o[0],this.currentModelId=o[0].id}async getRemoteLlms(){const o=this.params.config.url||"https://huggingface.co",e=await fetch(`${o}/chat/__data.json`,{headers:{...this.headers,cookie:this.cookie},body:null,method:"GET"});if(e.status!==200)throw new Error(`Failed to get remote LLMs with status code: ${e.status}`);const t=(await e.json()).nodes[0].data,l=t[t[0].models],m=[],i=g=>g===-1?null:t[g];for(const g of l){const s=t[g];if(t[s.unlisted])continue;const p={id:i(s.id),name:i(s.name),displayName:i(s.displayName),preprompt:i(s.preprompt),promptExamples:[],websiteUrl:i(s.websiteUrl),description:i(s.description),datasetName:i(s.datasetName),datasetUrl:i(s.datasetUrl),modelUrl:i(s.modelUrl),parameters:{}},a=i(s.promptExamples);if(a!==null){const f=a.map(n=>i(n));p.promptExamples=f.map(n=>({title:t[n.title],prompt:t[n.prompt]}))}const w=i(s.parameters),h={};for(const[f,n]of Object.entries(w)){if(n===-1){h[f]=null;continue}if(Array.isArray(t[n])){h[f]=t[n].map(d=>t[d]);continue}h[f]=t[n]}p.parameters=h,m.push(p)}return this.models=m,m}async getNewChat(o){const e={model:this.currentModelId,preprompt:o};let r=0;const t=this.params.config.url||"https://huggingface.co";for(;r<5;){const l=await fetch(`${t}/chat/conversation`,{headers:{...this.headers,"content-type":"application/json",cookie:this.cookie,Referer:`${t}/chat/`},body:JSON.stringify(e),method:"POST"}),{conversationId:m}=await l.json();if(m){this.currentConversionID=m;break}else r++}if(!this.currentConversionID)throw new Error("Failed to create new conversion");return await this.getConversationHistory(this.currentConversionID)}async getConversationHistory(o){if(!o)throw new Error("conversationId is required for getConversationHistory");const e=this.params.config.url||"https://huggingface.co",r=await fetch(`${e}/chat/conversation/${o}/__data.json`,{headers:{...this.headers,cookie:this.cookie,Referer:`${e}/chat/`},body:null,method:"GET"});if(r.status!=200)throw new Error("Unable get conversation details "+r);{const t=await r.json();return this.metadataParser(t,o)}}metadataParser(o,e){const r={id:"",model:"",systemPrompt:"",title:"",history:[]},t=o.nodes[1].data,l=t[t[0].model],m=t[t[0].preprompt],i=t[t[0].title],g=t[t[0].messages],s=[];for(const p of g){const a=t[p],w=new Date(t[a.createdAt][1]).getTime()/1e3,h=new Date(t[a.updatedAt][1]).getTime()/1e3;s.push({id:t[a.id],role:t[a.from],content:t[a.content],createdAt:w,updatedAt:h})}return r.id=e,r.model=l,r.systemPrompt=m,r.title=i,r.history=s,this.currentConversation=r,r}async sendMessage(o,e){if(o==="")throw new Error("the prompt can not be empty.");if(!e&&!this.currentConversionID?await this.getNewChat():e?(this.currentConversionID=e,await this.getConversationHistory(e)):this.currentConversionID&&await this.getConversationHistory(this.currentConversionID),!this.currentConversation)throw new Error("Failed to create new conversion");const r={inputs:o,id:this.currentConversation.history[this.currentConversation.history.length-1].id,is_retry:!1,is_continue:!1,web_search:!1,tools:[]},t=new FormData;t.append("data",JSON.stringify(r));const l=this.params.config.url||"https://huggingface.co",m=new AbortController,i=setTimeout(()=>m.abort(),this.params.config.timeout),g=await fetch(`${l}/chat/conversation/${this.currentConversionID}`,{headers:{...this.headers,cookie:this.cookie,Referer:`${l}/chat/conversation/${this.currentConversionID}`},body:t,method:"POST",signal:m.signal});clearTimeout(i);function s(n){try{const d=n.split(` `),c=[];for(const v of d)v.trim()&&c.push(JSON.parse(v));return c}catch{return[{}]}}const p=new TextDecoder;let a="";const w=new TransformStream({async transform(n,d){const c=p.decode(n);try{const v=s(c);for(const u of v)u.type==="finalAnswer"?(a=u?.text||"",d.terminate()):u.type==="stream"&&d.enqueue(u?.token||"")}catch{throw new Error("Error during parsing response")}}}),h=g.body?.pipeThrough(w);async function f(){return new Promise(async(n,d)=>{try{if(!h)d("ModifiedStream undefined");else{const c=h.getReader();for(;;){const{done:v,value:u}=await c.read();if(v){n(a);break}}}}catch(c){d(c)}})}return{id:this.currentConversionID,stream:h,completeResponsePromise:f}}async deleteConversation(o){const e=this.params.config.url||"https://huggingface.co";return(await fetch(`${e}/chat/conversation/${o}`,{headers:{...this.headers,cookie:this.cookie,Referer:`${e}/chat/`},body:null,method:"DELETE"})).json()}}export{U as HuggingFaceService};