UNPKG

ai21

Version:

AI21 TypeScript SDK

434 lines (433 loc) 11.7 kB
const T = "https://api.ai21.com/studio/v1"; const c = class c { }; c.API_KEY = process.env.AI21_API_KEY ?? void 0, c.BASE_URL = process.env.AI21_BASE_URL ?? T, c.TIMEOUT_SECONDS = process.env.AI21_TIMEOUT_SECONDS ? Number(process.env.AI21_TIMEOUT_SECONDS) : 6e4, c.MAX_RETRIES = process.env.AI21_MAX_RETRIES ? Number(process.env.AI21_MAX_RETRIES) : 3, c.LOG_LEVEL = process.env.AI21_LOG_LEVEL ?? "info"; let d = c; class l extends Error { } class D extends l { constructor() { super("API key is required"); } } class R extends Error { constructor(e) { super(`Failed to decode chunk: ${e}`); } } class h { constructor(e) { this.client = e; } } const x = ["jamba-1.5-mini", "jamba-1.5-large"]; class U extends h { create(e, t) { return x.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 $ extends h { constructor() { super(...arguments), this.completions = new U(this.client); } } const B = "1.1.1"; class A { } class L extends A { async prepareFormDataRequest(e) { const t = new FormData(); return t.append("file", e), { formData: t, headers: {} }; } } class g { async handleResponse({ response: e, options: t }) { if (t.stream) { if (!e.body) throw new l("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 p = "data: ", O = "[DONE]"; class F { decode(e) { if (!e) return null; if (e.startsWith(p)) return e.slice(p.length); throw new R(`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 I extends F { 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: a, value: o } = await t.read(); if (a) break; s += r.decode(o, { stream: !0 }); const i = s.split(/\r\n|\n/); s = i.pop() || "", yield* this._iterLines(i); } yield* this.readBuffer(s); } finally { t.releaseLock(); } } } class N extends F { 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 a = typeof s == "string" ? s : s.toString("utf-8"); r += a; const o = r.split(/\r\n|\n/); r = o.pop() || "", yield* this._iterLines(o); } yield* this.readBuffer(r); } } function q(n) { try { return JSON.parse(n); } catch { throw new R(n); } } class v { constructor(e, t) { this.response = e, this.decoder = t || new I(), this.iterator = this.stream(); } async *stream() { for await (const e of this.decoder.iterLines(this.response)) { if (e === O) break; yield q(e); } } async next() { return this.iterator.next(); } [Symbol.asyncIterator]() { return this; } } class M extends g { 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 v(e, new I()); } } class H extends g { 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 v(e, new N()); } } const f = typeof window < "u" && typeof window.document < "u"; var y, S, E; const _ = typeof self == "object" && typeof (self == null ? void 0 : self.importScripts) == "function" && (((y = self.constructor) == null ? void 0 : y.name) === "DedicatedWorkerGlobalScope" || ((S = self.constructor) == null ? void 0 : S.name) === "ServiceWorkerGlobalScope" || ((E = self.constructor) == null ? void 0 : E.name) === "SharedWorkerGlobalScope"); var b; const w = typeof process < "u" && !!process.version && !!((b = process.versions) != null && b.node); class k extends A { async convertReadableStream(e) { if (!w) 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: a } = await r.read(); s ? this.push(null) : this.push(a); } }); } // eslint-disable-next-line @typescript-eslint/no-explicit-any async createStreamFromFilePath(e, t) { if (!w) 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; } } // eslint-disable-next-line @typescript-eslint/no-explicit-any createFormDataRequest(e) { return { formData: e, headers: { "Content-Type": `multipart/form-data; boundary=${e.getBoundary()}` } }; } } function j() { return f || _ ? new M() : new H(); } function P() { return f || _ ? new L() : new k(); } const m = (n, e) => { if (typeof e != "number" || !Number.isInteger(e)) throw new l(`${n} must be an integer`); if (e < 0) throw new l(`${n} must be a positive integer`); return e; }, W = (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 C { constructor({ baseURL: e, maxRetries: t = d.MAX_RETRIES, timeout: r = d.TIMEOUT_SECONDS, fetch: s = j(), filesHandler: a = P() }) { this.baseURL = e, this.maxRetries = m("maxRetries", t), this.timeout = m("timeout", r), this.fetch = s, this.filesHandler = a; } 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 && W(s.formData, r.body); const a = { ...r == null ? void 0 : r.headers, ...s.headers }, o = { method: "post", path: e, body: s.formData, headers: a }; return this.performRequest(o).then((i) => this.fetch.handleResponse(i)); }); } getUserAgent() { const e = this.isRunningInBrowser() ? `browser/${typeof window < "u" ? window.navigator.userAgent : "unknown"}` : `node/${process.version}`; return `AI21 Typescript SDK ${B} ${e}`; } defaultHeaders(e) { return { ...{ Accept: "application/json", "User-Agent": this.getUserAgent(), ...this.authHeaders(e) }, ...e.headers }; } // eslint-disable-next-line @typescript-eslint/no-unused-vars 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((a) => this.fetch.handleResponse(a)); } 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 l(`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 G extends h { create(e, t) { return this.client.post("/conversational-rag", { body: e, ...t }); } } const u = "/library/files"; class K extends h { async create(e, t) { const { file: r, ...s } = e; return this.client.upload(u, r, { body: s, ...t }); } get(e, t) { return this.client.get( `${u}/${e}`, t ); } delete(e, t) { return this.client.delete( `${u}/${e}`, t ); } list(e, t) { return this.client.get(u, { query: e, ...t }); } update(e, t) { return this.client.put(`${u}/${e.fileId}`, { body: e, ...t }); } } class X extends C { constructor({ apiKey: e = d.API_KEY, baseURL: t = d.BASE_URL, timeout: r = d.TIMEOUT_SECONDS, maxRetries: s, via: a, ...o } = {}) { const i = { apiKey: e, baseURL: t, timeout: r, maxRetries: s, via: a, ...o }; if (!i.dangerouslyAllowBrowser && f) throw new l( "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 D(); super({ baseURL: t, timeout: r, maxRetries: s }), this.chat = new $(this), this.conversationalRag = new G(this), this.files = new K(this), this.apiKey = e, this.via = a ?? null, this.options = i; } // eslint-disable-next-line @typescript-eslint/no-unused-vars 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; } } export { X as AI21, l as AI21Error, C as APIClient, h as APIResource, $ as Chat, U as Completions, G as ConversationalRag, K as Files, D as MissingAPIKeyError, v as Stream, B as VERSION, f as isBrowser, w as isNode };