{"version":3,"file":"replicate.cjs","names":["LLM","GenerationChunk"],"sources":["../../src/llms/replicate.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 type ReplicateInstance from \"replicate\";\n\n/**\n * Interface defining the structure of the input data for the Replicate\n * class. It includes details about the model to be used, any additional\n * input parameters, and the API key for the Replicate service.\n */\nexport interface ReplicateInput {\n  // owner/model_name:version\n  model: `${string}/${string}:${string}`;\n\n  input?: {\n    // different models accept different inputs\n    [key: string]: string | number | boolean;\n  };\n\n  apiKey?: string;\n\n  /** The key used to pass prompts to the model. */\n  promptKey?: string;\n}\n\n/**\n * Class responsible for managing the interaction with the Replicate API.\n * It handles the API key and model details, makes the actual API calls,\n * and converts the API response into a format usable by the rest of the\n * LangChain framework.\n * @example\n * ```typescript\n * const model = new Replicate({\n *   model: \"replicate/flan-t5-xl:3ae0799123a1fe11f8c89fd99632f843fc5f7a761630160521c4253149754523\",\n * });\n *\n * const res = await model.invoke(\n *   \"Question: What would be a good company name for a company that makes colorful socks?\\nAnswer:\"\n * );\n * console.log({ res });\n * ```\n */\nexport class Replicate extends LLM implements ReplicateInput {\n  static lc_name() {\n    return \"Replicate\";\n  }\n\n  get lc_secrets(): { [key: string]: string } | undefined {\n    return {\n      apiKey: \"REPLICATE_API_TOKEN\",\n    };\n  }\n\n  lc_serializable = true;\n\n  model: ReplicateInput[\"model\"];\n\n  input: ReplicateInput[\"input\"];\n\n  apiKey: string;\n\n  promptKey?: string;\n\n  constructor(fields: ReplicateInput & BaseLLMParams) {\n    super(fields);\n\n    const apiKey =\n      fields?.apiKey ??\n      getEnvironmentVariable(\"REPLICATE_API_KEY\") ?? // previous environment variable for backwards compatibility\n      getEnvironmentVariable(\"REPLICATE_API_TOKEN\"); // current environment variable, matching the Python library\n\n    if (!apiKey) {\n      throw new Error(\n        \"Please set the REPLICATE_API_TOKEN environment variable\"\n      );\n    }\n\n    this.apiKey = apiKey;\n    this.model = fields.model;\n    this.input = fields.input ?? {};\n    this.promptKey = fields.promptKey;\n  }\n\n  _llmType() {\n    return \"replicate\";\n  }\n\n  /** @ignore */\n  async _call(\n    prompt: string,\n    options: this[\"ParsedCallOptions\"]\n  ): Promise<string> {\n    const replicate = await this._prepareReplicate();\n    const input = await this._getReplicateInput(replicate, prompt);\n\n    const output = await this.caller.callWithOptions(\n      { signal: options.signal },\n      () =>\n        replicate.run(this.model, {\n          input,\n        })\n    );\n\n    if (typeof output === \"string\") {\n      return output;\n    } else if (Array.isArray(output)) {\n      return output.join(\"\");\n    } else {\n      // Note this is a little odd, but the output format is not consistent\n      // across models, so it makes some amount of sense.\n      return String(output);\n    }\n  }\n\n  async *_streamResponseChunks(\n    prompt: string,\n    options: this[\"ParsedCallOptions\"],\n    runManager?: CallbackManagerForLLMRun\n  ): AsyncGenerator<GenerationChunk> {\n    const replicate = await this._prepareReplicate();\n    const input = await this._getReplicateInput(replicate, prompt);\n\n    const stream = await this.caller.callWithOptions(\n      { signal: options?.signal },\n      async () =>\n        replicate.stream(this.model, {\n          input,\n        })\n    );\n    for await (const chunk of stream) {\n      if (chunk.event === \"output\") {\n        yield new GenerationChunk({ text: chunk.data, generationInfo: chunk });\n        await runManager?.handleLLMNewToken(chunk.data ?? \"\");\n      }\n\n      // stream is done\n      if (chunk.event === \"done\")\n        yield new GenerationChunk({\n          text: \"\",\n          generationInfo: { finished: true },\n        });\n    }\n  }\n\n  /** @ignore */\n  static async imports(): Promise<{\n    Replicate: typeof ReplicateInstance;\n  }> {\n    try {\n      const { default: Replicate } = await import(\"replicate\");\n      return { Replicate };\n    } catch {\n      throw new Error(\n        \"Please install replicate as a dependency with, e.g. `pnpm install replicate`\"\n      );\n    }\n  }\n\n  private async _prepareReplicate(): Promise<ReplicateInstance> {\n    const imports = await Replicate.imports();\n\n    return new imports.Replicate({\n      userAgent: \"langchain\",\n      auth: this.apiKey,\n    });\n  }\n\n  private async _getReplicateInput(\n    replicate: ReplicateInstance,\n    prompt: string\n  ) {\n    if (this.promptKey === undefined) {\n      const [modelString, versionString] = this.model.split(\":\");\n      const version = await replicate.models.versions.get(\n        modelString.split(\"/\")[0],\n        modelString.split(\"/\")[1],\n        versionString\n      );\n      const openapiSchema = version.openapi_schema;\n      const inputProperties: { \"x-order\": number | undefined }[] =\n        // oxlint-disable-next-line typescript/no-explicit-any\n        (openapiSchema as any)?.components?.schemas?.Input?.properties;\n      if (inputProperties === undefined) {\n        this.promptKey = \"prompt\";\n      } else {\n        const sortedInputProperties = Object.entries(inputProperties).sort(\n          ([_keyA, valueA], [_keyB, valueB]) => {\n            const orderA = valueA[\"x-order\"] || 0;\n            const orderB = valueB[\"x-order\"] || 0;\n            return orderA - orderB;\n          }\n        );\n        this.promptKey = sortedInputProperties[0][0] ?? \"prompt\";\n      }\n    }\n\n    return {\n      [this.promptKey!]: prompt,\n      ...this.input,\n    };\n  }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AA4CA,IAAa,YAAb,MAAa,kBAAkBA,qCAAAA,IAA8B;CAC3D,OAAO,UAAU;AACf,SAAO;;CAGT,IAAI,aAAoD;AACtD,SAAO,EACL,QAAQ,uBACT;;CAGH,kBAAkB;CAElB;CAEA;CAEA;CAEA;CAEA,YAAY,QAAwC;AAClD,QAAM,OAAO;EAEb,MAAM,SACJ,QAAQ,WAAA,GAAA,0BAAA,wBACe,oBAAoB,KAAA,GAAA,0BAAA,wBACpB,sBAAsB;AAE/C,MAAI,CAAC,OACH,OAAM,IAAI,MACR,0DACD;AAGH,OAAK,SAAS;AACd,OAAK,QAAQ,OAAO;AACpB,OAAK,QAAQ,OAAO,SAAS,EAAE;AAC/B,OAAK,YAAY,OAAO;;CAG1B,WAAW;AACT,SAAO;;;CAIT,MAAM,MACJ,QACA,SACiB;EACjB,MAAM,YAAY,MAAM,KAAK,mBAAmB;EAChD,MAAM,QAAQ,MAAM,KAAK,mBAAmB,WAAW,OAAO;EAE9D,MAAM,SAAS,MAAM,KAAK,OAAO,gBAC/B,EAAE,QAAQ,QAAQ,QAAQ,QAExB,UAAU,IAAI,KAAK,OAAO,EACxB,OACD,CAAC,CACL;AAED,MAAI,OAAO,WAAW,SACpB,QAAO;WACE,MAAM,QAAQ,OAAO,CAC9B,QAAO,OAAO,KAAK,GAAG;MAItB,QAAO,OAAO,OAAO;;CAIzB,OAAO,sBACL,QACA,SACA,YACiC;EACjC,MAAM,YAAY,MAAM,KAAK,mBAAmB;EAChD,MAAM,QAAQ,MAAM,KAAK,mBAAmB,WAAW,OAAO;EAE9D,MAAM,SAAS,MAAM,KAAK,OAAO,gBAC/B,EAAE,QAAQ,SAAS,QAAQ,EAC3B,YACE,UAAU,OAAO,KAAK,OAAO,EAC3B,OACD,CAAC,CACL;AACD,aAAW,MAAM,SAAS,QAAQ;AAChC,OAAI,MAAM,UAAU,UAAU;AAC5B,UAAM,IAAIC,wBAAAA,gBAAgB;KAAE,MAAM,MAAM;KAAM,gBAAgB;KAAO,CAAC;AACtE,UAAM,YAAY,kBAAkB,MAAM,QAAQ,GAAG;;AAIvD,OAAI,MAAM,UAAU,OAClB,OAAM,IAAIA,wBAAAA,gBAAgB;IACxB,MAAM;IACN,gBAAgB,EAAE,UAAU,MAAM;IACnC,CAAC;;;;CAKR,aAAa,UAEV;AACD,MAAI;GACF,MAAM,EAAE,SAAS,cAAc,MAAM,OAAO;AAC5C,UAAO,EAAE,WAAW;UACd;AACN,SAAM,IAAI,MACR,+EACD;;;CAIL,MAAc,oBAAgD;AAG5D,SAAO,KAFS,OAAM,UAAU,SAAS,GAEtB,UAAU;GAC3B,WAAW;GACX,MAAM,KAAK;GACZ,CAAC;;CAGJ,MAAc,mBACZ,WACA,QACA;AACA,MAAI,KAAK,cAAc,KAAA,GAAW;GAChC,MAAM,CAAC,aAAa,iBAAiB,KAAK,MAAM,MAAM,IAAI;GAO1D,MAAM,mBANU,MAAM,UAAU,OAAO,SAAS,IAC9C,YAAY,MAAM,IAAI,CAAC,IACvB,YAAY,MAAM,IAAI,CAAC,IACvB,cACD,EAC6B,gBAGJ,YAAY,SAAS,OAAO;AACtD,OAAI,oBAAoB,KAAA,EACtB,MAAK,YAAY;OASjB,MAAK,YAPyB,OAAO,QAAQ,gBAAgB,CAAC,MAC3D,CAAC,OAAO,SAAS,CAAC,OAAO,YAAY;AAGpC,YAFe,OAAO,cAAc,MACrB,OAAO,cAAc;KAGvC,CACsC,GAAG,MAAM;;AAIpD,SAAO;IACJ,KAAK,YAAa;GACnB,GAAG,KAAK;GACT"}