{"version":3,"sources":["../src/template.ts"],"sourcesContent":["/**\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { MediaPart, MessageData, Part, Role } from '@genkit-ai/ai/model';\nimport { DocumentData } from '@genkit-ai/ai/retriever';\nimport Handlebars from 'handlebars';\nimport { PromptMetadata } from './metadata.js';\n\nconst Promptbars: typeof Handlebars =\n  global['dotprompt.handlebars'] || Handlebars.create();\nglobal['dotprompt.handlebars'] = Promptbars;\n\nfunction jsonHelper(serializable: any, options: { hash: { indent?: number } }) {\n  return new Promptbars.SafeString(\n    JSON.stringify(serializable, null, options.hash.indent || 0)\n  );\n}\nPromptbars.registerHelper('json', jsonHelper);\n\nfunction roleHelper(role: string) {\n  return new Promptbars.SafeString(`<<<dotprompt:role:${role}>>>`);\n}\nPromptbars.registerHelper('role', roleHelper);\n\nfunction historyHelper() {\n  return new Promptbars.SafeString('<<<dotprompt:history>>>');\n}\nPromptbars.registerHelper('history', historyHelper);\n\nfunction sectionHelper(name: string) {\n  return new Promptbars.SafeString(`<<<dotprompt:section ${name}>>>`);\n}\nPromptbars.registerHelper('section', sectionHelper);\n\nfunction mediaHelper(options: Handlebars.HelperOptions) {\n  return new Promptbars.SafeString(\n    `<<<dotprompt:media:url ${options.hash.url}${\n      options.hash.contentType ? ` ${options.hash.contentType}` : ''\n    }>>>`\n  );\n}\nPromptbars.registerHelper('media', mediaHelper);\n\nconst ROLE_REGEX = /(<<<dotprompt:(?:role:[a-z]+|history))>>>/g;\n\nfunction toMessages(\n  renderedString: string,\n  options?: { context?: DocumentData[]; messages?: MessageData[] }\n): MessageData[] {\n  let currentMessage: { role: string; source: string } = {\n    role: 'user',\n    source: '',\n  };\n  const messageSources: {\n    role: string;\n    source?: string;\n    content?: MessageData['content'];\n    metadata?: Record<string, unknown>;\n  }[] = [currentMessage];\n\n  for (const piece of renderedString\n    .split(ROLE_REGEX)\n    .filter((s) => s.trim() !== '')) {\n    if (piece.startsWith('<<<dotprompt:role:')) {\n      const role = piece.substring(18);\n      if (currentMessage.source.trim()) {\n        currentMessage = { role, source: '' };\n        messageSources.push(currentMessage);\n      } else {\n        currentMessage.role = role;\n      }\n    } else if (piece.startsWith('<<<dotprompt:history')) {\n      messageSources.push(\n        ...(options?.messages?.map((m) => {\n          return {\n            ...m,\n            metadata: { ...(m.metadata || {}), purpose: 'history' },\n          };\n        }) || [])\n      );\n      currentMessage = { role: 'model', source: '' };\n      messageSources.push(currentMessage);\n    } else {\n      currentMessage.source += piece;\n    }\n  }\n\n  const messages: MessageData[] = messageSources\n    .filter((ms) => ms.content || ms.source)\n    .map((m) => {\n      const out: MessageData = {\n        role: m.role as Role,\n        content: m.content || toParts(m.source!),\n      };\n      if (m.metadata) out.metadata = m.metadata;\n      return out;\n    });\n\n  if (\n    !options?.messages ||\n    messages.find((m) => m.metadata?.purpose === 'history')\n  )\n    return messages;\n\n  if (messages.at(-1)?.role === 'user') {\n    return [\n      ...messages.slice(0, -1),\n      ...options.messages,\n      messages.at(-1),\n    ] as MessageData[];\n  }\n\n  return [...messages, ...options.messages] as MessageData[];\n}\n\nconst PART_REGEX = /(<<<dotprompt:(?:media:url|section).*?)>>>/g;\n\nfunction toParts(source: string): Part[] {\n  const parts: Part[] = [];\n  const pieces = source.split(PART_REGEX).filter((s) => s.trim() !== '');\n  for (let i = 0; i < pieces.length; i++) {\n    const piece = pieces[i];\n    if (piece.startsWith('<<<dotprompt:media:')) {\n      // eslint-disable-next-line @typescript-eslint/no-unused-vars\n      const [_, url, contentType] = piece.split(' ');\n      const part: MediaPart = { media: { url } };\n      if (contentType) part.media.contentType = contentType;\n      parts.push(part);\n    } else if (piece.startsWith('<<<dotprompt:section')) {\n      const [_, sectionType] = piece.split(' ');\n      parts.push({ metadata: { purpose: sectionType, pending: true } });\n    } else {\n      parts.push({ text: piece });\n    }\n  }\n\n  return parts;\n}\n\nexport function compile<Variables = any>(\n  source: string,\n  metadata: PromptMetadata\n) {\n  const renderString = Promptbars.compile<Variables>(source, {\n    knownHelpers: {\n      json: true,\n      section: true,\n      media: true,\n      role: true,\n      history: true,\n    },\n  });\n\n  return (\n    input: Variables,\n    options?: { context?: DocumentData[]; messages?: MessageData[] },\n    data?: Record<string, any>\n  ) => {\n    const renderedString = renderString(input, {\n      data: {\n        metadata: { prompt: metadata, context: options?.context || null },\n        ...data,\n      },\n    });\n    return toMessages(renderedString, options);\n  };\n}\n\nexport function defineHelper(name: string, fn: Handlebars.HelperDelegate) {\n  Promptbars.registerHelper(name, fn);\n}\n\nexport function definePartial(name: string, source: string) {\n  Promptbars.registerPartial(name, source);\n}\n"],"mappings":"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","names":["_a"]}