UNPKG

@zhengxs/erniebot

Version:

非官方 JS-SDK,可以调用文心大模型的能力,包含文本创作、通用对话、语义向量、AI作图等

824 lines (821 loc) 25.2 kB
var V = (n, e, t) => { if (!e.has(n)) throw TypeError("Cannot " + t); }; var m = (n, e, t) => (V(n, e, "read from private field"), t ? t.call(n) : e.get(n)), x = (n, e, t) => { if (e.has(n)) throw TypeError("Cannot add the same private member more than once"); e instanceof WeakSet ? e.add(n) : e.set(n, t); }, v = (n, e, t, s) => (V(n, e, "write to private field"), s ? s.call(n, t) : e.set(n, t), t); const C = Object.prototype.toString.call(typeof process < "u" ? process : 0) === "[object process]", te = !C && typeof Deno < "u", re = !(C || te) && typeof window < "u", he = {}; function le() { return globalThis; } let de = le(); const N = () => de, g = (n) => C ? process.env[n] ?? void 0 : te ? Deno.env.get(n) : N()[n]; function I(n) { const e = g("DEBUG") === "true"; return function(s, ...r) { e && console.log("[%s]:[%s]", n, s, ...r); }; } const U = (n) => n instanceof Error ? n : new Error(n), fe = (n) => { try { return JSON.parse(n); } catch { return; } }; let d = class extends Error { }; class ne extends d { } class se extends d { } let l = class q extends d { constructor(e, t, s, r) { super(`${q.makeMessage(e, t, s)}`), this.status = e, this.headers = r; const o = t; this.error = o, this.code = o == null ? void 0 : o.code, this.param = o == null ? void 0 : o.param, this.type = o == null ? void 0 : o.type; } static makeMessage(e, t, s) { const r = t != null && t.message ? typeof t.message == "string" ? t.message : JSON.stringify(t.message) : t ? JSON.stringify(t) : s; return e && r ? `${e} ${r}` : e ? `${e} status code (no body)` : r || "(no status code or body)"; } static generate(e, t, s, r) { if (!e) return new k({ cause: U(t) }); const o = t == null ? void 0 : t.error; return e === 400 ? new $(e, o, s, r) : e === 401 ? new D(e, o, s, r) : e === 403 ? new O(e, o, s, r) : e === 404 ? new j(e, o, s, r) : e === 409 ? new H(e, o, s, r) : e === 422 ? new M(e, o, s, r) : e === 429 ? new Q(e, o, s, r) : e >= 500 ? new W(e, o, s, r) : new q(e, o, s, r); } }, T = class extends l { constructor({ message: e } = {}) { super(void 0, void 0, e || "Request was aborted.", void 0), this.status = void 0; } }, k = class extends l { constructor({ message: e, cause: t }) { super(void 0, void 0, e || "Connection error.", void 0), this.status = void 0, t && (this.cause = t); } }, _ = class extends k { constructor({ message: e } = {}) { super({ message: e ?? "Request timed out." }); } }, $ = class extends l { constructor() { super(...arguments), this.status = 400; } }, D = class extends l { constructor() { super(...arguments), this.status = 401; } }, O = class extends l { constructor() { super(...arguments), this.status = 403; } }, j = class extends l { constructor() { super(...arguments), this.status = 404; } }, H = class extends l { constructor() { super(...arguments), this.status = 409; } }, M = class extends l { constructor() { super(...arguments), this.status = 422; } }, Q = class extends l { constructor() { super(...arguments), this.status = 429; } }, W = class extends l { }; const pe = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, APIConnectionError: k, APIConnectionTimeoutError: _, APIError: l, APIUserAbortError: T, AuthenticationError: D, BadRequestError: $, ConflictError: H, EBError: d, InternalServerError: W, InvalidArgumentError: ne, NotFoundError: j, PermissionDeniedError: O, RateLimitError: Q, UnprocessableEntityError: M, UnsupportedAPITypeError: se }, Symbol.toStringTag, { value: "Module" })); class y { constructor(e, t) { this.iterator = e, this.controller = t; } static fromSSEResponse(e, t) { let s = !1; const r = new me(); async function* o() { if (!e.body) throw t.abort(), new d("Attempted to iterate over a response with no body"); const i = new X(), c = Y(e.body); for await (const u of c) for (const f of i.decode(u)) { const A = r.decode(f); A && (yield A); } for (const u of i.flush()) { const f = r.decode(u); f && (yield f); } } async function* a() { if (s) throw new Error("Cannot iterate over a consumed stream, use `.tee()` to split the stream."); s = !0; let i = !1; try { for await (const c of o()) if (!i) { if (c.data.startsWith("[DONE]")) { i = !0; continue; } if (c.event === null) { let u; try { u = JSON.parse(c.data); } catch (f) { throw console.error("Could not parse message into JSON:", c.data), console.error("From chunk:", c.raw), f; } if (u && u.error) throw new l(void 0, u.error, void 0, void 0); yield u; } } i = !0; } catch (c) { if (c instanceof Error && c.name === "AbortError") return; throw c; } finally { i || t.abort(); } } return new y(a, t); } // Generates a Stream from a newline-separated ReadableStream where each item // is a JSON Value. static fromReadableStream(e, t) { let s = !1; async function* r() { const a = new X(), i = Y(e); for await (const c of i) for (const u of a.decode(c)) yield u; for (const c of a.flush()) yield c; } async function* o() { if (s) throw new Error("Cannot iterate over a consumed stream, use `.tee()` to split the stream."); s = !0; let a = !1; try { for await (const i of r()) a || i && (yield JSON.parse(i)); a = !0; } catch (i) { if (i instanceof Error && i.name === "AbortError") return; throw i; } finally { a || t.abort(); } } return new y(o, t); } [Symbol.asyncIterator]() { return this.iterator(); } tee() { const e = [], t = [], s = this.iterator(), r = (o) => ({ next: () => { if (o.length === 0) { const a = s.next(); e.push(a), t.push(a); } return o.shift(); } }); return [ new y(() => r(e), this.controller), new y(() => r(t), this.controller) ]; } // Converts this stream to a newline-separated ReadableStream of JSON Stringified values in the stream // which can be turned back into a Stream with Stream.fromReadableStream. toReadableStream() { let e; const t = this, s = new TextEncoder(); return new ReadableStream({ async start() { e = t[Symbol.asyncIterator](); }, async pull(r) { try { const { value: o, done: a } = await e.next(); if (a) return r.close(); const i = o.result, c = s.encode(JSON.stringify(i) + ` `); r.enqueue(c); } catch (o) { r.error(o); } }, async cancel() { var r; await ((r = e.return) == null ? void 0 : r.call(e)); } }); } } class me { constructor() { this.event = null, this.data = [], this.chunks = []; } decode(e) { if (e.endsWith("\r") && (e = e.substring(0, e.length - 1)), !e) { if (!this.event && !this.data.length) return null; const o = { event: this.event, data: this.data.join(` `), raw: this.chunks }; return this.event = null, this.data = [], this.chunks = [], o; } if (this.chunks.push(e), e.startsWith(":")) return null; let [t, s, r] = Ee(e, ":"); return r.startsWith(" ") && (r = r.substring(1)), t === "event" ? this.event = r : t === "data" && this.data.push(r), null; } } const J = class L { // TextDecoder found in browsers; not typed to avoid pulling in either "dom" or "node" types. constructor() { this.buffer = [], this.trailingCR = !1; } decode(e) { let t = this.decodeText(e); if (this.trailingCR && (t = "\r" + t, this.trailingCR = !1), t.endsWith("\r") && (this.trailingCR = !0, t = t.slice(0, -1)), !t) return []; const s = L.NEWLINE_CHARS.has(t[t.length - 1] || ""); let r = t.split(L.NEWLINE_REGEXP); return r.length === 1 && !s ? (this.buffer.push(r[0]), []) : (this.buffer.length > 0 && (r = [this.buffer.join("") + r[0], ...r.slice(1)], this.buffer = []), s || (this.buffer = [r.pop() || ""]), r); } decodeText(e) { if (e == null) return ""; if (typeof e == "string") return e; if (typeof Buffer < "u") { if (e instanceof Buffer) return e.toString(); if (e instanceof Uint8Array) return Buffer.from(e).toString(); throw new d( `Unexpected: received non-Uint8Array (${e.constructor.name}) stream chunk in an environment with a global "Buffer" defined, which this library assumes to be Node. Please report this error.` ); } if (typeof TextDecoder < "u") { if (e instanceof Uint8Array || e instanceof ArrayBuffer) return this.textDecoder ?? (this.textDecoder = new TextDecoder("utf8")), this.textDecoder.decode(e); throw new d( `Unexpected: received non-Uint8Array/ArrayBuffer (${e.constructor.name}) in a web platform. Please report this error.` ); } throw new d("Unexpected: neither Buffer nor TextDecoder are available as globals. Please report this error."); } flush() { if (!this.buffer.length && !this.trailingCR) return []; const e = [this.buffer.join("")]; return this.buffer = [], this.trailingCR = !1, e; } }; J.NEWLINE_CHARS = /* @__PURE__ */ new Set([` `, "\r", "\v", "\f", "", "", "", "…", "\u2028", "\u2029"]); J.NEWLINE_REGEXP = /\r\n|[\n\r\x0b\x0c\x1c\x1d\x1e\x85\u2028\u2029]/g; let X = J; function Ee(n, e) { const t = n.indexOf(e); return t !== -1 ? [n.substring(0, t), e, n.substring(t + e.length)] : [n, "", ""]; } function Y(n) { if (n[Symbol.asyncIterator]) return n; const e = n.getReader(); return { async next() { try { const t = await e.read(); return t != null && t.done && e.releaseLock(), t; } catch (t) { throw e.releaseLock(), t; } }, async return() { const t = e.cancel(); return e.releaseLock(), await t, { done: !0, value: void 0 }; }, [Symbol.asyncIterator]() { return this; } }; } class F extends Promise { constructor(e, t) { super((s) => { s(null); }), this.responsePromise = e, this.parseResponse = t; } _thenUnwrap(e) { return new F(this.responsePromise, async (t) => e(await this.parseResponse(t))); } asResponse() { return this.responsePromise.then((e) => e.response); } async withResponse() { const [e, t] = await Promise.all([this.parse(), this.asResponse()]); return { data: e, response: t }; } parse() { return this.parsedPromise || (this.parsedPromise = this.responsePromise.then(this.parseResponse)), this.parsedPromise; } then(e, t) { return this.parse().then(e, t); } catch(e) { return this.parse().catch(e); } finally(e) { return this.parse().finally(e); } } const S = I("erniebot:client"); class ge { constructor(e = {}) { const { baseURL: t = "", headers: s = {}, timeout: r = 6e5, maxRetries: o = 2, fetch: a = N().fetch } = e || {}; this.fetch = a, this.baseURL = t, this.timeout = r, this.headers = s, this.maxRetries = o; } get(e, t) { return this.methodRequest("get", e, t); } post(e, t) { return this.methodRequest("post", e, t); } patch(e, t) { return this.methodRequest("patch", e, t); } put(e, t) { return this.methodRequest("put", e, t); } delete(e, t) { return this.methodRequest("delete", e, t); } methodRequest(e, t, s) { return this.request({ ...s, method: e, path: t }); } request(e, t = null) { return new F(this.makeRequest(e, t), (s) => this.parseResponse(s)); } async defaultQuery() { return {}; } /** * Override this to add your own default headers, for example: * * ```js * { * ...super.defaultHeaders(), * Authorization: 'Bearer 123', * } * ``` */ defaultHeaders(e) { return { ...this.headers, Accept: e.stream ? "text/event-stream" : "application/json", "Content-Type": "application/json", "User-Agent": this.getUserAgent(), ...this.authHeaders(e) }; } async parseResponse({ response: e, options: t, controller: s }) { const r = e.headers; if (t.stream) return S("response", e.status, e.url, r, e.body), y.fromSSEResponse(e, s); const o = r.get("content-type"); if (o != null && o.includes("application/json")) { const i = await e.json(); return S("response", e.status, e.url, r, i), i; } const a = await e.text(); return S("response", e.status, e.url, r, a), a; } authHeaders(e) { return {}; } getUserAgent() { var e; return ((e = N().navigator) == null ? void 0 : e.userAgent) || ""; } validateHeaders(e, t) { } /** * Used as a callback for mutating the given `RequestInit` object. * * This is useful for cases where you want to add certain headers based off of * the request properties, e.g. `method` or `url`. */ prepareRequest(e, { url: t, options: s }) { } getRequestClient() { return { fetch: this.fetch }; } async fetchWithTimeout(e, t, s, r) { const { signal: o, ...a } = t || {}; o && o.addEventListener("abort", () => r.abort()); const i = setTimeout(() => r.abort(), s); return this.getRequestClient().fetch.call(void 0, e, { signal: r.signal, ...a }).finally(() => clearTimeout(i)); } async buildURL({ path: e, query: t }) { const s = new URL(e, this.baseURL), r = oe(t, await this.defaultQuery()); return r.size && (s.search = r.toString()), s.toString(); } // TODO 实现请求重试 async makeRequest(e, t) { var u, f; const { req: s, url: r, timeout: o } = await this.buildRequest(e); if (await this.prepareRequest(s, { url: r, options: e }), S("request", r, e, s.headers), (u = e.signal) != null && u.aborted) throw new T(); const a = new AbortController(), i = await this.fetchWithTimeout(r, s, o, a).catch(U); if (i instanceof Error) throw (f = e.signal) != null && f.aborted ? new T() : i.name === "AbortError" ? new _() : new k({ cause: i }); const c = i.headers; if (!i.ok) { const A = await i.text().catch((ue) => U(ue).message), G = fe(A), z = G ? void 0 : A; throw S("response", i.status, r, c, z), this.makeStatusError(i.status, G, z, c); } return { response: i, options: e, controller: a }; } makeStatusError(e, t, s, r) { return l.generate(e, t, s, r); } async buildRequest(e) { const { method: t = "POST", timeout: s = this.timeout, headers: r = {} } = e, o = await this.buildURL(e), a = we(e.body) ? e.body.body : e.body ? JSON.stringify(e.body) : null, i = ye(a), c = { ...i && { "Content-Length": i }, ...this.defaultHeaders(e), ...r }, u = { method: t, body: a, headers: c, signal: e.signal ?? null }; return this.validateHeaders(c, r), { req: u, url: o, timeout: s }; } } function we(n) { return n && typeof n == "object" && n.body && n[Symbol.toStringTag] === "MultipartBody"; } function ye(n) { if (typeof n == "string") { if (typeof Buffer < "u") return Buffer.byteLength(n, "utf8").toString(); if (typeof TextEncoder < "u") return new TextEncoder().encode(n).length.toString(); } return null; } function oe(n, e) { const t = new URLSearchParams(n || []); return new URLSearchParams(e || []).forEach((r, o) => { t.has(o) || t.set(o, r); }), t; } class K { constructor(e) { this.client = e, this.get = e.get.bind(e), this.post = e.post.bind(e), this.patch = e.patch.bind(e), this.put = e.put.bind(e), this.delete = e.delete.bind(e); } } class be extends K { create(e, t) { return this.post("/chat/completions", { body: e, ...t, stream: e.stream ?? !1 }); } } class Re extends K { constructor() { super(...arguments), this.completions = new be(this.client); } } class Ae extends K { create(e, t) { return this.post("/embeddings", { body: e, ...t }); } } const ie = process.env.VERSION; class ae { setup(e) { this.client = e; } /** * 覆盖当前请求路径 * * @param path - 当前路径 * @param model - 请求模型 * @returns 返回空值将使用预设的路径 */ overrideResourcePath(e, t) { const s = this.resources[e]; if (s) { const { resourceId: r, models: o } = s, { moduleId: a } = o[t]; if (a) return `${this.baseURL}/${r}/${a}`; throw new ne(`${t} is not a supported model.`); } } /** * 返回默认请求参数 */ defaultQuery() { return {}; } /** * 添加授权请求头 */ authHeaders(e) { return {}; } /** * 预处理请求 */ prepareRequest(e, t) { } transformResponse(e, t) { return t; } async parseResponse({ response: e, options: t, controller: s }) { const r = I(`erniebot:backend:${this.apiType}`), o = e.headers; if (t.stream) return r("response", e.status, e.url, o, e.body), y.fromSSEResponse(e, s); const a = o.get("content-type"); if (a != null && a.includes("application/json")) { const c = await e.json(); r("response", e.status, e.url, o, c); const u = c.errorCode ?? c.error_code ?? 0; if (u === 0) return this.transformResponse("json", c); const f = c.errorMsg ?? c.error_msg ?? "unknown error"; return Promise.reject(this.makeStatusError(u, c, f, o)); } const i = await e.text(); return r("response", e.status, e.url, o, i), i; } makeStatusError(e, t, s, r) { let o; return e === 2 ? o = 500 : e === 6 ? o = 403 : e === 17 || e === 18 || e === 19 || e === 40407 ? o = 429 : e === 110 || e === 111 || e === 40401 ? o = 401 : (e === 336003 || e === 336100) && (o = 400), l.generate(o, t, s, r); } } class ve extends ae { constructor() { super(...arguments), this.apiType = "aistudio", this.baseURL = "https://aistudio.baidu.com/llm/lmapi/v1", this.resources = { "/chat/completions": { resourceId: "chat", models: { "ernie-bot": { moduleId: "completions" }, "ernie-bot-turbo": { moduleId: "eb-instant" }, "ernie-bot-4": { moduleId: "completions_pro" } } }, "/embeddings": { resourceId: "embeddings", models: { "ernie-text-embedding": { moduleId: "embedding-v1" } } } }; } authHeaders() { const { token: e = g("AISTUDIO_ACCESS_TOKEN") } = this.client; if (e == null) throw new d( "The EB_ACCESS_TOKEN environment variable is missing or empty; either provide it, or instantiate the ErnieBot client with an token option, like new ErnieBot({ token: 'My API Access Token' })." ); return { authorization: `token ${e}` }; } transformResponse(e, t) { return t.result; } } const Se = new ve(); I("erniebot-backend-bce:auth"); var E, R, b; class Ie { constructor() { x(this, E, void 0); x(this, R, void 0); x(this, b, void 0); } getAccessToken(e) { const t = m(this, E); return t || (m(this, b) && m(this, R) && m(this, R) > Date.now() ? Promise.resolve(m(this, b)) : (v(this, E, this.requestAccessToken(e).then((s) => (v(this, b, s.access_token), v(this, R, Date.now() + (s.expires_in - 120) * 1e3), m(this, b)))), m(this, E).finally(() => { v(this, E, void 0); }), m(this, E))); } requestAccessToken({ ak: e, sk: t }) { const s = new URL("https://aip.baidubce.com/oauth/2.0/token"); return s.search = new URLSearchParams({ grant_type: "client_credentials", client_id: e, client_secret: t }).toString(), fetch(s, { method: "GET" }).then((r) => r.json()); } } E = new WeakMap(), R = new WeakMap(), b = new WeakMap(); I("erniebot:backend:qianfan"); class ke extends ae { constructor() { super(...arguments), this.apiType = "qianfan", this.baseURL = "https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop", this.resources = { "/chat/completions": { resourceId: "chat", models: { "ernie-bot": { moduleId: "completions" }, "ernie-bot-turbo": { moduleId: "eb-instant" }, "ernie-bot-4": { moduleId: "completions_pro" } } } }, this.errCodes = { 2: 500, 6: 403 }, this.tokenManager = new Ie(); } async defaultQuery() { const { ak: e = g("QIANFAN_AK"), sk: t = g("QIANFAN_SK") } = this.client; if (e == null || t == null) throw new d("Invalid access key ID or secret access key"); return { access_token: await this.tokenManager.getAccessToken({ ak: e, sk: t }) }; } } const xe = new ke(), Pe = { aistudio: Se, qianfan: xe }; function Te(n) { const e = Pe[n.toLowerCase()]; if (e) return e; throw new se(`${n} cannot be recognized as an API type.`); } var ce = (n, e, t) => { if (!e.has(n)) throw TypeError("Cannot " + t); }, w = (n, e, t) => (ce(n, e, "read from private field"), t ? t.call(n) : e.get(n)), Z = (n, e, t) => { if (e.has(n)) throw TypeError("Cannot add the same private member more than once"); e instanceof WeakSet ? e.add(n) : e.set(n, t); }, B = (n, e, t, s) => (ce(n, e, "write to private field"), s ? s.call(n, t) : e.set(n, t), t), P, p; const ee = I("ernie"), h = class extends ge { /** * API Client for interfacing with the ERNIE Bot API. */ constructor(e) { const { apiType: t = g("EB_API_TYPE") || "aistudio", token: s = g("EB_ACCESS_TOKEN"), ak: r = g("EB_AK"), sk: o = g("EB_SK"), dangerouslyAllowBrowser: a = !1, ...i } = e || {}; if (super(i), this.options = e, Z(this, P, void 0), Z(this, p, void 0), this.chat = new Re(this), this.embeddings = new Ae(this), !a && re) throw new d( `It looks like you're running in a browser-like environment. This is disabled by default, as it risks exposing your secret API credentials to attackers. If you understand the risks and have appropriate mitigations in place, you can set the \`dangerouslyAllowBrowser\` option to \`true\`, e.g., new ERNIEBot({ apiKey, dangerouslyAllowBrowser: true });` ); this.ak = r, this.sk = o, this.token = s, this.apiType = t; } get apiType() { return w(this, P); } set apiType(e) { var s; const t = Te(e); (s = t.setup) == null || s.call(t, this), B(this, P, t.apiType), B(this, p, t), ee("apiType", e); } get backend() { return this.backend; } set backend(e) { var t; (t = e.setup) == null || t.call(e, this), B(this, p, e), this.apiType = e.apiType, ee("backend", this.apiType); } getUserAgent() { return `ERNIEBot JS-SDK/${ie} Backend/${w(this, p).apiType}`; } async defaultQuery() { var e, t; return ((t = (e = w(this, p)).defaultQuery) == null ? void 0 : t.call(e)) || {}; } authHeaders(e) { return w(this, p).authHeaders(e); } prepareRequest(e, t) { var s, r; return (r = (s = w(this, p)).prepareRequest) == null ? void 0 : r.call(s, e, t); } parseResponse(e) { return w(this, p).parseResponse(e); } async buildURL(e) { const { path: t, body: s } = e, r = s == null ? void 0 : s.model; if (r) { const o = w(this, p).overrideResourcePath(t, r); if (o) { const a = await this.defaultQuery(), i = oe(e.query, a), c = new URL(o); return c.search = i.toString(), c.toString(); } } return super.buildURL(e); } }; P = /* @__PURE__ */ new WeakMap(); p = /* @__PURE__ */ new WeakMap(); h.ERNIEBot = h; h.version = ie; h.EBError = d; h.APIError = l; h.APIConnectionError = k; h.APIConnectionTimeoutError = _; h.APIUserAbortError = T; h.NotFoundError = j; h.ConflictError = H; h.RateLimitError = Q; h.BadRequestError = $; h.AuthenticationError = D; h.InternalServerError = W; h.PermissionDeniedError = O; h.UnprocessableEntityError = M; let We = h; const { EBError: Je, APIError: Fe, APIConnectionError: Ke, APIConnectionTimeoutError: Ge, APIUserAbortError: ze, NotFoundError: Ve, ConflictError: Xe, RateLimitError: Ye, BadRequestError: Ze, AuthenticationError: et, InternalServerError: tt, PermissionDeniedError: rt, UnprocessableEntityError: nt } = pe; export { Ke as APIConnectionError, Ge as APIConnectionTimeoutError, Fe as APIError, ze as APIUserAbortError, et as AuthenticationError, Ze as BadRequestError, Xe as ConflictError, Je as EBError, We as ERNIEBot, tt as InternalServerError, Ve as NotFoundError, rt as PermissionDeniedError, Ye as RateLimitError, nt as UnprocessableEntityError, We as default };