@langchain/community
Version:
Third-party integrations for LangChain.js
1 lines • 8.13 kB
Source Map (JSON)
{"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"}