ai21
Version:
AI21 TypeScript SDK
3 lines (2 loc) • 8.89 kB
JavaScript
(function(a,h){typeof exports=="object"&&typeof module<"u"?h(exports):typeof define=="function"&&define.amd?define(["exports"],h):(a=typeof globalThis<"u"?globalThis:a||self,h(a.MySDK={}))})(this,function(a){"use strict";var O,L,N,M;const h="https://api.ai21.com/studio/v1",l=class l{};l.API_KEY=process.env.AI21_API_KEY??void 0,l.BASE_URL=process.env.AI21_BASE_URL??h,l.TIMEOUT_SECONDS=process.env.AI21_TIMEOUT_SECONDS?Number(process.env.AI21_TIMEOUT_SECONDS):6e4,l.MAX_RETRIES=process.env.AI21_MAX_RETRIES?Number(process.env.AI21_MAX_RETRIES):3,l.LOG_LEVEL=process.env.AI21_LOG_LEVEL??"info";let d=l;class c extends Error{}class S extends c{constructor(){super("API key is required")}}class E extends Error{constructor(e){super(`Failed to decode chunk: ${e}`)}}class f{constructor(e){this.client=e}}const q=["jamba-1.5-mini","jamba-1.5-large"];class b extends f{create(e,t){return q.includes(e.model)&&console.warn(`Warning: The model "${e.model}" is deprecated and will be removed in a future release.
Please use jamba-mini or jamba-large instead.`),this.client.post("/chat/completions",{body:e,...t,stream:e.stream??!1})}}class A extends f{constructor(){super(...arguments),this.completions=new b(this.client)}}const R="1.1.1";class g{}class x extends g{async prepareFormDataRequest(e){const t=new FormData;return t.append("file",e),{formData:t,headers:{}}}}class I{async handleResponse({response:e,options:t}){if(t.stream){if(!e.body)throw new c("Response body is null");return this.handleStream(e)}const r=e.headers.get("content-type");return r!=null&&r.includes("application/json")?await e.json():null}}const F="data: ",H="[DONE]";class v{decode(e){if(!e)return null;if(e.startsWith(F))return e.slice(F.length);throw new E(`Invalid SSE line: ${e}`)}async*_iterLines(e){for(const t of e)if(t.trim()){const r=this.decode(t);r&&(yield r)}}async*readBuffer(e){if(e.trim()){const t=this.decode(e);t&&(yield t)}}}class T extends v{async*iterLines(e){if(!e.body)throw new Error("Response body is null");const t=e.body.getReader(),r=new TextDecoder;let s="";try{for(;;){const{done:o,value:i}=await t.read();if(o)break;s+=r.decode(i,{stream:!0});const u=s.split(/\r\n|\n/);s=u.pop()||"",yield*this._iterLines(u)}yield*this.readBuffer(s)}finally{t.releaseLock()}}}class P extends v{async*iterLines(e){if(!e.body)throw new Error("Response body is null");const t=e.body;let r="";for await(const s of t){const o=typeof s=="string"?s:s.toString("utf-8");r+=o;const i=r.split(/\r\n|\n/);r=i.pop()||"",yield*this._iterLines(i)}yield*this.readBuffer(r)}}function j(n){try{return JSON.parse(n)}catch{throw new E(n)}}class m{constructor(e,t){this.response=e,this.decoder=t||new T,this.iterator=this.stream()}async*stream(){for await(const e of this.decoder.iterLines(this.response)){if(e===H)break;yield j(e)}}async next(){return this.iterator.next()}[Symbol.asyncIterator](){return this}}class k extends I{call(e,t){const r=new AbortController;return fetch(e,{method:t.method,headers:t!=null&&t.headers?t.headers:void 0,body:t!=null&&t.body?t.body:void 0,signal:r.signal})}handleStream(e){return new m(e,new T)}}class C extends I{async call(e,t){const s=(await import("node-fetch")).default;return s(e,{method:t.method,headers:t!=null&&t.headers?t.headers:void 0,body:t!=null&&t.body?t.body:void 0})}handleStream(e){return new m(e,new P)}}const w=typeof window<"u"&&typeof window.document<"u",_=typeof self=="object"&&typeof(self==null?void 0:self.importScripts)=="function"&&(((O=self.constructor)==null?void 0:O.name)==="DedicatedWorkerGlobalScope"||((L=self.constructor)==null?void 0:L.name)==="ServiceWorkerGlobalScope"||((N=self.constructor)==null?void 0:N.name)==="SharedWorkerGlobalScope"),y=typeof process<"u"&&!!process.version&&!!((M=process.versions)!=null&&M.node);class W extends g{async convertReadableStream(e){if(!y)throw new Error("Stream conversion is not supported in browser environment");const{Readable:t}=await import("stream"),r=e.getReader();return new t({async read(){const{done:s,value:o}=await r.read();s?this.push(null):this.push(o)}})}async createStreamFromFilePath(e,t){if(!y)throw new Error("File system operations are not supported in browser environment");const r=await import("fs").then(s=>s.default||s);if(!r.existsSync(e))throw new Error(`File not found: ${e}`);t.append("file",r.createReadStream(e),{filename:e.split("/").pop()})}async prepareFormDataRequest(e){try{const t=await import("form-data").then(s=>s.default||s),r=new t;if(typeof e=="string")return await this.createStreamFromFilePath(e,r),this.createFormDataRequest(r);if(!e||typeof e!="object")throw new Error(`Unsupported file type for Node.js file upload flow: ${e}`);if("buffer"in e)return r.append("file",e.buffer,{filename:e.name,contentType:e.type}),this.createFormDataRequest(r);if("stream"in e&&typeof e.stream=="function"){const s=await this.convertReadableStream(e.stream());return r.append("file",s,{filename:e.name,contentType:e.type}),this.createFormDataRequest(r)}throw new Error(`Unsupported file type for Node.js file upload flow: ${e}`)}catch(t){throw console.error("Error in prepareFormDataRequest:",t),t}}createFormDataRequest(e){return{formData:e,headers:{"Content-Type":`multipart/form-data; boundary=${e.getBoundary()}`}}}}function K(){return w||_?new k:new C}function G(){return w||_?new x:new W}const D=(n,e)=>{if(typeof e!="number"||!Number.isInteger(e))throw new c(`${n} must be an integer`);if(e<0)throw new c(`${n} must be a positive integer`);return e},X=(n,e)=>{for(const[t,r]of Object.entries(e))Array.isArray(r)?r.forEach(s=>n.append(t,s)):n.append(t,r)};class U{constructor({baseURL:e,maxRetries:t=d.MAX_RETRIES,timeout:r=d.TIMEOUT_SECONDS,fetch:s=K(),filesHandler:o=G()}){this.baseURL=e,this.maxRetries=D("maxRetries",t),this.timeout=D("timeout",r),this.fetch=s,this.filesHandler=o}get(e,t){return this.prepareAndExecuteRequest("get",e,t)}post(e,t){return this.prepareAndExecuteRequest("post",e,t)}put(e,t){return this.prepareAndExecuteRequest("put",e,t)}delete(e,t){return this.prepareAndExecuteRequest("delete",e,t)}upload(e,t,r){return this.filesHandler.prepareFormDataRequest(t).then(s=>{r!=null&&r.body&&X(s.formData,r.body);const o={...r==null?void 0:r.headers,...s.headers},i={method:"post",path:e,body:s.formData,headers:o};return this.performRequest(i).then(u=>this.fetch.handleResponse(u))})}getUserAgent(){const e=this.isRunningInBrowser()?`browser/${typeof window<"u"?window.navigator.userAgent:"unknown"}`:`node/${process.version}`;return`AI21 Typescript SDK ${R} ${e}`}defaultHeaders(e){return{...{Accept:"application/json","User-Agent":this.getUserAgent(),...this.authHeaders(e)},...e.headers}}authHeaders(e){return{}}buildFullUrl(e,t){let r=`${this.baseURL}${e}`;if(t){const s=new URLSearchParams(t).toString();r+=`?${s}`}return r}prepareAndExecuteRequest(e,t,r){const s={method:e,path:t,...r};return s!=null&&s.body&&(s.body=JSON.stringify(s.body),s.headers={...s.headers,"Content-Type":"application/json"}),this.performRequest(s).then(o=>this.fetch.handleResponse(o))}async performRequest(e){const t=this.buildFullUrl(e.path,e.query),r={...this.defaultHeaders(e),...e.headers},s=await this.fetch.call(t,{...e,headers:r});if(!s.ok)throw new c(`Request failed with status ${s.status}. ${await s.text()}`);return{response:s,options:e}}isRunningInBrowser(){return typeof window<"u"&&typeof window.document<"u"&&typeof fetch=="function"}}class $ extends f{create(e,t){return this.client.post("/conversational-rag",{body:e,...t})}}const p="/library/files";class B extends f{async create(e,t){const{file:r,...s}=e;return this.client.upload(p,r,{body:s,...t})}get(e,t){return this.client.get(`${p}/${e}`,t)}delete(e,t){return this.client.delete(`${p}/${e}`,t)}list(e,t){return this.client.get(p,{query:e,...t})}update(e,t){return this.client.put(`${p}/${e.fileId}`,{body:e,...t})}}class V extends U{constructor({apiKey:e=d.API_KEY,baseURL:t=d.BASE_URL,timeout:r=d.TIMEOUT_SECONDS,maxRetries:s,via:o,...i}={}){const u={apiKey:e,baseURL:t,timeout:r,maxRetries:s,via:o,...i};if(!u.dangerouslyAllowBrowser&&w)throw new c("AI21 client is not supported in the browser by default due to potential API key exposure. Use `dangerouslyAllowBrowser` option to `true` to override it.");if(e===void 0)throw new S;super({baseURL:t,timeout:r,maxRetries:s}),this.chat=new A(this),this.conversationalRag=new $(this),this.files=new B(this),this.apiKey=e,this.via=o??null,this.options=u}authHeaders(e){return{Authorization:`Bearer ${this.apiKey}`}}defaultHeaders(e){return{...super.defaultHeaders(e),"User-Agent":this.getUserAgent()}}getUserAgent(){let e=super.getUserAgent();return this.via&&(e+=` via ${this.via}`),e}}a.AI21=V,a.AI21Error=c,a.APIClient=U,a.APIResource=f,a.Chat=A,a.Completions=b,a.ConversationalRag=$,a.Files=B,a.MissingAPIKeyError=S,a.Stream=m,a.VERSION=R,a.isBrowser=w,a.isNode=y,Object.defineProperty(a,Symbol.toStringTag,{value:"Module"})});