{"version":3,"file":"common.cjs","names":["ChatMessage","BaseChatModel","IterableReadableStream","AIMessage"],"sources":["../../../src/chat_models/iflytek_xinghuo/common.ts"],"sourcesContent":["import { CallbackManagerForLLMRun } from \"@langchain/core/callbacks/manager\";\nimport { AIMessage, BaseMessage, ChatMessage } from \"@langchain/core/messages\";\nimport { ChatGeneration, ChatResult } from \"@langchain/core/outputs\";\nimport { getEnvironmentVariable } from \"@langchain/core/utils/env\";\nimport { IterableReadableStream } from \"@langchain/core/utils/stream\";\nimport {\n  BaseChatModel,\n  type BaseChatModelParams,\n} from \"@langchain/core/language_models/chat_models\";\nimport {\n  BaseWebSocketStream,\n  WebSocketStreamOptions,\n} from \"../../utils/iflytek_websocket_stream.js\";\n\n/**\n * Type representing the role of a message in the Xinghuo chat model.\n */\nexport type XinghuoMessageRole = \"assistant\" | \"user\";\n\n/**\n * Interface representing a message in the Xinghuo chat model.\n */\ninterface XinghuoMessage {\n  role: XinghuoMessageRole;\n  content: string;\n}\n\n/**\n * Interface representing the usage of tokens in a chat completion.\n */\ninterface TokenUsage {\n  completionTokens?: number;\n  promptTokens?: number;\n  totalTokens?: number;\n}\n\n/**\n * Interface representing a request for a chat completion.\n */\ninterface ChatCompletionRequest {\n  messages: XinghuoMessage[];\n  temperature?: number;\n  max_tokens?: number;\n  top_k?: number;\n  chat_id?: string;\n}\n\nexport interface ChatCompletionChunk {\n  header: {\n    code: number;\n    message: string;\n    sid: string;\n    status: number;\n  };\n  payload: {\n    choices: {\n      status: number;\n      seq: number;\n      text: {\n        content: string;\n        role: XinghuoMessageRole;\n        index: number;\n      }[];\n    };\n    usage?: {\n      text: {\n        question_tokens: number;\n        prompt_tokens: number;\n        completion_tokens: number;\n        total_tokens: number;\n      };\n    };\n  };\n}\n\n/**\n * Interface representing a response from a chat completion.\n */\ninterface ChatCompletionResponse {\n  result: string;\n  usage?: {\n    completion_tokens: number;\n    prompt_tokens: number;\n    total_tokens: number;\n  };\n}\n\n/**\n * Function that extracts the custom role of a generic chat message.\n * @param message Chat message from which to extract the custom role.\n * @returns The custom role of the chat message.\n */\nfunction extractGenericMessageCustomRole(message: ChatMessage) {\n  if (message.role !== \"assistant\" && message.role !== \"user\") {\n    console.warn(`Unknown message role: ${message.role}`);\n  }\n  return message.role as XinghuoMessageRole;\n}\n\n/**\n * Function that converts a base message to a Xinghuo message role.\n * @param message Base message to convert.\n * @returns The Xinghuo message role.\n */\nfunction messageToXinghuoRole(message: BaseMessage): XinghuoMessageRole {\n  const type = message._getType();\n  switch (type) {\n    case \"ai\":\n      return \"assistant\";\n    case \"human\":\n      return \"user\";\n    case \"system\":\n      throw new Error(\"System messages should not be here\");\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      return extractGenericMessageCustomRole(message);\n    }\n    default:\n      throw new Error(`Unknown message type: ${type}`);\n  }\n}\n\ndeclare interface IflytekXinghuoChatInput {\n  /** Model version to use. Available options are: v1.1, v2.1, v3.1, v3.5, v4.0\n   * @default \"v3.1\"\n   */\n  version: string;\n\n  /**\n   * ID of the end-user who made requests.\n   */\n  userId?: string;\n\n  /**\n   * APPID to use when making requests. Defaults to the value of\n   * `IFLYTEK_APPID` environment variable.\n   */\n  iflytekAppid?: string;\n\n  /**\n   * API key to use when making requests. Defaults to the value of\n   * `IFLYTEK_API_KEY` environment variable.\n   */\n  iflytekApiKey?: string;\n\n  /**\n   * API Secret to use when making requests. Defaults to the value of\n   * `IFLYTEK_API_SECRET` environment variable.\n   */\n  iflytekApiSecret?: string;\n\n  /** Amount of randomness injected into the response. Ranges\n   * from 0 to 1 (0 is not included). Use temp closer to 0 for analytical /\n   * multiple choice, and temp closer to 1 for creative\n   * and generative tasks. Defaults to 0.5.\n   */\n  temperature?: number;\n\n  max_tokens?: number;\n\n  top_k?: number;\n\n  streaming?: boolean;\n}\n\n/**\n * Wrapper around IflytekXingHuo large language models that use the Chat endpoint.\n *\n * To use you should have the `IFLYTEK_API_KEY` and `IFLYTEK_API_SECRET` and `IFLYTEK_APPID`\n * environment variable set.\n *\n * @augments BaseChatModel\n * @augments IflytekXinghuoChatInput\n */\nexport abstract class BaseChatIflytekXinghuo\n  extends BaseChatModel\n  implements IflytekXinghuoChatInput\n{\n  static lc_name() {\n    return \"ChatIflytekXinghuo\";\n  }\n\n  get callKeys(): string[] {\n    return [\"stop\", \"signal\", \"options\"];\n  }\n\n  get lc_secrets(): { [key: string]: string } | undefined {\n    return {\n      iflytekApiKey: \"IFLYTEK_API_KEY\",\n      iflytekApiSecret: \"IFLYTEK_API_SECRET\",\n    };\n  }\n\n  get lc_aliases(): { [key: string]: string } | undefined {\n    return undefined;\n  }\n\n  lc_serializable = true;\n\n  version = \"v3.1\";\n\n  iflytekAppid: string;\n\n  iflytekApiKey: string;\n\n  iflytekApiSecret: string;\n\n  userId?: string;\n\n  apiUrl: string;\n\n  domain: string;\n\n  temperature = 0.5;\n\n  max_tokens = 2048;\n\n  top_k = 4;\n\n  streaming = false;\n\n  constructor(fields?: Partial<IflytekXinghuoChatInput> & BaseChatModelParams) {\n    super(fields ?? {});\n\n    const iflytekAppid =\n      fields?.iflytekAppid ?? getEnvironmentVariable(\"IFLYTEK_APPID\");\n    if (!iflytekAppid) {\n      throw new Error(\"Iflytek APPID not found\");\n    } else {\n      this.iflytekAppid = iflytekAppid;\n    }\n\n    const iflytekApiKey =\n      fields?.iflytekApiKey ?? getEnvironmentVariable(\"IFLYTEK_API_KEY\");\n    if (!iflytekApiKey) {\n      throw new Error(\"Iflytek API key not found\");\n    } else {\n      this.iflytekApiKey = iflytekApiKey;\n    }\n\n    const iflytekApiSecret =\n      fields?.iflytekApiSecret ?? getEnvironmentVariable(\"IFLYTEK_API_SECRET\");\n    if (!iflytekApiSecret) {\n      throw new Error(\"Iflytek API secret not found\");\n    } else {\n      this.iflytekApiSecret = iflytekApiSecret;\n    }\n\n    this.userId = fields?.userId ?? this.userId;\n    this.streaming = fields?.streaming ?? this.streaming;\n    this.temperature = fields?.temperature ?? this.temperature;\n    this.max_tokens = fields?.max_tokens ?? this.max_tokens;\n    this.top_k = fields?.top_k ?? this.top_k;\n\n    this.version = fields?.version ?? this.version;\n    if (\n      [\"v1.1\", \"v2.1\", \"v3.1\", \"v3.5\", \"v4.0\", \"pro-128k\"].includes(\n        this.version\n      )\n    ) {\n      this.apiUrl = `wss://spark-api.xf-yun.com/${this.version}/chat`;\n      switch (this.version) {\n        case \"v1.1\":\n          this.domain = \"general\";\n          break;\n        case \"v2.1\":\n          this.domain = \"generalv2\";\n          break;\n        case \"v3.1\":\n          this.domain = \"generalv3\";\n          break;\n        case \"v3.5\":\n          this.domain = \"generalv3.5\";\n          break;\n        case \"v4.0\":\n          this.domain = \"4.0Ultra\";\n          break;\n        case \"pro-128k\":\n          this.domain = \"pro-128k\";\n          this.apiUrl = `wss://spark-api.xf-yun.com/chat/${this.version}`;\n          break;\n        default:\n          this.domain = \"generalv3\";\n      }\n    } else {\n      throw new Error(`Invalid model version: ${this.version}`);\n    }\n  }\n\n  /**\n   * Get the identifying parameters for the model\n   */\n  identifyingParams() {\n    return {\n      version: this.version,\n      ...this.invocationParams(),\n    };\n  }\n\n  /**\n   * Get the parameters used to invoke the model\n   */\n  invocationParams(): Omit<ChatCompletionRequest, \"messages\"> & {\n    streaming: boolean;\n  } {\n    return {\n      streaming: this.streaming,\n      temperature: this.temperature,\n      top_k: this.top_k,\n    };\n  }\n\n  /**\n   * Method that retrieves the auth websocketStream for making requests to the Iflytek Xinghuo API.\n   * @returns The auth websocketStream for making requests to the Iflytek Xinghuo API.\n   */\n  abstract openWebSocketStream<T extends BaseWebSocketStream<string>>(\n    options: WebSocketStreamOptions\n  ): Promise<T>;\n\n  /**\n   * Calls the Xinghuo API completion.\n   * @param request The request to send to the Xinghuo API.\n   * @param signal The signal for the API call.\n   * @returns The response from the Xinghuo API.\n   */\n  async completion(\n    request: ChatCompletionRequest,\n    stream: true,\n    signal?: AbortSignal\n  ): Promise<IterableReadableStream<string>>;\n\n  async completion(\n    request: ChatCompletionRequest,\n    stream: false,\n    signal?: AbortSignal\n  ): Promise<ChatCompletionResponse>;\n\n  async completion(\n    request: ChatCompletionRequest,\n    stream: boolean,\n    signal?: AbortSignal\n  ): Promise<IterableReadableStream<string> | ChatCompletionResponse> {\n    const webSocketStream = await this.openWebSocketStream({\n      signal,\n    });\n    const connection = await webSocketStream.connection;\n    const header = {\n      app_id: this.iflytekAppid,\n      uid: this.userId,\n    };\n    const parameter = {\n      chat: {\n        domain: this.domain,\n        temperature: request.temperature ?? this.temperature,\n        max_tokens: request.max_tokens ?? this.max_tokens,\n        top_k: request.top_k ?? this.top_k,\n      },\n    };\n    const payload = {\n      message: {\n        text: request.messages,\n      },\n    };\n    const message = JSON.stringify({\n      header,\n      parameter,\n      payload,\n    });\n    const { writable, readable } = connection;\n    const writer = writable.getWriter();\n    await writer.write(message);\n    const streams = IterableReadableStream.fromReadableStream(readable);\n    if (stream) {\n      return streams;\n    } else {\n      let response: ChatCompletionResponse = { result: \"\" };\n      for await (const chunk of streams) {\n        const data = JSON.parse(chunk) as ChatCompletionChunk;\n        const { header, payload } = data;\n        if (header.code === 0) {\n          if (header.status === 0) {\n            response.result = payload.choices?.text[0]?.content ?? \"\";\n          } else if (header.status === 1) {\n            response.result += payload.choices?.text[0]?.content ?? \"\";\n          } else if (header.status === 2) {\n            response = { ...response, usage: payload.usage?.text };\n            break;\n          }\n        } else {\n          break;\n        }\n      }\n      // eslint-disable-next-line no-void\n      void streams.cancel();\n      // eslint-disable-next-line no-void\n      void webSocketStream.close();\n      return response;\n    }\n  }\n\n  async _generate(\n    messages: BaseMessage[],\n    options: this[\"ParsedCallOptions\"],\n    runManager?: CallbackManagerForLLMRun | undefined\n  ): Promise<ChatResult> {\n    const tokenUsage: TokenUsage = {};\n    const params = this.invocationParams();\n    const messagesMapped: XinghuoMessage[] = messages.map((message) => {\n      if (typeof message.content !== \"string\") {\n        throw new Error(\n          \"ChatIflytekXinghuo does not support non-string message content.\"\n        );\n      }\n      return {\n        role: messageToXinghuoRole(message),\n        content: message.content,\n      };\n    });\n    const data = params.streaming\n      ? await (async () => {\n          const streams = await this.completion(\n            { messages: messagesMapped, ...params },\n            true,\n            options.signal\n          );\n          let response: ChatCompletionResponse = { result: \"\" };\n          for await (const chunk of streams) {\n            const data = JSON.parse(chunk) as ChatCompletionChunk;\n            const { header, payload } = data;\n            if (header.code === 0) {\n              if (header.status === 0) {\n                response.result = payload.choices?.text[0]?.content ?? \"\";\n              } else if (header.status === 1) {\n                response.result += payload.choices?.text[0]?.content ?? \"\";\n              } else if (header.status === 2) {\n                response = { ...response, usage: payload.usage?.text };\n                break;\n              }\n              // eslint-disable-next-line no-void\n              void runManager?.handleLLMNewToken(\n                payload.choices?.text[0]?.content\n              );\n            } else {\n              break;\n            }\n          }\n          // eslint-disable-next-line no-void\n          void streams.cancel();\n          return response;\n        })()\n      : await this.completion(\n          { messages: messagesMapped, ...params },\n          false,\n          options.signal\n        );\n\n    const {\n      completion_tokens: completionTokens,\n      prompt_tokens: promptTokens,\n      total_tokens: totalTokens,\n    } = data.usage ?? {};\n\n    if (completionTokens) {\n      tokenUsage.completionTokens =\n        (tokenUsage.completionTokens ?? 0) + completionTokens;\n    }\n\n    if (promptTokens) {\n      tokenUsage.promptTokens = (tokenUsage.promptTokens ?? 0) + promptTokens;\n    }\n\n    if (totalTokens) {\n      tokenUsage.totalTokens = (tokenUsage.totalTokens ?? 0) + totalTokens;\n    }\n\n    const generations: ChatGeneration[] = [];\n    const text = data.result ?? \"\";\n    generations.push({\n      text,\n      message: new AIMessage(text),\n    });\n\n    return {\n      generations,\n      llmOutput: { tokenUsage },\n    };\n  }\n\n  /** @ignore */\n  // oxlint-disable-next-line typescript/no-explicit-any\n  _combineLLMOutput(): Record<string, any> | undefined {\n    return [];\n  }\n\n  _llmType(): string {\n    return \"iflytek_xinghuo\";\n  }\n}\n"],"mappings":"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"}