@langchain/community
Version:
Third-party integrations for LangChain.js
1 lines • 20 kB
Source Map (JSON)
{"version":3,"file":"base.cjs","names":["message: BaseMessage","ChatMessage","BaseChatModel","fields?: Partial<TencentHunyuanChatInputWithSign> & BaseChatModelParams","request: object","timestamp: number","messages: BaseMessage[]","options: this[\"ParsedCallOptions\"]","runManager?: CallbackManagerForLLMRun","ChatGenerationChunk","AIMessageChunk","request: ChatCompletionRequest","signal?: AbortSignal","IterableReadableStream","options?: this[\"ParsedCallOptions\"]","usage: Usage","generations: ChatGeneration[]","text","AIMessage","data","response: ChatCompletionResponse"],"sources":["../../../src/chat_models/tencent_hunyuan/base.ts"],"sourcesContent":["import {\n BaseChatModel,\n type BaseChatModelParams,\n} from \"@langchain/core/language_models/chat_models\";\nimport {\n AIMessage,\n BaseMessage,\n ChatMessage,\n AIMessageChunk,\n} from \"@langchain/core/messages\";\nimport {\n ChatGeneration,\n ChatResult,\n ChatGenerationChunk,\n} from \"@langchain/core/outputs\";\nimport { CallbackManagerForLLMRun } from \"@langchain/core/callbacks/manager\";\nimport { getEnvironmentVariable } from \"@langchain/core/utils/env\";\nimport { IterableReadableStream } from \"@langchain/core/utils/stream\";\nimport { sign } from \"../../utils/tencent_hunyuan/common.js\";\n\n/**\n * Type representing the role of a message in the Hunyuan chat model.\n */\nexport type HunyuanMessageRole = \"system\" | \"assistant\" | \"user\";\n\n/**\n * Interface representing a message in the Hunyuan chat model.\n */\ninterface HunyuanMessage {\n Role: HunyuanMessageRole;\n Content: string;\n}\n\n/**\n * Models available, see https://cloud.tencent.com/document/product/1729/104753.\n */\ntype ModelName =\n | (string & NonNullable<unknown>)\n // hunyuan-lite\n | \"hunyuan-lite\" // context size: 4k, input size: 3k, output size: 1k\n // hunyuan-standard\n | \"hunyuan-standard\" // alias for hunyuan-standard-32K\n | \"hunyuan-standard-32K\" // context size: 32k, input size: 30k, output size: 2k\n | \"hunyuan-standard-256K\" // context size: 256k, input size: 250k, output size: 6k\n // hunyuan-pro\n | \"hunyuan-pro\"; // context size: 32k, input size: 28k, output size: 4k\n\n/**\n * Interface representing the usage of tokens in a chat completion.\n * See https://cloud.tencent.com/document/api/1729/101838#Usage.\n */\ninterface Usage {\n TotalTokens?: number;\n PromptTokens?: number;\n CompletionTokens?: number;\n}\n\n/**\n * Interface representing a request for a chat completion.\n * See https://cloud.tencent.com/document/api/1729/105701.\n */\ninterface ChatCompletionRequest {\n Model: ModelName;\n Messages: HunyuanMessage[];\n Stream?: boolean;\n StreamModeration?: boolean;\n EnableEnhancement?: boolean;\n Temperature?: number;\n TopP?: number;\n}\n\n/**\n * Interface representing a chat completion choice message.\n * See https://cloud.tencent.com/document/api/1729/101838#Message.\n */\ninterface ChoiceMessage {\n Role: string;\n Content: string;\n}\n\n/**\n * Interface representing a chat completion choice.\n * See https://cloud.tencent.com/document/api/1729/101838#Choice.\n */\ninterface Choice {\n FinishReason: \"stop\" | \"sensitive\" | \"\";\n Delta: ChoiceMessage;\n Message: ChoiceMessage;\n}\n\n/**\n * Interface representing a error response from a chat completion.\n */\ninterface Error {\n Code: string;\n Message: string;\n}\n\n/**\n * Interface representing a response from a chat completion.\n * See https://cloud.tencent.com/document/product/1729/105701.\n */\ninterface ChatCompletionResponse {\n Created: number;\n Usage: Usage;\n Note: string;\n Choices: Choice[];\n Id?: string;\n RequestId?: string;\n Error?: Error;\n ErrorMsg?: Error;\n}\n\n/**\n * Interface defining the input to the ChatTencentHunyuan class.\n */\nexport interface TencentHunyuanChatInput {\n /**\n * Tencent Cloud API Host.\n * @default \"hunyuan.tencentcloudapi.com\"\n */\n host?: string;\n\n /**\n * Model name to use.\n * @default \"hunyuan-pro\"\n */\n model: ModelName;\n\n /**\n * Whether to stream the results or not. Defaults to false.\n * @default false\n */\n streaming?: boolean;\n\n /**\n * SecretID to use when making requests, can be obtained from https://console.cloud.tencent.com/cam/capi.\n * Defaults to the value of `TENCENT_SECRET_ID` environment variable.\n */\n tencentSecretId?: string;\n\n /**\n * Secret key to use when making requests, can be obtained from https://console.cloud.tencent.com/cam/capi.\n * Defaults to the value of `TENCENT_SECRET_KEY` environment variable.\n */\n tencentSecretKey?: string;\n\n /**\n * Amount of randomness injected into the response. Ranges\n * from 0.0 to 2.0. Use temp closer to 0 for analytical /\n * multiple choice, and temp closer to 1 for creative\n * and generative tasks. Defaults to 1.0.95.\n */\n temperature?: number;\n\n /**\n * Total probability mass of tokens to consider at each step. Range\n * from 0 to 1.0. Defaults to 1.0.\n */\n topP?: number;\n}\n\n/**\n * Interface defining the input to the ChatTencentHunyuan class.\n */\ninterface TencentHunyuanChatInputWithSign extends TencentHunyuanChatInput {\n /**\n * Tencent Cloud API v3 sign method.\n */\n sign: sign;\n}\n\n/**\n * Function that converts a base message to a Hunyuan message role.\n * @param message Base message to convert.\n * @returns The Hunyuan message role.\n */\nfunction messageToRole(message: BaseMessage): HunyuanMessageRole {\n const type = message._getType();\n switch (type) {\n case \"ai\":\n return \"assistant\";\n case \"human\":\n return \"user\";\n case \"system\":\n return \"system\";\n case \"function\":\n throw new Error(\"Function messages not supported\");\n case \"generic\": {\n if (!ChatMessage.isInstance(message)) {\n throw new Error(\"Invalid generic chat message\");\n }\n if ([\"system\", \"assistant\", \"user\"].includes(message.role)) {\n return message.role as HunyuanMessageRole;\n }\n throw new Error(`Unknown message role: ${message.role}`);\n }\n default:\n throw new Error(`Unknown message type: ${type}`);\n }\n}\n\n/**\n * Wrapper around Tencent Hunyuan large language models that use the Chat endpoint.\n *\n * To use you should have the `TENCENT_SECRET_ID` and `TENCENT_SECRET_KEY`\n * environment variable set.\n *\n * @augments BaseLLM\n * @augments TencentHunyuanInput\n * @example\n * ```typescript\n * const messages = [new HumanMessage(\"Hello\")];\n *\n * const hunyuanLite = new ChatTencentHunyuan({\n * model: \"hunyuan-lite\",\n * tencentSecretId: \"YOUR-SECRET-ID\",\n * tencentSecretKey: \"YOUR-SECRET-KEY\",\n * });\n *\n * let res = await hunyuanLite.call(messages);\n *\n * const hunyuanPro = new ChatTencentHunyuan({\n * model: \"hunyuan-pro\",\n * temperature: 1,\n * tencentSecretId: \"YOUR-SECRET-ID\",\n * tencentSecretKey: \"YOUR-SECRET-KEY\",\n * });\n *\n * res = await hunyuanPro.call(messages);\n * ```\n */\nexport class ChatTencentHunyuan\n extends BaseChatModel\n implements TencentHunyuanChatInputWithSign\n{\n static lc_name() {\n return \"ChatTencentHunyuan\";\n }\n\n get callKeys(): string[] {\n return [\"stop\", \"signal\", \"options\"];\n }\n\n get lc_secrets(): { [key: string]: string } | undefined {\n return {\n tencentSecretId: \"TENCENT_SECRET_ID\",\n tencentSecretKey: \"TENCENT_SECRET_KEY\",\n };\n }\n\n get lc_aliases(): { [key: string]: string } | undefined {\n return undefined;\n }\n\n lc_serializable = true;\n\n tencentSecretId?: string;\n\n tencentSecretKey?: string;\n\n streaming = false;\n\n host = \"hunyuan.tencentcloudapi.com\";\n\n model = \"hunyuan-pro\";\n\n temperature?: number | undefined;\n\n topP?: number | undefined;\n\n sign: sign;\n\n constructor(\n fields?: Partial<TencentHunyuanChatInputWithSign> & BaseChatModelParams\n ) {\n super(fields ?? {});\n\n this.tencentSecretId =\n fields?.tencentSecretId ?? getEnvironmentVariable(\"TENCENT_SECRET_ID\");\n if (!this.tencentSecretId) {\n throw new Error(\"Tencent SecretID not found\");\n }\n\n this.tencentSecretKey =\n fields?.tencentSecretKey ?? getEnvironmentVariable(\"TENCENT_SECRET_KEY\");\n if (!this.tencentSecretKey) {\n throw new Error(\"Tencent SecretKey not found\");\n }\n\n this.host = fields?.host ?? this.host;\n this.topP = fields?.topP ?? this.topP;\n this.model = fields?.model ?? this.model;\n this.streaming = fields?.streaming ?? this.streaming;\n this.temperature = fields?.temperature ?? this.temperature;\n if (!fields?.sign) {\n throw new Error(\"Sign method undefined\");\n }\n this.sign = fields?.sign;\n }\n\n /**\n * Get the parameters used to invoke the model\n */\n invocationParams(): Omit<ChatCompletionRequest, \"Messages\"> {\n return {\n TopP: this.topP,\n Model: this.model,\n Stream: this.streaming,\n Temperature: this.temperature,\n };\n }\n\n /**\n * Get the HTTP headers used to invoke the model\n */\n invocationHeaders(request: object, timestamp: number): HeadersInit {\n const headers = {\n \"Content-Type\": \"application/json\",\n \"X-TC-Action\": \"ChatCompletions\",\n \"X-TC-Version\": \"2023-09-01\",\n \"X-TC-Timestamp\": timestamp.toString(),\n Authorization: \"\",\n };\n\n headers.Authorization = this.sign(\n this.host,\n request,\n timestamp,\n this.tencentSecretId ?? \"\",\n this.tencentSecretKey ?? \"\",\n headers\n );\n return headers;\n }\n\n async *_streamResponseChunks(\n messages: BaseMessage[],\n options: this[\"ParsedCallOptions\"],\n runManager?: CallbackManagerForLLMRun\n ): AsyncGenerator<ChatGenerationChunk> {\n const stream = await this.caller.call(async () =>\n this.createStream(\n {\n ...this.invocationParams(),\n Messages: messages.map((message) => ({\n Role: messageToRole(message),\n Content: message.content as string,\n })),\n },\n options?.signal\n )\n );\n\n for await (const chunk of stream) {\n // handle streaming error\n if (chunk.ErrorMsg?.Message) {\n throw new Error(`[${chunk.Id}] ${chunk.ErrorMsg?.Message}`);\n }\n\n const {\n Choices: [\n {\n Delta: { Content },\n FinishReason,\n },\n ],\n } = chunk;\n yield new ChatGenerationChunk({\n text: Content,\n message: new AIMessageChunk({ content: Content }),\n generationInfo: FinishReason\n ? {\n usage: chunk.Usage,\n request_id: chunk.Id,\n finish_reason: FinishReason,\n }\n : undefined,\n });\n await runManager?.handleLLMNewToken(Content);\n }\n }\n\n private async *createStream(\n request: ChatCompletionRequest,\n signal?: AbortSignal\n ): AsyncGenerator<ChatCompletionResponse> {\n const timestamp = Math.trunc(Date.now() / 1000);\n const headers = this.invocationHeaders(request, timestamp);\n const response = await fetch(`https://${this.host}`, {\n headers,\n method: \"POST\",\n body: JSON.stringify(request),\n signal,\n });\n\n if (!response.ok) {\n const text = await response.text();\n throw new Error(\n `Hunyuan call failed with status code ${response.status}: ${text}`\n );\n }\n\n if (\n !response.headers.get(\"content-type\")?.startsWith(\"text/event-stream\")\n ) {\n const text = await response.text();\n try {\n const data = JSON.parse(text);\n if (data?.Response?.Error?.Message) {\n throw new Error(\n `[${data?.Response?.RequestId}] ${data?.Response?.Error?.Message}`\n );\n }\n } catch {\n throw new Error(\n `Could not begin Hunyuan stream, received a non-JSON parseable response: ${text}.`\n );\n }\n }\n\n if (!response.body) {\n throw new Error(\n `Could not begin Hunyuan stream, received empty body response.`\n );\n }\n\n const decoder = new TextDecoder(\"utf-8\");\n const stream = IterableReadableStream.fromReadableStream(response.body);\n let extra = \"\";\n for await (const chunk of stream) {\n const decoded = extra + decoder.decode(chunk);\n const lines = decoded.split(\"\\n\");\n extra = lines.pop() || \"\";\n for (const line of lines) {\n if (!line.startsWith(\"data:\")) {\n continue;\n }\n try {\n yield JSON.parse(line.slice(\"data:\".length).trim());\n } catch {\n console.warn(`Received a non-JSON parseable chunk: ${line}`);\n }\n }\n }\n }\n\n /** @ignore */\n async _generate(\n messages: BaseMessage[],\n options?: this[\"ParsedCallOptions\"],\n runManager?: CallbackManagerForLLMRun\n ): Promise<ChatResult> {\n const params = this.invocationParams();\n if (params.Stream) {\n let usage: Usage = {};\n const stream = this._streamResponseChunks(\n messages,\n options ?? {},\n runManager\n );\n\n const generations: ChatGeneration[] = [];\n for await (const chunk of stream) {\n const text = chunk.text ?? \"\";\n generations.push({\n text,\n message: new AIMessage(text),\n });\n usage = chunk.generationInfo?.usage;\n }\n return {\n generations,\n llmOutput: {\n tokenUsage: {\n totalTokens: usage.TotalTokens,\n promptTokens: usage.PromptTokens,\n completionTokens: usage.CompletionTokens,\n },\n },\n };\n }\n\n const data = await this.completionWithRetry(\n {\n ...params,\n Messages: messages.map((message) => ({\n Role: messageToRole(message),\n Content: message.content as string,\n })),\n },\n options?.signal\n ).then<ChatCompletionResponse>((data) => {\n const response: ChatCompletionResponse = data?.Response;\n if (response?.Error?.Message) {\n throw new Error(`[${response.RequestId}] ${response.Error.Message}`);\n }\n return response;\n });\n\n const text = data.Choices[0]?.Message?.Content ?? \"\";\n const {\n TotalTokens = 0,\n PromptTokens = 0,\n CompletionTokens = 0,\n } = data.Usage;\n\n return {\n generations: [\n {\n text,\n message: new AIMessage(text),\n },\n ],\n llmOutput: {\n tokenUsage: {\n totalTokens: TotalTokens,\n promptTokens: PromptTokens,\n completionTokens: CompletionTokens,\n },\n },\n };\n }\n\n /** @ignore */\n async completionWithRetry(\n request: ChatCompletionRequest,\n signal?: AbortSignal\n ) {\n return this.caller.call(async () => {\n const timestamp = Math.trunc(Date.now() / 1000);\n const headers = this.invocationHeaders(request, timestamp);\n const response = await fetch(`https://${this.host}`, {\n headers,\n method: \"POST\",\n body: JSON.stringify(request),\n signal,\n });\n\n return response.json();\n });\n }\n\n _llmType() {\n return \"tencenthunyuan\";\n }\n\n /** @ignore */\n _combineLLMOutput() {\n return [];\n }\n}\n"],"mappings":"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"}