{"version":3,"file":"openai_moderation.cjs","names":["BaseChain","OpenAIClient","AsyncCaller"],"sources":["../../src/chains/openai_moderation.ts"],"sourcesContent":["import { type ClientOptions, OpenAIClient } from \"@langchain/openai\";\nimport { ChainValues } from \"@langchain/core/utils/types\";\nimport {\n  AsyncCaller,\n  AsyncCallerParams,\n} from \"@langchain/core/utils/async_caller\";\nimport { getEnvironmentVariable } from \"@langchain/core/utils/env\";\nimport { BaseChain, ChainInputs } from \"./base.js\";\n\n/**\n * Interface for the input parameters of the OpenAIModerationChain class.\n */\nexport interface OpenAIModerationChainInput\n  extends ChainInputs, AsyncCallerParams {\n  apiKey?: string;\n  /** @deprecated Use \"apiKey\" instead. */\n  openAIApiKey?: string;\n  openAIOrganization?: string;\n  throwError?: boolean;\n  configuration?: ClientOptions;\n}\n\n/**\n * Class representing a chain for moderating text using the OpenAI\n * Moderation API. It extends the BaseChain class and implements the\n * OpenAIModerationChainInput interface.\n * @example\n * ```typescript\n * const moderation = new OpenAIModerationChain({ throwError: true });\n *\n * const badString = \"Bad naughty words from user\";\n *\n * try {\n *   const { output: moderatedContent, results } = await moderation.call({\n *     input: badString,\n *   });\n *\n *   if (results[0].category_scores[\"harassment/threatening\"] > 0.01) {\n *     throw new Error(\"Harassment detected!\");\n *   }\n *\n *   const model = new OpenAI({ temperature: 0 });\n *   const promptTemplate = \"Hello, how are you today {person}?\";\n *   const prompt = new PromptTemplate({\n *     template: promptTemplate,\n *     inputVariables: [\"person\"],\n *   });\n *   const chain = new LLMChain({ llm: model, prompt });\n *   const response = await chain.call({ person: moderatedContent });\n *   console.log({ response });\n * } catch (error) {\n *   console.error(\"Naughty words detected!\");\n * }\n * ```\n */\nexport class OpenAIModerationChain\n  extends BaseChain\n  implements OpenAIModerationChainInput\n{\n  static lc_name() {\n    return \"OpenAIModerationChain\";\n  }\n\n  get lc_secrets(): { [key: string]: string } | undefined {\n    return {\n      openAIApiKey: \"OPENAI_API_KEY\",\n    };\n  }\n\n  inputKey = \"input\";\n\n  outputKey = \"output\";\n\n  openAIApiKey?: string;\n\n  openAIOrganization?: string;\n\n  clientConfig: ClientOptions;\n\n  client: OpenAIClient;\n\n  throwError: boolean;\n\n  caller: AsyncCaller;\n\n  constructor(fields?: OpenAIModerationChainInput) {\n    super(fields);\n    this.throwError = fields?.throwError ?? false;\n    this.openAIApiKey =\n      fields?.apiKey ??\n      fields?.openAIApiKey ??\n      getEnvironmentVariable(\"OPENAI_API_KEY\");\n\n    if (!this.openAIApiKey) {\n      throw new Error(\"OpenAI API key not found\");\n    }\n\n    this.openAIOrganization = fields?.openAIOrganization;\n\n    this.clientConfig = {\n      ...fields?.configuration,\n      apiKey: this.openAIApiKey,\n      organization: this.openAIOrganization,\n    };\n\n    this.client = new OpenAIClient(this.clientConfig);\n\n    this.caller = new AsyncCaller(fields ?? {});\n  }\n\n  _moderate(text: string, results: OpenAIClient.Moderation): string {\n    if (results.flagged) {\n      const errorStr = \"Text was found that violates OpenAI's content policy.\";\n      if (this.throwError) {\n        throw new Error(errorStr);\n      } else {\n        return errorStr;\n      }\n    }\n    return text;\n  }\n\n  async _call(values: ChainValues): Promise<ChainValues> {\n    const text = values[this.inputKey];\n    const moderationRequest: OpenAIClient.ModerationCreateParams = {\n      input: text,\n    };\n    let mod;\n    try {\n      mod = await this.caller.call(() =>\n        this.client.moderations.create(moderationRequest)\n      );\n    } catch (error) {\n      // oxlint-disable-next-line no-instanceof/no-instanceof\n      if (error instanceof Error) {\n        throw error;\n      } else {\n        throw new Error(error as string);\n      }\n    }\n    const output = this._moderate(text, mod.results[0]);\n    return {\n      [this.outputKey]: output,\n      results: mod.results,\n    };\n  }\n\n  _chainType() {\n    return \"moderation_chain\";\n  }\n\n  get inputKeys(): string[] {\n    return [this.inputKey];\n  }\n\n  get outputKeys(): string[] {\n    return [this.outputKey];\n  }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAuDA,IAAa,wBAAb,cACUA,aAAAA,UAEV;CACE,OAAO,UAAU;AACf,SAAO;;CAGT,IAAI,aAAoD;AACtD,SAAO,EACL,cAAc,kBACf;;CAGH,WAAW;CAEX,YAAY;CAEZ;CAEA;CAEA;CAEA;CAEA;CAEA;CAEA,YAAY,QAAqC;AAC/C,QAAM,OAAO;AACb,OAAK,aAAa,QAAQ,cAAc;AACxC,OAAK,eACH,QAAQ,UACR,QAAQ,iBAAA,GAAA,0BAAA,wBACe,iBAAiB;AAE1C,MAAI,CAAC,KAAK,aACR,OAAM,IAAI,MAAM,2BAA2B;AAG7C,OAAK,qBAAqB,QAAQ;AAElC,OAAK,eAAe;GAClB,GAAG,QAAQ;GACX,QAAQ,KAAK;GACb,cAAc,KAAK;GACpB;AAED,OAAK,SAAS,IAAIC,kBAAAA,aAAa,KAAK,aAAa;AAEjD,OAAK,SAAS,IAAIC,mCAAAA,YAAY,UAAU,EAAE,CAAC;;CAG7C,UAAU,MAAc,SAA0C;AAChE,MAAI,QAAQ,SAAS;GACnB,MAAM,WAAW;AACjB,OAAI,KAAK,WACP,OAAM,IAAI,MAAM,SAAS;OAEzB,QAAO;;AAGX,SAAO;;CAGT,MAAM,MAAM,QAA2C;EACrD,MAAM,OAAO,OAAO,KAAK;EACzB,MAAM,oBAAyD,EAC7D,OAAO,MACR;EACD,IAAI;AACJ,MAAI;AACF,SAAM,MAAM,KAAK,OAAO,WACtB,KAAK,OAAO,YAAY,OAAO,kBAAkB,CAClD;WACM,OAAO;AAEd,OAAI,iBAAiB,MACnB,OAAM;OAEN,OAAM,IAAI,MAAM,MAAgB;;EAGpC,MAAM,SAAS,KAAK,UAAU,MAAM,IAAI,QAAQ,GAAG;AACnD,SAAO;IACJ,KAAK,YAAY;GAClB,SAAS,IAAI;GACd;;CAGH,aAAa;AACX,SAAO;;CAGT,IAAI,YAAsB;AACxB,SAAO,CAAC,KAAK,SAAS;;CAGxB,IAAI,aAAuB;AACzB,SAAO,CAAC,KAAK,UAAU"}