{"version":3,"file":"moderation.cjs","names":["initChatModel","AIMessage","HumanMessage","ToolMessage","createMiddleware"],"sources":["../../../../../src/agents/middleware/provider/openai/moderation.ts"],"sourcesContent":["import type { BaseMessage } from \"@langchain/core/messages\";\nimport { AIMessage, HumanMessage, ToolMessage } from \"@langchain/core/messages\";\nimport type { BaseChatModel } from \"@langchain/core/language_models/chat_models\";\nimport { BaseLanguageModel } from \"@langchain/core/language_models/base\";\n\nimport { initChatModel } from \"../../../../chat_models/universal.js\";\nimport { createMiddleware } from \"../../../middleware.js\";\nimport type { MiddlewareResult, AgentMiddleware } from \"../../types.js\";\nimport type { AgentBuiltInState } from \"../../../runtime.js\";\n\n/**\n * OpenAI model interface.\n */\ninterface OpenAIModel extends BaseLanguageModel {\n  getName: () => string;\n  _getClientOptions: () => unknown;\n  client: {\n    moderations: {\n      create: (\n        input: {\n          input: string | string[];\n          model: string;\n        },\n        options?: unknown\n      ) => Promise<ModerationResponse>;\n    };\n  };\n}\n\n/**\n * Check if the model is an OpenAI model that supports moderation.\n * @param model - The model to check.\n * @returns Whether the model is an OpenAI model that supports moderation.\n */\nfunction isOpenAIModel(model: unknown): model is OpenAIModel {\n  if (\n    !model ||\n    typeof model !== \"object\" ||\n    model === null ||\n    !(\"client\" in model) ||\n    !(\"_getClientOptions\" in model) ||\n    typeof model._getClientOptions !== \"function\"\n  ) {\n    return false;\n  }\n\n  /**\n   * client may not yet be initialized, so we need to check if the model has a _getClientOptions method.\n   */\n  model._getClientOptions();\n  return (\n    typeof model.client === \"object\" &&\n    model.client !== null &&\n    \"moderations\" in model.client &&\n    typeof model.client.moderations === \"object\" &&\n    model.client.moderations !== null &&\n    \"create\" in model.client.moderations &&\n    typeof model.client.moderations.create === \"function\"\n  );\n}\n\n/**\n * Stage where a violation occurred.\n */\nexport type ViolationStage = \"input\" | \"output\" | \"tool\";\n\n/**\n * Default template for violation messages.\n */\nconst DEFAULT_VIOLATION_TEMPLATE =\n  \"I'm sorry, but I can't comply with that request. It was flagged for {categories}.\";\n\n/**\n * Result of moderation.\n * @see https://platform.openai.com/docs/api-reference/moderations/object\n */\ninterface ModerationResult {\n  flagged: boolean;\n  categories: Record<string, boolean>;\n  category_scores: Record<string, number>;\n  category_applied_input_types: Record<string, string[]>;\n}\n\n/**\n * Moderation response.\n * @see https://platform.openai.com/docs/api-reference/moderations/create\n */\ninterface ModerationResponse {\n  id: string;\n  model: string;\n  results: ModerationResult[];\n}\n\ntype ModerationModel =\n  | \"omni-moderation-latest\"\n  | \"omni-moderation-2024-09-26\"\n  | \"text-moderation-latest\"\n  | \"text-moderation-stable\";\n\n/**\n * Error raised when OpenAI flags content and `exitBehavior` is set to `\"error\"`.\n */\nexport class OpenAIModerationError extends Error {\n  content: string;\n  stage: ViolationStage;\n  result: ModerationResult;\n  originalMessage: string;\n\n  constructor({\n    content,\n    stage,\n    result,\n    message,\n  }: {\n    content: string;\n    stage: ViolationStage;\n    result: ModerationResult;\n    message: string;\n  }) {\n    super(message);\n    this.name = \"OpenAIModerationError\";\n    this.content = content;\n    this.stage = stage;\n    this.result = result;\n    this.originalMessage = message;\n  }\n}\n\n/**\n * Options for configuring the OpenAI Moderation middleware.\n */\nexport interface OpenAIModerationMiddlewareOptions {\n  /**\n   * OpenAI model to use for moderation. Can be either a model name or a BaseChatModel instance.\n   * @example\n   * ```ts\n   * const model = new ChatOpenAI({ model: \"gpt-4o-mini\" });\n   * const middleware = openAIModerationMiddleware({ model });\n   * const agent = createAgent({\n   *   model,\n   *   middleware: [middleware],\n   * });\n   * ```\n   * @example\n   * ```ts\n   * const middleware = openAIModerationMiddleware({ model: \"gpt-4o-mini\" });\n   * const agent = createAgent({\n   *   model: \"gpt-5\",\n   *   middleware: [middleware],\n   * });\n   * ```\n   */\n  model: string | BaseChatModel;\n\n  /**\n   * Moderation model to use.\n   * @default \"omni-moderation-latest\"\n   */\n  moderationModel?: ModerationModel;\n\n  /**\n   * Whether to check user input messages.\n   * @default true\n   */\n  checkInput?: boolean;\n\n  /**\n   * Whether to check model output messages.\n   * @default true\n   */\n  checkOutput?: boolean;\n\n  /**\n   * Whether to check tool result messages.\n   * @default false\n   */\n  checkToolResults?: boolean;\n\n  /**\n   * How to handle violations.\n   * - `\"error\"`: Throw an error when content is flagged\n   * - `\"end\"`: End the agent execution and return a violation message\n   * - `\"replace\"`: Replace the flagged content with a violation message\n   * @default \"end\"\n   */\n  exitBehavior?: \"error\" | \"end\" | \"replace\";\n\n  /**\n   * Custom template for violation messages.\n   * Available placeholders: `{categories}`, `{category_scores}`, `{original_content}`\n   */\n  violationMessage?: string;\n}\n\n/**\n * Middleware that moderates agent traffic using OpenAI's moderation endpoint.\n *\n * This middleware checks messages for content policy violations at different stages:\n * - Input: User messages before they reach the model\n * - Output: AI model responses\n * - Tool results: Results returned from tool executions\n *\n * @param options - Configuration options for the middleware\n * @param options.model - OpenAI model to use for moderation. Can be either a model name or a BaseChatModel instance.\n * @param options.moderationModel - Moderation model to use.\n * @param options.checkInput - Whether to check user input messages.\n * @param options.checkOutput - Whether to check model output messages.\n * @param options.checkToolResults - Whether to check tool result messages.\n * @param options.exitBehavior - How to handle violations.\n * @param options.violationMessage - Custom template for violation messages.\n * @returns Middleware function that can be used to moderate agent traffic.\n *\n * @example  Using model instance\n * ```ts\n * import { createAgent, openAIModerationMiddleware } from \"langchain\";\n *\n * const middleware = openAIModerationMiddleware({\n *   checkInput: true,\n *   checkOutput: true,\n *   exitBehavior: \"end\"\n * });\n *\n * const agent = createAgent({\n *   model: \"openai:gpt-4o\",\n *   tools: [...],\n *   middleware: [middleware],\n * });\n * ```\n *\n * @example Using model name\n * ```ts\n * import { createAgent, openAIModerationMiddleware } from \"langchain\";\n *\n * const middleware = openAIModerationMiddleware({\n *   model: \"gpt-4o-mini\",\n *   checkInput: true,\n *   checkOutput: true,\n *   exitBehavior: \"end\"\n * });\n *\n * const agent = createAgent({\n *   model: \"openai:gpt-4o\",\n *   tools: [...],\n *   middleware: [middleware],\n * });\n * ```\n *\n * @example Custom violation message\n * ```ts\n * const middleware = openAIModerationMiddleware({\n *   violationMessage: \"Content flagged: {categories}. Scores: {category_scores}\"\n * });\n * ```\n */\nexport function openAIModerationMiddleware(\n  options: OpenAIModerationMiddlewareOptions\n): AgentMiddleware {\n  const {\n    model,\n    moderationModel = \"omni-moderation-latest\",\n    checkInput = true,\n    checkOutput = true,\n    checkToolResults = false,\n    exitBehavior = \"end\",\n    violationMessage,\n  } = options;\n\n  let openaiModel: OpenAIModel | undefined;\n  const initModerationModel = async (): Promise<OpenAIModel> => {\n    if (openaiModel) {\n      return openaiModel;\n    }\n\n    const resolvedModel =\n      typeof model === \"string\" ? await initChatModel(model) : model;\n\n    /**\n     * Check if the model is an OpenAI model.\n     */\n    if (!resolvedModel.getName().includes(\"ChatOpenAI\")) {\n      throw new Error(\n        `Model must be an OpenAI model to use moderation middleware. Got: ${resolvedModel.getName()}`\n      );\n    }\n\n    /**\n     * check if OpenAI model package supports moderation.\n     */\n    if (!isOpenAIModel(resolvedModel)) {\n      throw new Error(\n        \"Model must support moderation to use moderation middleware.\"\n      );\n    }\n\n    openaiModel = resolvedModel as unknown as OpenAIModel;\n    return openaiModel;\n  };\n\n  /**\n   * Extract text content from a message.\n   */\n  const extractText = (message: BaseMessage): string | null => {\n    if (message.content == null) {\n      return null;\n    }\n    const text = message.text;\n    return text || null;\n  };\n\n  /**\n   * Find the last index of a message type in the messages array.\n   */\n  const findLastIndex = (\n    messages: BaseMessage[],\n    messageType: typeof AIMessage | typeof HumanMessage | typeof ToolMessage\n  ): number | null => {\n    for (let idx = messages.length - 1; idx >= 0; idx--) {\n      if (messageType.isInstance(messages[idx])) {\n        return idx;\n      }\n    }\n    return null;\n  };\n\n  /**\n   * Format violation message from moderation result.\n   */\n  const formatViolationMessage = (\n    content: string,\n    result: ModerationResult\n  ): string => {\n    // Convert categories to array of flagged category names\n    const categories: string[] = [];\n    const categoriesObj = result.categories as unknown as Record<\n      string,\n      boolean\n    >;\n    for (const [name, flagged] of Object.entries(categoriesObj)) {\n      if (flagged) {\n        categories.push(name.replace(/_/g, \" \"));\n      }\n    }\n\n    const categoryLabel =\n      categories.length > 0\n        ? categories.join(\", \")\n        : \"OpenAI's safety policies\";\n\n    const template = violationMessage || DEFAULT_VIOLATION_TEMPLATE;\n    const scoresJson = JSON.stringify(\n      result.category_scores as unknown as Record<string, number>,\n      null,\n      2\n    );\n\n    try {\n      return template\n        .replace(\"{categories}\", categoryLabel)\n        .replace(\"{category_scores}\", scoresJson)\n        .replace(\"{original_content}\", content);\n    } catch {\n      return template;\n    }\n  };\n\n  function moderateContent(\n    input: string | string[],\n    params?: { model?: ModerationModel; options?: unknown }\n  ): Promise<ModerationResponse> {\n    const clientOptions = openaiModel?._getClientOptions?.();\n    const moderationModel = params?.model ?? \"omni-moderation-latest\";\n    const moderationRequest = {\n      input,\n      model: moderationModel,\n    };\n    return openaiModel!.client.moderations.create(\n      moderationRequest,\n      clientOptions\n    );\n  }\n\n  /**\n   * Apply violation handling based on exit behavior.\n   */\n  const applyViolation = (\n    messages: BaseMessage[],\n    index: number | null,\n    stage: ViolationStage,\n    content: string,\n    result: ModerationResult\n  ): MiddlewareResult<Partial<AgentBuiltInState>> | undefined => {\n    const violationText = formatViolationMessage(content, result);\n\n    if (exitBehavior === \"error\") {\n      throw new OpenAIModerationError({\n        content,\n        stage,\n        result,\n        message: violationText,\n      });\n    }\n\n    if (exitBehavior === \"end\") {\n      return {\n        jumpTo: \"end\",\n        messages: [new AIMessage({ content: violationText })],\n      };\n    }\n\n    if (index == null) {\n      return undefined;\n    }\n\n    /**\n     * Replace the original message with a new message that contains the violation text.\n     */\n    const newMessages = [...messages];\n    const original = newMessages[index];\n    const MessageConstructor = Object.getPrototypeOf(original).constructor;\n    newMessages[index] = new MessageConstructor({\n      ...original,\n      content: violationText,\n    });\n\n    return { messages: newMessages };\n  };\n\n  /**\n   * Moderate user input messages.\n   */\n  const moderateUserMessage = async (\n    messages: BaseMessage[]\n  ): Promise<MiddlewareResult<Partial<AgentBuiltInState>> | null> => {\n    const idx = findLastIndex(messages, HumanMessage);\n    if (idx == null) {\n      return null;\n    }\n\n    const message = messages[idx];\n    const text = extractText(message);\n    if (!text) {\n      return null;\n    }\n\n    await initModerationModel();\n    const response = await moderateContent(text, {\n      model: moderationModel,\n    });\n\n    const flaggedResult = response.results.find((result) => result.flagged);\n    if (!flaggedResult) {\n      return null;\n    }\n\n    return applyViolation(messages, idx, \"input\", text, flaggedResult);\n  };\n\n  /**\n   * Moderate tool result messages.\n   */\n  const moderateToolMessages = async (\n    messages: BaseMessage[]\n  ): Promise<MiddlewareResult<Partial<AgentBuiltInState>> | null> => {\n    const lastAiIdx = findLastIndex(messages, AIMessage);\n    if (lastAiIdx == null) {\n      return null;\n    }\n\n    const working = [...messages];\n    let modified = false;\n\n    for (let idx = lastAiIdx + 1; idx < working.length; idx++) {\n      const msg = working[idx];\n      if (!ToolMessage.isInstance(msg)) {\n        continue;\n      }\n\n      const text = extractText(msg);\n      if (!text) {\n        continue;\n      }\n\n      await initModerationModel();\n      const response = await moderateContent(text, {\n        model: moderationModel,\n      });\n      const flaggedResult = response.results.find((result) => result.flagged);\n      if (!flaggedResult) {\n        continue;\n      }\n\n      const action = applyViolation(working, idx, \"tool\", text, flaggedResult);\n      if (action) {\n        if (\"jumpTo\" in action) {\n          return action;\n        }\n        if (\"messages\" in action) {\n          working.splice(\n            0,\n            working.length,\n            ...(action.messages as BaseMessage[])\n          );\n          modified = true;\n        }\n      }\n    }\n\n    if (modified) {\n      return { messages: working };\n    }\n\n    return null;\n  };\n\n  /**\n   * Moderate model output messages.\n   */\n  const moderateOutput = async (\n    messages: BaseMessage[]\n  ): Promise<MiddlewareResult<Partial<AgentBuiltInState>> | null> => {\n    const lastAiIdx = findLastIndex(messages, AIMessage);\n    if (lastAiIdx == null) {\n      return null;\n    }\n\n    const aiMessage = messages[lastAiIdx];\n    const text = extractText(aiMessage);\n    if (!text) {\n      return null;\n    }\n\n    await initModerationModel();\n    const response = await moderateContent(text, {\n      model: moderationModel,\n    });\n    const flaggedResult = response.results.find((result) => result.flagged);\n    if (!flaggedResult) {\n      return null;\n    }\n\n    return applyViolation(messages, lastAiIdx, \"output\", text, flaggedResult);\n  };\n\n  /**\n   * Moderate inputs (user messages and tool results) before model call.\n   */\n  const moderateInputs = async (\n    messages: BaseMessage[]\n  ): Promise<MiddlewareResult<Partial<AgentBuiltInState>> | null> => {\n    const working = [...messages];\n    let modified = false;\n\n    if (checkToolResults) {\n      const action = await moderateToolMessages(working);\n      if (action) {\n        if (\"jumpTo\" in action) {\n          return action;\n        }\n        if (\"messages\" in action) {\n          working.splice(\n            0,\n            working.length,\n            ...(action.messages as BaseMessage[])\n          );\n          modified = true;\n        }\n      }\n    }\n\n    if (checkInput) {\n      const action = await moderateUserMessage(working);\n      if (action) {\n        if (\"jumpTo\" in action) {\n          return action;\n        }\n        if (\"messages\" in action) {\n          working.splice(\n            0,\n            working.length,\n            ...(action.messages as BaseMessage[])\n          );\n          modified = true;\n        }\n      }\n    }\n\n    if (modified) {\n      return { messages: working };\n    }\n\n    return null;\n  };\n\n  return createMiddleware({\n    name: \"OpenAIModerationMiddleware\",\n    beforeModel: {\n      hook: async (\n        state\n      ): Promise<MiddlewareResult<Partial<AgentBuiltInState>> | undefined> => {\n        if (!checkInput && !checkToolResults) {\n          return undefined;\n        }\n\n        const messages = state.messages || [];\n        if (messages.length === 0) {\n          return undefined;\n        }\n\n        return (await moderateInputs(messages)) ?? undefined;\n      },\n      canJumpTo: [\"end\"],\n    },\n    afterModel: {\n      hook: async (\n        state\n      ): Promise<MiddlewareResult<Partial<AgentBuiltInState>> | undefined> => {\n        if (!checkOutput) {\n          return undefined;\n        }\n\n        const messages = state.messages || [];\n        if (messages.length === 0) {\n          return undefined;\n        }\n\n        return (await moderateOutput(messages)) ?? undefined;\n      },\n      canJumpTo: [\"end\"],\n    },\n  });\n}\n"],"mappings":"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"}