(
scriptPath: string,
context: {
vars: Record<string, VarValue>;
provider?: ApiProvider;
config?: {
basePath?: string;
timeout?: number;
};
},
)
| 23 | * @returns The prompt output from the script. |
| 24 | */ |
| 25 | export const executablePromptFunction = async ( |
| 26 | scriptPath: string, |
| 27 | context: { |
| 28 | vars: Record<string, VarValue>; |
| 29 | provider?: ApiProvider; |
| 30 | config?: { |
| 31 | basePath?: string; |
| 32 | timeout?: number; |
| 33 | }; |
| 34 | }, |
| 35 | ): Promise<string> => { |
| 36 | invariant(context.provider?.id, 'provider.id is required'); |
| 37 | |
| 38 | const transformedContext: PromptFunctionContext = { |
| 39 | vars: context.vars, |
| 40 | provider: { |
| 41 | id: |
| 42 | typeof context.provider?.id === 'function' ? context.provider?.id() : context.provider?.id, |
| 43 | label: context.provider?.label, |
| 44 | }, |
| 45 | config: context.config ?? {}, |
| 46 | }; |
| 47 | |
| 48 | const scriptParts = parseScriptParts(scriptPath); |
| 49 | const fileHashes = getFileHashes(scriptParts); |
| 50 | |
| 51 | const cacheKey = `exec-prompt:${scriptPath}:${fileHashes.join(':')}:${safeJsonStringify(transformedContext)}`; |
| 52 | |
| 53 | let cachedResult; |
| 54 | if (fileHashes.length > 0 && isCacheEnabled()) { |
| 55 | const cache = getCache(); |
| 56 | cachedResult = await cache.get(cacheKey); |
| 57 | |
| 58 | if (cachedResult) { |
| 59 | logger.debug(`Returning cached result for executable prompt ${scriptPath}`); |
| 60 | return cachedResult as string; |
| 61 | } |
| 62 | } |
| 63 | |
| 64 | return new Promise<string>((resolve, reject) => { |
| 65 | const command = scriptParts.shift(); |
| 66 | invariant(command, 'No command found in script path'); |
| 67 | |
| 68 | // Pass context as JSON argument to the script |
| 69 | const scriptArgs = scriptParts.concat([safeJsonStringify(transformedContext) as string]); |
| 70 | |
| 71 | const options = { |
| 72 | cwd: context.config?.basePath, |
| 73 | timeout: context.config?.timeout || 60000, // Default 60 second timeout |
| 74 | }; |
| 75 | |
| 76 | logger.debug(`Executing prompt script: ${command} ${scriptArgs.join(' ')}`); |
| 77 | |
| 78 | execFile(command, scriptArgs, options, async (error, stdout, stderr) => { |
| 79 | if (error) { |
| 80 | logger.error(`Error running executable prompt ${scriptPath}: ${error.message}`); |
| 81 | reject(error); |
| 82 | return; |
no test coverage detected
searching dependent graphs…