"use strict";
// import { spawn } from 'child_process';
// import path from 'path';
// // Adjust paths as per your project structure if types or util are in different locations.
// import type { AssertionParams, GradingResult } from '../types';
// import invariant from '../util/invariant';
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.handleRoleAdherence = void 0;
// /**
//  * Represents the result of a role adherence grading.
//  */
// export interface RoleAdherenceResult {
//   pass: boolean;
//   score: number;
//   reason: string;
// }
// /**
//  * Calls the Python script `role_adherence_eval.py` to evaluate
//  * role adherence for a given conversational context and chatbot role.
//  *
//  * @param llmOutput The current LLM's output for the turn being evaluated.
//  * @param context The full context object from Promptfoo, including _conversation history, vars, and chatbot_role.
//  * @returns A promise that resolves to a RoleAdherenceResult.
//  */
// async function executeAndGradeRoleAdherence(
//   llmOutput: string,
//   context: Record<string, any>,
// ): Promise<RoleAdherenceResult> {
//   console.log('--- executeAndGradeRoleAdherence START ---');
//   console.log(
//     '  LLM Output (current turn, first 100 chars):',
//     llmOutput.substring(0, 100) + (llmOutput.length > 100 ? '...' : ''),
//   );
//   console.log('  Context received by TypeScript:', JSON.stringify(context, null, 2));
//   // Ensure this path points correctly to your Python script
//   const pythonScriptPath = path.join(__dirname, 'python', 'role_adherence_eval.py');
//   console.log('  Constructed Python script path:', pythonScriptPath);
//   const llmOutputString = llmOutput;
//   const contextJsonString = JSON.stringify(context);
//   const jsonPromise = new Promise<string>((resolve, reject) => {
//     const pythonProcessArguments = [pythonScriptPath, llmOutputString, contextJsonString];
//     const py = spawn('python', pythonProcessArguments, {
//       env: process.env, // IMPORTANT: Pass environment variables (e.g., OPENAI_API_KEY) to the child process
//       stdio: ['pipe', 'pipe', 'pipe'], // Capture stdin, stdout, and stderr
//     });
//     let stdoutData = '';
//     let stderrData = '';
//     py.stdout.on('data', (chunk) => {
//       const chunkStr = chunk.toString();
//       stdoutData += chunkStr;
//     });
//     py.stderr.on('data', (chunk) => {
//       const chunkStr = chunk.toString();
//       stderrData += chunkStr;
//       console.error('Python stderr chunk:', chunkStr); // Log stderr as it comes
//     });
//     py.on('close', (code) => {
//       console.log('Python process closed with code:', code);
//       if (code === 0) {
//         if (stdoutData.trim()) {
//           console.log('Python script succeeded. Raw stdout:', stdoutData.trim());
//           resolve(stdoutData.trim());
//         } else {
//           reject(new Error('Python script succeeded but produced no JSON output on stdout.'));
//         }
//       } else {
//         const errorMessage = `role_adherence_eval.py exited with code ${code}. Stderr: ${stderrData.trim() || 'No stderr output.'}`;
//         console.error('Python script failed:', errorMessage);
//         reject(new Error(errorMessage));
//       }
//     });
//     py.on('error', (err) => {
//       console.error('Error spawning Python process:', err);
//       reject(err);
//     });
//   });
//   try {
//     console.log('  Awaiting JSON result from Python script...');
//     const jsonResultString = await jsonPromise;
//     const result = JSON.parse(jsonResultString) as RoleAdherenceResult;
//     return result;
//   } catch (error: any) {
//     return {
//       pass: false,
//       score: 0,
//       reason: `Failed to execute role adherence evaluation: ${error.message || 'Unknown error during execution.'}`,
//     };
//   }
// }
// export const handleRoleAdherence = async ({
//   assertion,
//   renderedValue,
//   outputString, // This is the LLM's output for the *current* turn
//   test, // Contains the full test object including _conversation and vars
// }: AssertionParams): Promise<GradingResult> => {
//   invariant(
//     typeof outputString === 'string',
//     'LLM response (outputString) must be a string for role adherence assertion.',
//   );
//   const testVars = test.vars || {};
//   // Added explicit type for assertions array for better type safety
//   const assertions: Array<{ type: string; threshold?: number }> = test.assert || [];
//   // Find the specific role-adherence assertion to get its parameters
//   const roleAdherenceAssert = assertions.find((a) => a.type === 'role-adherence');
//   // Use the threshold from the specific assertion, or fallback to default 0.5
//   const threshold =
//     typeof roleAdherenceAssert?.threshold === 'number' ? roleAdherenceAssert.threshold : 0.5;
//   // Promptfoo's `_conversation` variable directly provides the history.
//   // We pass the entire `test` object as context to the Python script
//   // so it can access `_conversation` and `vars`.
//   const contextForPython = {
//     ...test, // Pass the entire test object, including _conversation
//     defaultTest: {
//       // Also pass defaultTest asserts, if any, for threshold fallback logic in Python
//       assert: (test as any).defaultTest?.assert || [],
//     },
//   };
//   const gradingResult = await executeAndGradeRoleAdherence(
//     outputString, // The current LLM output
//     contextForPython as Record<string, any>, // The full context including _conversation history and chatbot_role
//   );
//   return gradingResult;
// };
const child_process_1 = require("child_process");
const path_1 = __importDefault(require("path"));
const invariant_1 = __importDefault(require("../util/invariant"));
const matchers_1 = require("../matchers");
const defaults_1 = require("../providers/defaults");
async function executeAndGradeRoleAdherence(llmOutput, textProvider, providerType, context) {
    const pythonScriptPath = path_1.default.join(__dirname, "python", "role_adherence_eval.py");
    const contextJson = JSON.stringify(context);
    const jsonPromise = new Promise((resolve, reject) => {
        const py = (0, child_process_1.spawn)("python", [pythonScriptPath, llmOutput, JSON.stringify(textProvider), providerType], {
            env: process.env,
            stdio: ["pipe", "pipe", "pipe"],
        });
        let stdoutData = "", stderrData = "";
        py.stdin.write(contextJson);
        py.stdin.end();
        py.stdout.on("data", (c) => (stdoutData += c.toString()));
        py.stderr.on("data", (c) => {
            stderrData += c.toString();
            // console.error("[role_adherence.py stderr]:", c.toString());
        });
        py.on("close", (code) => {
            // console.error("[role_adherence.py stderr(final)]:", stderrData.trim());
            if (code === 0) {
                resolve(stdoutData.trim());
            }
            else {
                reject(new Error(`Python exited with code ${code}. stdout="${stdoutData}", stderr="${stderrData}"`));
            }
        });
        py.on("error", (err) => reject(new Error(`Failed to start Python: ${err.message}`)));
    });
    try {
        return JSON.parse(await jsonPromise);
    }
    catch (e) {
        console.error("Invalid JSON from Python:", e);
        return { pass: false, score: 0, reason: "evaluation failed" };
    }
}
const handleRoleAdherence = async ({ assertion, outputString, test, workspaceId, }) => {
    (0, invariant_1.default)(typeof outputString === "string", "output must be string");
    const textProvider = await (0, matchers_1.getAndCheckProvider)("text", test.options?.provider, (await (0, defaults_1.getDefaultProviders)(undefined, workspaceId)).gradingProvider, "role-adherence");
    const providerType = textProvider.constructor.name;
    console.log("RoleAdherence provider ID:", textProvider?.id);
    console.log("RoleAdherence Construction name:", providerType);
    const contextForPython = {
        ...test,
        defaultTest: {
            assert: test.defaultTest?.assert || [],
        },
    };
    const grading = await executeAndGradeRoleAdherence(outputString, textProvider, providerType, contextForPython);
    return {
        assertion,
        pass: grading.pass,
        score: grading.score,
        reason: grading.reason,
    };
};
exports.handleRoleAdherence = handleRoleAdherence;
//# sourceMappingURL=roleAdherenceAssertion.js.map