{"version":3,"file":"layerup_security.cjs","names":["LLM","LayerupSecuritySDK"],"sources":["../../src/llms/layerup_security.ts"],"sourcesContent":["import {\n  LLM,\n  BaseLLM,\n  type BaseLLMCallOptions,\n} from \"@langchain/core/language_models/llms\";\nimport {\n  GuardrailResponse,\n  LayerupSecurity as LayerupSecuritySDK,\n  LLMMessage,\n} from \"@layerup/layerup-security\";\n\nexport interface LayerupSecurityOptions extends BaseLLMCallOptions {\n  llm: BaseLLM;\n  layerupApiKey?: string;\n  layerupApiBaseUrl?: string;\n  promptGuardrails?: string[];\n  responseGuardrails?: string[];\n  mask?: boolean;\n  metadata?: Record<string, unknown>;\n  handlePromptGuardrailViolation?: (violation: GuardrailResponse) => LLMMessage;\n  handleResponseGuardrailViolation?: (\n    violation: GuardrailResponse\n  ) => LLMMessage;\n}\n\nfunction defaultGuardrailViolationHandler(\n  violation: GuardrailResponse\n): LLMMessage {\n  if (violation.canned_response) return violation.canned_response;\n\n  const guardrailName = violation.offending_guardrail\n    ? `Guardrail ${violation.offending_guardrail}`\n    : \"A guardrail\";\n  throw new Error(\n    `${guardrailName} was violated without a proper guardrail violation handler.`\n  );\n}\n\nexport class LayerupSecurity extends LLM {\n  static lc_name() {\n    return \"LayerupSecurity\";\n  }\n\n  lc_serializable = true;\n\n  llm: BaseLLM;\n\n  layerupApiKey: string;\n\n  layerupApiBaseUrl = \"https://api.uselayerup.com/v1\";\n\n  promptGuardrails: string[] = [];\n\n  responseGuardrails: string[] = [];\n\n  mask = false;\n\n  metadata: Record<string, unknown> = {};\n\n  handlePromptGuardrailViolation: (violation: GuardrailResponse) => LLMMessage =\n    defaultGuardrailViolationHandler;\n\n  handleResponseGuardrailViolation: (\n    violation: GuardrailResponse\n  ) => LLMMessage = defaultGuardrailViolationHandler;\n\n  private layerup: LayerupSecuritySDK;\n\n  constructor(options: LayerupSecurityOptions) {\n    super(options);\n\n    if (!options.llm) {\n      throw new Error(\"Layerup Security requires an LLM to be provided.\");\n    } else if (!options.layerupApiKey) {\n      throw new Error(\"Layerup Security requires an API key to be provided.\");\n    }\n\n    this.llm = options.llm;\n    this.layerupApiKey = options.layerupApiKey;\n    this.layerupApiBaseUrl =\n      options.layerupApiBaseUrl || this.layerupApiBaseUrl;\n    this.promptGuardrails = options.promptGuardrails || this.promptGuardrails;\n    this.responseGuardrails =\n      options.responseGuardrails || this.responseGuardrails;\n    this.mask = options.mask || this.mask;\n    this.metadata = options.metadata || this.metadata;\n    this.handlePromptGuardrailViolation =\n      options.handlePromptGuardrailViolation ||\n      this.handlePromptGuardrailViolation;\n    this.handleResponseGuardrailViolation =\n      options.handleResponseGuardrailViolation ||\n      this.handleResponseGuardrailViolation;\n\n    this.layerup = new LayerupSecuritySDK({\n      apiKey: this.layerupApiKey,\n      baseURL: this.layerupApiBaseUrl,\n    });\n  }\n\n  _llmType() {\n    return \"layerup_security\";\n  }\n\n  async _call(input: string, options?: BaseLLMCallOptions): Promise<string> {\n    // Since LangChain LLMs only support string inputs, we will wrap each call to Layerup in a single-message\n    // array of messages, then extract the string element when we need to access it.\n    let messages: LLMMessage[] = [\n      {\n        role: \"user\",\n        content: input,\n      },\n    ];\n    let unmaskResponse;\n\n    if (this.mask) {\n      [messages, unmaskResponse] = await this.layerup.maskPrompt(\n        messages,\n        this.metadata\n      );\n    }\n\n    if (this.promptGuardrails.length > 0) {\n      const securityResponse = await this.layerup.executeGuardrails(\n        this.promptGuardrails,\n        messages,\n        input,\n        this.metadata\n      );\n\n      // If there is a guardrail violation, extract the canned response and reply with that instead\n      if (!securityResponse.all_safe) {\n        const replacedResponse: LLMMessage =\n          this.handlePromptGuardrailViolation(securityResponse);\n        return replacedResponse.content as string;\n      }\n    }\n\n    // Invoke the underlying LLM with the prompt and options\n    let result = await this.llm.invoke(messages[0].content as string, options);\n\n    if (this.mask && unmaskResponse) {\n      result = unmaskResponse(result);\n    }\n\n    // Add to messages array for response guardrail handler\n    messages.push({\n      role: \"assistant\",\n      content: result,\n    });\n\n    if (this.responseGuardrails.length > 0) {\n      const securityResponse = await this.layerup.executeGuardrails(\n        this.responseGuardrails,\n        messages,\n        result,\n        this.metadata\n      );\n\n      // If there is a guardrail violation, extract the canned response and reply with that instead\n      if (!securityResponse.all_safe) {\n        const replacedResponse: LLMMessage =\n          this.handleResponseGuardrailViolation(securityResponse);\n        return replacedResponse.content as string;\n      }\n    }\n\n    return result;\n  }\n}\n"],"mappings":";;;;;;AAyBA,SAAS,iCACP,WACY;AACZ,KAAI,UAAU,gBAAiB,QAAO,UAAU;CAEhD,MAAM,gBAAgB,UAAU,sBAC5B,aAAa,UAAU,wBACvB;AACJ,OAAM,IAAI,MACR,GAAG,cAAc,6DAClB;;AAGH,IAAa,kBAAb,cAAqCA,qCAAAA,IAAI;CACvC,OAAO,UAAU;AACf,SAAO;;CAGT,kBAAkB;CAElB;CAEA;CAEA,oBAAoB;CAEpB,mBAA6B,EAAE;CAE/B,qBAA+B,EAAE;CAEjC,OAAO;CAEP,WAAoC,EAAE;CAEtC,iCACE;CAEF,mCAEkB;CAElB;CAEA,YAAY,SAAiC;AAC3C,QAAM,QAAQ;AAEd,MAAI,CAAC,QAAQ,IACX,OAAM,IAAI,MAAM,mDAAmD;WAC1D,CAAC,QAAQ,cAClB,OAAM,IAAI,MAAM,uDAAuD;AAGzE,OAAK,MAAM,QAAQ;AACnB,OAAK,gBAAgB,QAAQ;AAC7B,OAAK,oBACH,QAAQ,qBAAqB,KAAK;AACpC,OAAK,mBAAmB,QAAQ,oBAAoB,KAAK;AACzD,OAAK,qBACH,QAAQ,sBAAsB,KAAK;AACrC,OAAK,OAAO,QAAQ,QAAQ,KAAK;AACjC,OAAK,WAAW,QAAQ,YAAY,KAAK;AACzC,OAAK,iCACH,QAAQ,kCACR,KAAK;AACP,OAAK,mCACH,QAAQ,oCACR,KAAK;AAEP,OAAK,UAAU,IAAIC,0BAAAA,gBAAmB;GACpC,QAAQ,KAAK;GACb,SAAS,KAAK;GACf,CAAC;;CAGJ,WAAW;AACT,SAAO;;CAGT,MAAM,MAAM,OAAe,SAA+C;EAGxE,IAAI,WAAyB,CAC3B;GACE,MAAM;GACN,SAAS;GACV,CACF;EACD,IAAI;AAEJ,MAAI,KAAK,KACP,EAAC,UAAU,kBAAkB,MAAM,KAAK,QAAQ,WAC9C,UACA,KAAK,SACN;AAGH,MAAI,KAAK,iBAAiB,SAAS,GAAG;GACpC,MAAM,mBAAmB,MAAM,KAAK,QAAQ,kBAC1C,KAAK,kBACL,UACA,OACA,KAAK,SACN;AAGD,OAAI,CAAC,iBAAiB,SAGpB,QADE,KAAK,+BAA+B,iBAAiB,CAC/B;;EAK5B,IAAI,SAAS,MAAM,KAAK,IAAI,OAAO,SAAS,GAAG,SAAmB,QAAQ;AAE1E,MAAI,KAAK,QAAQ,eACf,UAAS,eAAe,OAAO;AAIjC,WAAS,KAAK;GACZ,MAAM;GACN,SAAS;GACV,CAAC;AAEF,MAAI,KAAK,mBAAmB,SAAS,GAAG;GACtC,MAAM,mBAAmB,MAAM,KAAK,QAAQ,kBAC1C,KAAK,oBACL,UACA,QACA,KAAK,SACN;AAGD,OAAI,CAAC,iBAAiB,SAGpB,QADE,KAAK,iCAAiC,iBAAiB,CACjC;;AAI5B,SAAO"}