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;
}