From 99d5fbe296c29a50af803baee6359731b0f9ece3 Mon Sep 17 00:00:00 2001 From: Anthony Barone Date: Thu, 23 May 2024 14:16:50 -0400 Subject: [PATCH] Recursively look for `.prompt` files in specified dir Fixes https://github.com/firebase/genkit/issues/210. --- js/plugins/dotprompt/src/index.ts | 5 +++++ js/plugins/dotprompt/src/registry.ts | 22 +++++++++++++++++----- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/js/plugins/dotprompt/src/index.ts b/js/plugins/dotprompt/src/index.ts index e8f956fa7..b64cdbce9 100644 --- a/js/plugins/dotprompt/src/index.ts +++ b/js/plugins/dotprompt/src/index.ts @@ -28,6 +28,11 @@ import { loadPromptFolder, lookupPrompt } from './registry.js'; export { defineDotprompt, Dotprompt }; export interface DotpromptPluginOptions { + // Directory to look for .prompt files. + // + // Note: This directory will be searched recursively, and any sub-directory + // paths will be included in the prompt name. E.g. - if a prompt file is + // located at `/foo/bar.prompt`, the prompt name will be `foo-bar`. dir: string; } diff --git a/js/plugins/dotprompt/src/registry.ts b/js/plugins/dotprompt/src/registry.ts index 9ccba374c..803f23cb3 100644 --- a/js/plugins/dotprompt/src/registry.ts +++ b/js/plugins/dotprompt/src/registry.ts @@ -80,7 +80,7 @@ export async function loadPromptFolder( promptsPath, { withFileTypes: true, - recursive: false, + recursive: true, }, (err, dirEnts) => { if (err) { @@ -88,7 +88,15 @@ export async function loadPromptFolder( } else { dirEnts.forEach(async (dirEnt) => { if (dirEnt.isFile() && dirEnt.name.endsWith('.prompt')) { - loadPrompt(dirEnt.path, dirEnt.name); + // If this prompt is in a subdirectory, we need to include that + // in the namespace to prevent naming conflicts. + let prefix = ''; + if (promptsPath !== dirEnt.path) { + prefix = dirEnt.path + .replace(`${promptsPath}/`, '') + .replace(/\//g, '-'); + } + loadPrompt(dirEnt.path, dirEnt.name, prefix); } }); resolve(); @@ -101,8 +109,12 @@ export async function loadPromptFolder( }); } -export function loadPrompt(path: string, filename: string): Dotprompt { - let name = basename(filename, '.prompt'); +export function loadPrompt( + path: string, + filename: string, + prefix = '' +): Dotprompt { + let name = `${prefix ? `${prefix}-` : ''}${basename(filename, '.prompt')}`; let variant: string | null = null; if (name.includes('.')) { const parts = name.split('.'); @@ -114,6 +126,6 @@ export function loadPrompt(path: string, filename: string): Dotprompt { if (variant) { prompt.variant = variant; } - prompt.define({ ns: 'dotprompt' }); + prompt.define({ ns: `dotprompt` }); return prompt; }