MCPcopy
hub / github.com/promptfoo/promptfoo / callApi

Method callApi

src/providers/scriptCompletion.ts:67–136  ·  view source on GitHub ↗
(prompt: string, context?: CallApiContextParams)

Source from the content-addressed store, hash-verified

65 }
66
67 async callApi(prompt: string, context?: CallApiContextParams): Promise<ProviderResponse> {
68 const scriptParts = parseScriptParts(this.scriptPath);
69 const fileHashes = getFileHashes(scriptParts);
70
71 if (fileHashes.length === 0) {
72 logger.warn(`Could not find any valid files in the command: ${this.scriptPath}`);
73 }
74
75 const cacheKey = `exec:${this.scriptPath}:${fileHashes.join(':')}:${prompt}:${JSON.stringify(this.options)}`;
76
77 let cachedResult;
78 if (fileHashes.length > 0 && isCacheEnabled()) {
79 const cache = await getCache();
80 cachedResult = await cache.get(cacheKey);
81
82 if (cachedResult) {
83 logger.debug(`Returning cached result for script ${this.scriptPath}: ${cachedResult}`);
84 return { ...JSON.parse(cachedResult as string), cached: true };
85 }
86 } else if (fileHashes.length === 0 && isCacheEnabled()) {
87 logger.warn(
88 `Could not hash any files for command ${this.scriptPath}, caching will not be used`,
89 );
90 }
91
92 return new Promise<ProviderResponse>((resolve, reject) => {
93 const command = scriptParts.shift();
94 invariant(command, 'No command found in script path');
95 // Remove properties not useful in shell scripts and non-serializable objects
96 // These can contain circular references (e.g., Timeout objects) that break JSON serialization
97 delete context?.getCache;
98 delete context?.logger;
99 delete context?.filters; // NunjucksFilterMap contains functions
100 delete context?.originalProvider; // ApiProvider object with methods
101 const scriptArgs = scriptParts.concat([
102 prompt,
103 safeJsonStringify(this.options || {}) as string,
104 safeJsonStringify(context || {}) as string,
105 ]);
106 const options = this.options?.config.basePath ? { cwd: this.options.config.basePath } : {};
107
108 const child = execFile(command, scriptArgs, options, async (error, stdout, stderr) => {
109 if (error) {
110 logger.debug(`Error running script ${this.scriptPath}: ${error.message}`);
111 reject(error);
112 return;
113 }
114 const standardOutput = stripText(Buffer.from(stdout).toString('utf8').trim());
115 const errorOutput = stripText(Buffer.from(stderr).toString('utf8').trim());
116 if (errorOutput) {
117 logger.debug(`Error output from script ${this.scriptPath}: ${errorOutput}`);
118 if (!standardOutput) {
119 reject(new Error(errorOutput));
120 return;
121 }
122 }
123 logger.debug(`Output from script ${this.scriptPath}: ${standardOutput}`);
124 const result = { output: standardOutput };

Callers

nothing calls this directly

Calls 12

isCacheEnabledFunction · 0.90
getCacheFunction · 0.90
safeJsonStringifyFunction · 0.90
parseScriptPartsFunction · 0.85
getFileHashesFunction · 0.85
invariantFunction · 0.85
resolveFunction · 0.85
parseMethod · 0.80
stripTextFunction · 0.70
toStringMethod · 0.65
getMethod · 0.45
setMethod · 0.45

Tested by

no test coverage detected