spark-desk
Version:
使用WebSocket调用 讯飞星火认知大模型 的js库
3 lines (2 loc) • 8.12 kB
JavaScript
;var t=require("commander"),e=require("crypto-js"),o=require("ws"),n=require("node:fs/promises"),s=require("node:path"),r=require("node:readline");function i(t){var e=Object.create(null);return t&&Object.keys(t).forEach((function(o){if("default"!==o){var n=Object.getOwnPropertyDescriptor(t,o);Object.defineProperty(e,o,n.get?n:{enumerable:!0,get:function(){return t[o]}})}})),e.default=t,Object.freeze(e)}var a=i(n),c=i(s),h=i(r);function u(t,e,o,n){return new(o||(o=Promise))((function(s,r){function i(t){try{c(n.next(t))}catch(t){r(t)}}function a(t){try{c(n.throw(t))}catch(t){r(t)}}function c(t){var e;t.done?s(t.value):(e=t.value,e instanceof o?e:new o((function(t){t(e)}))).then(i,a)}c((n=n.apply(t,e||[])).next())}))}"function"==typeof SuppressedError&&SuppressedError;var d;!function(t){t.Ultra="Ultra",t.Max32k="Max32k",t.Max="Max",t.Pro128k="Pro128k",t.Pro="Pro",t.Lite="Lite"}(d||(d={}));const l={[d.Ultra]:"4.0Ultra",[d.Max32k]:"max-32k",[d.Max]:"generalv3.5",[d.Pro128k]:"pro-128k",[d.Pro]:"generalv3",[d.Lite]:"lite"};class p{constructor(t,e=.5,o=2048,n=4,s){this.domain=t,this.temperature=e,this.max_tokens=o,this.top_k=n,this.chat_id=s}static createFromVersion(t){if(t in l)return new p(l[t]);throw new Error("不存在的版本.")}toValue(){return{chat:{domain:this.domain,temperature:this.temperature,max_tokens:this.max_tokens,top_k:this.top_k,chat_id:this.chat_id}}}}var k,m;!function(t){t.Assistant="assistant",t.User="user",t.System="system"}(k||(k={}));class v{constructor(){this.history=[]}static generateUid(){return Math.random().toString(36).substring(2,16)}getHistory(t){const e=[];for(let o of this.history){if(!(0+this.getMessageLength(o)<=t))return e;e.push(o)}return e}}class w extends v{getMessageLength(t){throw t.content.length}constructor(t,e=v.generateUid(),o=5e3){super(),this.spark=t,this.uid=e,this.tokenLength=o,this.history=[],this.systemContent=null}speak(t,e=p.createFromVersion(this.spark.version),o){var n,s,r;return u(this,void 0,void 0,(function*(){if(t.length<=0)throw new Error("内容不可以为空.");const i=yield this.spark.request({header:{app_id:this.spark.APPID,uid:this.uid},parameter:e.toValue(),payload:{message:{text:[...this.getHistory(),{role:k.User,content:t}]}}},6e4,o);return this.history.push({role:k.User,content:t}),this.history.push({role:k.Assistant,content:i.getAllContent()}),{content:i.getAllContent(),promptTokens:null!==(n=i.getPromptTokens())&&void 0!==n?n:-1,completionTokens:null!==(s=i.getCompletionTokens())&&void 0!==s?s:-1,totalTokens:null!==(r=i.getTotalTokens())&&void 0!==r?r:-1,sid:i.getSid()}}))}getHistory(t=this.tokenLength){const e=[];null!==this.systemContent&&this.systemContent.length>0&&e.push({role:k.System,content:this.systemContent});for(let o of this.history){if(!(0+o.content.length<=t))return e;e.push(o)}return e}setSystemContent(t){this.systemContent=t}}!function(t){t[t.Browser=0]="Browser",t[t.Node=1]="Node"}(m||(m={}));class g{constructor(t){this.url=t,this.environment=g.getEnvironment(),this.environment===m.Browser?this.webSocket=new WebSocket(t):this.webSocket=new o(t)}static getEnvironment(){return"undefined"!=typeof window?m.Browser:m.Node}addEventListener(t,e,n){(this.environment===m.Browser&&this.webSocket instanceof WebSocket||this.webSocket instanceof o)&&this.webSocket.addEventListener(t,e,n)}removeEventListener(t,e,n){(this.environment===m.Browser&&this.webSocket instanceof WebSocket||this.webSocket instanceof o)&&this.webSocket.removeEventListener(t,e,n)}close(){this.webSocket.close()}send(t){this.webSocket.send(t)}}class y{constructor(t){this.websocketResponses=t}getAllContent(){return this.hasError(),this.websocketResponses.map((t=>t.payload.choices.text.map((t=>t.content)).join(""))).join("")}getPromptTokens(){var t,e;return this.hasError(),null===(e=null===(t=this.websocketResponses.at(-1))||void 0===t?void 0:t.payload.usage)||void 0===e?void 0:e.text.prompt_tokens}getCompletionTokens(){var t,e;return this.hasError(),null===(e=null===(t=this.websocketResponses.at(-1))||void 0===t?void 0:t.payload.usage)||void 0===e?void 0:e.text.completion_tokens}getTotalTokens(){var t,e;return this.hasError(),null===(e=null===(t=this.websocketResponses.at(-1))||void 0===t?void 0:t.payload.usage)||void 0===e?void 0:e.text.total_tokens}hasError(){this.websocketResponses.forEach((t=>{if(0!==t.header.code)throw new Error(JSON.stringify(t))}))}getSid(){const[t=null]=this.websocketResponses;if(null===t)throw new Error("没有相应任何内容");return t.header.sid}}const f={[d.Ultra]:"wss://spark-api.xf-yun.com/v4.0/chat",[d.Max32k]:"wss://spark-api.xf-yun.com/chat/max-32k",[d.Max]:"wss://spark-api.xf-yun.com/v3.5/chat",[d.Pro128k]:" wss://spark-api.xf-yun.com/chat/pro-128k",[d.Pro]:"wss://spark-api.xf-yun.com/v3.1/chat",[d.Lite]:"wss://spark-api.xf-yun.com/v1.1/chat"};class S{}class P extends S{get version(){return this.option.version}constructor(t){super(),this.option=t}get APPID(){return this.option.APPID}getWebsocketUrl(){const t=this.option.APIKey,o=this.option.APISecret,n=this.getUrl();this.option.noEncryption&&(n.protocol="ws");const s=n.host,r=(new Date).toUTCString(),i=`host: ${s}\ndate: ${r}\nGET ${n.pathname} HTTP/1.1`,a=e.HmacSHA256(i,o),c=e.enc.Base64.stringify(a);return`${n}?authorization=${btoa(`api_key="${t}", algorithm="hmac-sha256", headers="host date request-line", signature="${c}"`)}&date=${r}&host=${s}`}getUrl(){if(this.option.version in f)return new URL(f[this.option.version]);throw new Error("不存在的版本.")}request(t,e=6e4,o){return u(this,void 0,void 0,(function*(){return new Promise(((n,s)=>{const r=setTimeout((()=>{s(new Error("请求超时")),i&&i.close()}),e),i=new g(this.getWebsocketUrl()),a=[];i.addEventListener("open",(()=>{i.send(JSON.stringify(t))})),i.addEventListener("message",(t=>{o&&o(t);const e=JSON.parse(t.data.toString());a.push(e)})),i.addEventListener("close",(()=>{clearTimeout(r),n(new y(a))})),i.addEventListener("error",s)}))}))}createUser(t,e){return new w(this,t,e)}}const E=h.createInterface({input:process.stdin,output:process.stdout});const b=new t.Command;b.name("星火大模型").description("通过命令行简单的使用星火大模型。").version("1.4.1"),b.argument("[question]","对星火大模型提出的问题。").option("-u,--uid <uid>","指定UID,默认为 spark-desk。","spark-desk").option("-l,--tokenLength <length>","指定历史问答信息的token长度,1tokens 约等于1.5个中文汉字 或者 0.8个英文单词。默认为 0,没有上下文。","0").action(((t,e)=>u(void 0,void 0,void 0,(function*(){const o=yield function(){return u(this,void 0,void 0,(function*(){const t=process.env.HOME||process.env.USERPROFILE;if(!t)throw new Error("无法读取用户目录,无法读取用户配置文件.");const e=c.join(t,".spark-desk");try{yield a.access(e);try{JSON.parse(yield a.readFile(e).then((t=>t.toString())))}catch(t){t instanceof SyntaxError&&(console.error("配置文件格式错误,请检查配置文件: "+e.toString()),process.exit(-1))}}catch(t){const o=yield new Promise((t=>E.question("请输入 APPID:",t))),n=yield new Promise((t=>E.question("请输入 APISecret:",t))),s=yield new Promise((t=>E.question("请输入 APIKey:",t)));yield a.writeFile(e,JSON.stringify({APPID:o,APISecret:n,APIKey:s,version:d.Lite,noEncryption:!1,uid:"spark-desk"},void 0,"\t"))}return a.readFile(e).then((t=>JSON.parse(t.toString())))}))}().catch((t=>{throw new Error("读取配置失败:"+t.toString())})),n=new P(o),s=(null==e?void 0:e.uid)||o.uid,r=new w(n,s,parseInt(e.tokenLength));function i(t){return u(this,void 0,void 0,(function*(){try{const e=yield r.speak(t,p.createFromVersion(n.version),(t=>{process.stdout.write(new y([JSON.parse(t.toString())]).getAllContent())}));process.stdout.write(`[${e.promptTokens}/${e.completionTokens}/${e.totalTokens}]\n`)}catch(t){process.stdout.write((null==t?void 0:t.toString())+"\n")}finally{E.prompt()}}))}E.setPrompt(s+" > "),"string"==typeof t&&t.length>=0?yield i(t):E.prompt(),E.addListener("line",i),E.addListener("close",(()=>process.stdout.write("感谢您的使用.")))})))),b.parse();