{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import type { Pipeline, PipelineResult } from 'open-guardrail-core';\n\n/**\n * Vercel AI SDK middleware-compatible interface.\n * Works with `experimental_middleware` in `generateText` / `streamText`.\n */\nexport interface GuardrailMiddleware {\n  /**\n   * Transform params before sending to the model.\n   * Runs input guards on the last user message.\n   */\n  transformParams?: (options: {\n    params: LanguageModelParams;\n  }) => Promise<LanguageModelParams>;\n\n  /**\n   * Wrap generate to run output guards on the response.\n   */\n  wrapGenerate?: (options: {\n    doGenerate: () => Promise<GenerateResult>;\n    params: LanguageModelParams;\n  }) => Promise<GenerateResult>;\n}\n\ninterface LanguageModelParams {\n  prompt: Array<{ role: string; content: string | Array<{ type: string; text?: string }> }>;\n  [key: string]: unknown;\n}\n\ninterface GenerateResult {\n  text?: string;\n  [key: string]: unknown;\n}\n\nexport interface GuardrailMiddlewareOptions {\n  input?: Pipeline;\n  output?: Pipeline;\n  onBlocked?: (result: PipelineResult, stage: 'input' | 'output') => void;\n}\n\nexport class GuardrailBlockedError extends Error {\n  readonly stage: 'input' | 'output';\n  readonly result: PipelineResult;\n\n  constructor(stage: 'input' | 'output', result: PipelineResult) {\n    super(`Guardrail blocked at ${stage} stage: ${result.action}`);\n    this.name = 'GuardrailBlockedError';\n    this.stage = stage;\n    this.result = result;\n  }\n}\n\nfunction extractLastUserMessage(params: LanguageModelParams): string | null {\n  for (let i = params.prompt.length - 1; i >= 0; i--) {\n    const msg = params.prompt[i];\n    if (msg.role === 'user') {\n      if (typeof msg.content === 'string') return msg.content;\n      if (Array.isArray(msg.content)) {\n        const textPart = msg.content.find((p) => p.type === 'text' && p.text);\n        return textPart?.text ?? null;\n      }\n    }\n  }\n  return null;\n}\n\nfunction replaceLastUserMessage(params: LanguageModelParams, newText: string): LanguageModelParams {\n  const prompt = [...params.prompt];\n  for (let i = prompt.length - 1; i >= 0; i--) {\n    if (prompt[i].role === 'user') {\n      prompt[i] = { ...prompt[i], content: newText };\n      break;\n    }\n  }\n  return { ...params, prompt };\n}\n\nexport function createGuardrailMiddleware(options: GuardrailMiddlewareOptions): GuardrailMiddleware {\n  const middleware: GuardrailMiddleware = {};\n\n  if (options.input) {\n    middleware.transformParams = async ({ params }) => {\n      const userMessage = extractLastUserMessage(params);\n      if (!userMessage) return params;\n\n      const result = await options.input!.run(userMessage);\n\n      if (!result.passed) {\n        options.onBlocked?.(result, 'input');\n        throw new GuardrailBlockedError('input', result);\n      }\n\n      if (result.output && result.output !== userMessage) {\n        return replaceLastUserMessage(params, result.output);\n      }\n\n      return params;\n    };\n  }\n\n  if (options.output) {\n    middleware.wrapGenerate = async ({ doGenerate, params }) => {\n      const generateResult = await doGenerate();\n\n      if (generateResult.text) {\n        const result = await options.output!.run(generateResult.text);\n\n        if (!result.passed) {\n          options.onBlocked?.(result, 'output');\n          throw new GuardrailBlockedError('output', result);\n        }\n\n        if (result.output) {\n          return { ...generateResult, text: result.output };\n        }\n      }\n\n      return generateResult;\n    };\n  }\n\n  return middleware;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAwCO,IAAM,wBAAN,cAAoC,MAAM;AAAA,EACtC;AAAA,EACA;AAAA,EAET,YAAY,OAA2B,QAAwB;AAC7D,UAAM,wBAAwB,KAAK,WAAW,OAAO,MAAM,EAAE;AAC7D,SAAK,OAAO;AACZ,SAAK,QAAQ;AACb,SAAK,SAAS;AAAA,EAChB;AACF;AAEA,SAAS,uBAAuB,QAA4C;AAC1E,WAAS,IAAI,OAAO,OAAO,SAAS,GAAG,KAAK,GAAG,KAAK;AAClD,UAAM,MAAM,OAAO,OAAO,CAAC;AAC3B,QAAI,IAAI,SAAS,QAAQ;AACvB,UAAI,OAAO,IAAI,YAAY,SAAU,QAAO,IAAI;AAChD,UAAI,MAAM,QAAQ,IAAI,OAAO,GAAG;AAC9B,cAAM,WAAW,IAAI,QAAQ,KAAK,CAAC,MAAM,EAAE,SAAS,UAAU,EAAE,IAAI;AACpE,eAAO,UAAU,QAAQ;AAAA,MAC3B;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,uBAAuB,QAA6B,SAAsC;AACjG,QAAM,SAAS,CAAC,GAAG,OAAO,MAAM;AAChC,WAAS,IAAI,OAAO,SAAS,GAAG,KAAK,GAAG,KAAK;AAC3C,QAAI,OAAO,CAAC,EAAE,SAAS,QAAQ;AAC7B,aAAO,CAAC,IAAI,EAAE,GAAG,OAAO,CAAC,GAAG,SAAS,QAAQ;AAC7C;AAAA,IACF;AAAA,EACF;AACA,SAAO,EAAE,GAAG,QAAQ,OAAO;AAC7B;AAEO,SAAS,0BAA0B,SAA0D;AAClG,QAAM,aAAkC,CAAC;AAEzC,MAAI,QAAQ,OAAO;AACjB,eAAW,kBAAkB,OAAO,EAAE,OAAO,MAAM;AACjD,YAAM,cAAc,uBAAuB,MAAM;AACjD,UAAI,CAAC,YAAa,QAAO;AAEzB,YAAM,SAAS,MAAM,QAAQ,MAAO,IAAI,WAAW;AAEnD,UAAI,CAAC,OAAO,QAAQ;AAClB,gBAAQ,YAAY,QAAQ,OAAO;AACnC,cAAM,IAAI,sBAAsB,SAAS,MAAM;AAAA,MACjD;AAEA,UAAI,OAAO,UAAU,OAAO,WAAW,aAAa;AAClD,eAAO,uBAAuB,QAAQ,OAAO,MAAM;AAAA,MACrD;AAEA,aAAO;AAAA,IACT;AAAA,EACF;AAEA,MAAI,QAAQ,QAAQ;AAClB,eAAW,eAAe,OAAO,EAAE,YAAY,OAAO,MAAM;AAC1D,YAAM,iBAAiB,MAAM,WAAW;AAExC,UAAI,eAAe,MAAM;AACvB,cAAM,SAAS,MAAM,QAAQ,OAAQ,IAAI,eAAe,IAAI;AAE5D,YAAI,CAAC,OAAO,QAAQ;AAClB,kBAAQ,YAAY,QAAQ,QAAQ;AACpC,gBAAM,IAAI,sBAAsB,UAAU,MAAM;AAAA,QAClD;AAEA,YAAI,OAAO,QAAQ;AACjB,iBAAO,EAAE,GAAG,gBAAgB,MAAM,OAAO,OAAO;AAAA,QAClD;AAAA,MACF;AAEA,aAAO;AAAA,IACT;AAAA,EACF;AAEA,SAAO;AACT;","names":[]}