{"version":3,"file":"llms.cjs","names":["LLM","convertEventStreamToIterableReadableDataStream","GenerationChunk"],"sources":["../src/llms.ts"],"sourcesContent":["import { LLM, type BaseLLMParams } from \"@langchain/core/language_models/llms\";\nimport { getEnvironmentVariable } from \"@langchain/core/utils/env\";\nimport { CallbackManagerForLLMRun } from \"@langchain/core/callbacks/manager\";\nimport { GenerationChunk } from \"@langchain/core/outputs\";\n\nimport { convertEventStreamToIterableReadableDataStream } from \"./utils/event_source_parse.js\";\n\n/**\n * Interface for CloudflareWorkersAI input parameters.\n */\nexport interface CloudflareWorkersAIInput {\n  cloudflareAccountId?: string;\n  cloudflareApiToken?: string;\n  model?: string;\n  baseUrl?: string;\n  streaming?: boolean;\n}\n\n/**\n * Class representing the CloudflareWorkersAI language model. It extends the LLM (Large\n * Language Model) class, providing a standard interface for interacting\n * with the CloudflareWorkersAI language model.\n */\nexport class CloudflareWorkersAI\n  extends LLM\n  implements CloudflareWorkersAIInput\n{\n  model = \"@cf/meta/llama-2-7b-chat-int8\";\n\n  cloudflareAccountId?: string;\n\n  cloudflareApiToken?: string;\n\n  baseUrl: string;\n\n  streaming = false;\n\n  static lc_name() {\n    return \"CloudflareWorkersAI\";\n  }\n\n  lc_serializable = true;\n\n  constructor(fields?: CloudflareWorkersAIInput & BaseLLMParams) {\n    super(fields ?? {});\n    this._addVersion(\"@langchain/cloudflare\", __PKG_VERSION__);\n\n    this.model = fields?.model ?? this.model;\n    this.streaming = fields?.streaming ?? this.streaming;\n    this.cloudflareAccountId =\n      fields?.cloudflareAccountId ??\n      getEnvironmentVariable(\"CLOUDFLARE_ACCOUNT_ID\");\n    this.cloudflareApiToken =\n      fields?.cloudflareApiToken ??\n      getEnvironmentVariable(\"CLOUDFLARE_API_TOKEN\");\n    this.baseUrl =\n      fields?.baseUrl ??\n      `https://api.cloudflare.com/client/v4/accounts/${this.cloudflareAccountId}/ai/run`;\n    if (this.baseUrl.endsWith(\"/\")) {\n      this.baseUrl = this.baseUrl.slice(0, -1);\n    }\n  }\n\n  /**\n   * Method to validate the environment.\n   */\n  validateEnvironment() {\n    if (this.baseUrl === undefined) {\n      if (!this.cloudflareAccountId) {\n        throw new Error(\n          `No Cloudflare account ID found. Please provide it when instantiating the CloudflareWorkersAI class, or set it as \"CLOUDFLARE_ACCOUNT_ID\" in your environment variables.`\n        );\n      }\n      if (!this.cloudflareApiToken) {\n        throw new Error(\n          `No Cloudflare API key found. Please provide it when instantiating the CloudflareWorkersAI class, or set it as \"CLOUDFLARE_API_KEY\" in your environment variables.`\n        );\n      }\n    }\n  }\n\n  /** Get the identifying parameters for this LLM. */\n  get identifyingParams() {\n    return { model: this.model };\n  }\n\n  /**\n   * Get the parameters used to invoke the model\n   */\n  invocationParams() {\n    return {\n      model: this.model,\n    };\n  }\n\n  /** Get the type of LLM. */\n  _llmType() {\n    return \"cloudflare\";\n  }\n\n  async _request(\n    prompt: string,\n    options: this[\"ParsedCallOptions\"],\n    stream?: boolean\n  ) {\n    this.validateEnvironment();\n\n    const url = `${this.baseUrl}/${this.model}`;\n    const headers = {\n      Authorization: `Bearer ${this.cloudflareApiToken}`,\n      \"Content-Type\": \"application/json\",\n    };\n\n    const data = { prompt, stream };\n    return this.caller.call(async () => {\n      const response = await fetch(url, {\n        method: \"POST\",\n        headers,\n        body: JSON.stringify(data),\n        signal: options.signal,\n      });\n      if (!response.ok) {\n        const error = new Error(\n          `Cloudflare LLM call failed with status code ${response.status}`\n        );\n        // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n        (error as any).response = response;\n        throw error;\n      }\n      return response;\n    });\n  }\n\n  async *_streamResponseChunks(\n    prompt: string,\n    options: this[\"ParsedCallOptions\"],\n    runManager?: CallbackManagerForLLMRun\n  ): AsyncGenerator<GenerationChunk> {\n    const response = await this._request(prompt, options, true);\n    if (!response.body) {\n      throw new Error(\"Empty response from Cloudflare. Please try again.\");\n    }\n    const stream = convertEventStreamToIterableReadableDataStream(\n      response.body\n    );\n    for await (const chunk of stream) {\n      if (chunk !== \"[DONE]\") {\n        const parsedChunk = JSON.parse(chunk);\n        const generationChunk = new GenerationChunk({\n          text: parsedChunk.response,\n        });\n        yield generationChunk;\n        // oxlint-disable-next-line no-void\n        void runManager?.handleLLMNewToken(generationChunk.text ?? \"\");\n      }\n    }\n  }\n\n  /** Call out to CloudflareWorkersAI's complete endpoint.\n   Args:\n       prompt: The prompt to pass into the model.\n   Returns:\n       The string generated by the model.\n   Example:\n   let response = CloudflareWorkersAI.call(\"Tell me a joke.\");\n   */\n  async _call(\n    prompt: string,\n    options: this[\"ParsedCallOptions\"],\n    runManager?: CallbackManagerForLLMRun\n  ): Promise<string> {\n    if (!this.streaming) {\n      const response = await this._request(prompt, options);\n\n      const responseData = await response.json();\n\n      return responseData.result.response;\n    } else {\n      const stream = this._streamResponseChunks(prompt, options, runManager);\n      let finalResult: GenerationChunk | undefined;\n      for await (const chunk of stream) {\n        if (finalResult === undefined) {\n          finalResult = chunk;\n        } else {\n          finalResult = finalResult.concat(chunk);\n        }\n      }\n      return finalResult?.text ?? \"\";\n    }\n  }\n}\n"],"mappings":";;;;;;;;;;;AAuBA,IAAa,sBAAb,cACUA,qCAAAA,IAEV;CACE,QAAQ;CAER;CAEA;CAEA;CAEA,YAAY;CAEZ,OAAO,UAAU;AACf,SAAO;;CAGT,kBAAkB;CAElB,YAAY,QAAmD;AAC7D,QAAM,UAAU,EAAE,CAAC;AACnB,OAAK,YAAY,yBAAA,QAAyC;AAE1D,OAAK,QAAQ,QAAQ,SAAS,KAAK;AACnC,OAAK,YAAY,QAAQ,aAAa,KAAK;AAC3C,OAAK,sBACH,QAAQ,wBAAA,GAAA,0BAAA,wBACe,wBAAwB;AACjD,OAAK,qBACH,QAAQ,uBAAA,GAAA,0BAAA,wBACe,uBAAuB;AAChD,OAAK,UACH,QAAQ,WACR,iDAAiD,KAAK,oBAAoB;AAC5E,MAAI,KAAK,QAAQ,SAAS,IAAI,CAC5B,MAAK,UAAU,KAAK,QAAQ,MAAM,GAAG,GAAG;;;;;CAO5C,sBAAsB;AACpB,MAAI,KAAK,YAAY,KAAA,GAAW;AAC9B,OAAI,CAAC,KAAK,oBACR,OAAM,IAAI,MACR,0KACD;AAEH,OAAI,CAAC,KAAK,mBACR,OAAM,IAAI,MACR,oKACD;;;;CAMP,IAAI,oBAAoB;AACtB,SAAO,EAAE,OAAO,KAAK,OAAO;;;;;CAM9B,mBAAmB;AACjB,SAAO,EACL,OAAO,KAAK,OACb;;;CAIH,WAAW;AACT,SAAO;;CAGT,MAAM,SACJ,QACA,SACA,QACA;AACA,OAAK,qBAAqB;EAE1B,MAAM,MAAM,GAAG,KAAK,QAAQ,GAAG,KAAK;EACpC,MAAM,UAAU;GACd,eAAe,UAAU,KAAK;GAC9B,gBAAgB;GACjB;EAED,MAAM,OAAO;GAAE;GAAQ;GAAQ;AAC/B,SAAO,KAAK,OAAO,KAAK,YAAY;GAClC,MAAM,WAAW,MAAM,MAAM,KAAK;IAChC,QAAQ;IACR;IACA,MAAM,KAAK,UAAU,KAAK;IAC1B,QAAQ,QAAQ;IACjB,CAAC;AACF,OAAI,CAAC,SAAS,IAAI;IAChB,MAAM,wBAAQ,IAAI,MAChB,+CAA+C,SAAS,SACzD;AAEA,UAAc,WAAW;AAC1B,UAAM;;AAER,UAAO;IACP;;CAGJ,OAAO,sBACL,QACA,SACA,YACiC;EACjC,MAAM,WAAW,MAAM,KAAK,SAAS,QAAQ,SAAS,KAAK;AAC3D,MAAI,CAAC,SAAS,KACZ,OAAM,IAAI,MAAM,oDAAoD;EAEtE,MAAM,SAASC,2BAAAA,+CACb,SAAS,KACV;AACD,aAAW,MAAM,SAAS,OACxB,KAAI,UAAU,UAAU;GAEtB,MAAM,kBAAkB,IAAIC,wBAAAA,gBAAgB,EAC1C,MAFkB,KAAK,MAAM,MAEZ,CAAC,UACnB,CAAC;AACF,SAAM;AAED,eAAY,kBAAkB,gBAAgB,QAAQ,GAAG;;;;;;;;;;;CAapE,MAAM,MACJ,QACA,SACA,YACiB;AACjB,MAAI,CAAC,KAAK,UAKR,SAAO,OAFoB,MAFJ,KAAK,SAAS,QAAQ,QAAQ,EAEjB,MAAM,EAEtB,OAAO;OACtB;GACL,MAAM,SAAS,KAAK,sBAAsB,QAAQ,SAAS,WAAW;GACtE,IAAI;AACJ,cAAW,MAAM,SAAS,OACxB,KAAI,gBAAgB,KAAA,EAClB,eAAc;OAEd,eAAc,YAAY,OAAO,MAAM;AAG3C,UAAO,aAAa,QAAQ"}