MCPcopy
hub / github.com/promptfoo/promptfoo / maybeLoadFromExternalFile

Function maybeLoadFromExternalFile

src/util/file.ts:75–231  ·  view source on GitHub ↗
(
  filePath: string | object | Function | undefined | null,
  context?: 'assertion' | 'general' | 'vars',
)

Source from the content-addressed store, hash-verified

73 * @throws {Error} If the specified file does not exist.
74 */
75export function maybeLoadFromExternalFile(
76 filePath: string | object | Function | undefined | null,
77 context?: 'assertion' | 'general' | 'vars',
78) {
79 if (Array.isArray(filePath)) {
80 return filePath.map((path) => {
81 const content: any = maybeLoadFromExternalFile(path, context);
82 return content;
83 });
84 }
85
86 if (typeof filePath !== 'string') {
87 return filePath;
88 }
89 if (!filePath.startsWith('file://')) {
90 return filePath;
91 }
92
93 // Render the file path using Nunjucks
94 const renderedFilePath = getNunjucksEngineForFilePath().renderString(filePath, {});
95
96 // Parse the file URL to extract file path and function name using existing utility
97 // This handles colon splitting correctly, including Windows drive letters (C:\path)
98 const { filePath: cleanPath, functionName } = parseFileUrl(renderedFilePath);
99
100 // In assertion contexts, always preserve Python/JS file references
101 // This prevents premature dereferencing of assertion files that should be
102 // handled by the assertion system, not the generic config loader
103 if (context === 'assertion' && (cleanPath.endsWith('.py') || isJavascriptFile(cleanPath))) {
104 logger.debug(`Preserving Python/JS file reference in assertion context: ${renderedFilePath}`);
105 return renderedFilePath;
106 }
107
108 // In vars contexts, preserve all file:// references for test case expansion
109 // This prevents premature file loading - JS/Python files should be executed at runtime
110 // by renderPrompt in evaluatorHelpers.ts, and glob patterns should be expanded by
111 // generateVarCombinations in evaluator.ts
112 if (context === 'vars') {
113 logger.debug(`Preserving file reference in vars context: ${renderedFilePath}`);
114 return renderedFilePath;
115 }
116
117 // For Python/JS files with function names, return the original string unchanged
118 // to allow the assertion system to handle function loading at execution time.
119 // This prevents premature file existence checks that would fail for function references.
120 if (functionName && (cleanPath.endsWith('.py') || isJavascriptFile(cleanPath))) {
121 return renderedFilePath;
122 }
123
124 // For non-Python/JS files, use the original path (ignore potential function name)
125 const pathToUse =
126 functionName && !(cleanPath.endsWith('.py') || isJavascriptFile(cleanPath))
127 ? renderedFilePath.slice('file://'.length) // Use original path for non-script files
128 : cleanPath;
129
130 const resolvedPath = path.resolve(cliState.basePath || '', pathToUse);
131
132 // Check if the path contains glob patterns

Callers 15

file.test.tsFile · 0.90
createRuntimeTestSuiteFunction · 0.90
constructorMethod · 0.90
setCookiesMethod · 0.90
callGeminiApiMethod · 0.90
callGeminiMethod · 0.90
loadFileFunction · 0.90
loadCredentialsMethod · 0.90
callGeminiApiMethod · 0.90
getIntentTestCountFunction · 0.90
constructorMethod · 0.90

Calls 7

parseFileUrlFunction · 0.90
isJavascriptFileFunction · 0.90
resolveMethod · 0.80
parseMethod · 0.80
pushMethod · 0.80
valuesMethod · 0.80

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…