diff --git a/libs/langchain-community/src/chat_models/zhipuai.ts b/libs/langchain-community/src/chat_models/zhipuai.ts index d7a82279f274..6bb993588afa 100644 --- a/libs/langchain-community/src/chat_models/zhipuai.ts +++ b/libs/langchain-community/src/chat_models/zhipuai.ts @@ -225,13 +225,11 @@ export class ChatZhipuAI extends BaseChatModel implements ChatZhipuAIParams { constructor(fields: Partial & BaseChatModelParams = {}) { super(fields); - this.zhipuAIApiKey = encodeApiKey( + this.zhipuAIApiKey = fields?.apiKey ?? - fields?.zhipuAIApiKey ?? - getEnvironmentVariable("ZHIPUAI_API_KEY") - ); - this.apiKey = this.zhipuAIApiKey; - if (!this.apiKey) { + fields?.zhipuAIApiKey ?? + getEnvironmentVariable("ZHIPUAI_API_KEY"); + if (!this.zhipuAIApiKey) { throw new Error("ZhipuAI API key not found"); } @@ -390,7 +388,7 @@ export class ChatZhipuAI extends BaseChatModel implements ChatZhipuAIParams { method: "POST", headers: { ...(stream ? { Accept: "text/event-stream" } : {}), - Authorization: `Bearer ${this.apiKey}`, + Authorization: `Bearer ${encodeApiKey(this.zhipuAIApiKey)}`, "Content-Type": "application/json", }, body: JSON.stringify(request), diff --git a/libs/langchain-community/src/embeddings/zhipuai.ts b/libs/langchain-community/src/embeddings/zhipuai.ts index 872fef7a2003..d51c2dc4eb39 100644 --- a/libs/langchain-community/src/embeddings/zhipuai.ts +++ b/libs/langchain-community/src/embeddings/zhipuai.ts @@ -48,7 +48,7 @@ export class ZhipuAIEmbeddings { modelName: ZhipuAIEmbeddingsParams["modelName"] = "embedding-2"; - apiKey: string; + apiKey?: string; stripNewLines = true; @@ -59,9 +59,7 @@ export class ZhipuAIEmbeddings this.modelName = fields?.modelName ?? this.modelName; this.stripNewLines = fields?.stripNewLines ?? this.stripNewLines; - this.apiKey = encodeApiKey( - fields?.apiKey ?? getEnvironmentVariable("ZHIPUAI_API_KEY") - ); + this.apiKey = fields?.apiKey ?? getEnvironmentVariable("ZHIPUAI_API_KEY"); if (!this.apiKey) { throw new Error("ZhipuAI API key not found"); @@ -84,7 +82,7 @@ export class ZhipuAIEmbeddings const headers = { Accept: "application/json", "Content-Type": "application/json", - Authorization: this.apiKey, + Authorization: encodeApiKey(this.apiKey), }; return this.caller.call(async () => { diff --git a/libs/langchain-community/src/utils/zhipuai.ts b/libs/langchain-community/src/utils/zhipuai.ts index 9ef2e92aa0fd..475f3b84558f 100644 --- a/libs/langchain-community/src/utils/zhipuai.ts +++ b/libs/langchain-community/src/utils/zhipuai.ts @@ -1,22 +1,45 @@ -import jwt from "jsonwebtoken"; +import jsonwebtoken from "jsonwebtoken"; -export function encodeApiKey(apiKey: string | undefined) { - if (!apiKey) throw Error("Invalid api key"); - const [key, secret] = apiKey.split("."); - const API_TOKEN_TTL_SECONDS = 3 * 60; - const now = new Date().valueOf(); - const payload = { - api_key: key, - exp: now + API_TOKEN_TTL_SECONDS * 1000, - timestamp: now, +const API_TOKEN_TTL_SECONDS = 3 * 60; +const CACHE_TTL_SECONDS = API_TOKEN_TTL_SECONDS - 30; +const tokenCache: { + [key: string]: { + token: string; + createAt: number; }; - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const options: any = { - algorithm: "HS256", - header: { - alg: "HS256", - sign_type: "SIGN", - }, - }; - return jwt.sign(payload, secret, options); -} +} = {}; + +export const encodeApiKey = (apiSecretKey?: string, cache = true): string => { + if (!apiSecretKey) throw new Error("Api_key is required"); + try { + if ( + tokenCache[apiSecretKey] && + Date.now() - tokenCache[apiSecretKey].createAt < CACHE_TTL_SECONDS * 1000 + ) { + return tokenCache[apiSecretKey].token; + } + + const [apiKey, secret] = apiSecretKey.split("."); + const payload = { + api_key: apiKey, + exp: Math.round(Date.now() * 1000) + API_TOKEN_TTL_SECONDS * 1000, + timestamp: Math.round(Date.now() * 1000), + }; + // algorithm = "HS256", headers = { "alg": "HS256", "sign_type": "SIGN" } + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + const ret = jsonwebtoken.sign(payload, secret, { + algorithm: "HS256", + header: { alg: "HS256", sign_type: "SIGN" }, + }); + if (cache) { + tokenCache[apiSecretKey] = { + token: ret, + createAt: Date.now(), + }; + } + return ret; + } catch (e) { + throw new Error("invalid api_key"); + } +};