private static TestOutcome ExpectGptOutcome()

in src/extensions/testframework/YamlTestCaseRunner.cs [819:908]


        private static TestOutcome ExpectGptOutcome(string output, string expectGpt, string workingDirectory, out string gptStdOut, out string gptStdErr, out string gptMerged)
        {
            Logger.Log($"ExpectGptOutcome: Checking for {expectGpt} in '{output}'");

            var outcome = TestOutcome.None;

            var sbOut = new StringBuilder();
            var sbErr = new StringBuilder();
            var sbMerged = new StringBuilder();

            var question = new StringBuilder();
            question.AppendLine($"Here's the console output:\n\n{output}\n");
            question.AppendLine($"Here's the expectation:\n\n{expectGpt}\n");
            question.AppendLine("You **must always** answer \"PASS\" if the expectation is met.");
            question.AppendLine("You **must always** answer \"FAIL\" if the expectation is not met.");
            question.AppendLine("You **must only** answer \"PASS\" with no additional text if the expectation is met.");
            question.AppendLine("If you answer \"FAIL\", you **must** provide additional text to explain why the expectation was not met (without using the word \"PASS\" as we will interpret that as a \"PASS\").");
            var questionTempFile = WriteTextToTempFile(question.ToString())!;

            try
            {
                var startProcess = FindCacheCli("ai");
                var startArgs = $"chat --quiet true --index-name @none --question @{questionTempFile}";
                var startInfo = new ProcessStartInfo(startProcess, startArgs)
                {
                    UseShellExecute = false,
                    RedirectStandardInput = true,
                    RedirectStandardError = true,
                    RedirectStandardOutput = true,
                    WorkingDirectory = workingDirectory
                };

                Logger.Log($"ExpectGptOutcome: Process.Start('{startProcess} {startArgs}')");
                var process = Process.Start(startInfo);
                if (process == null) throw new Exception("Process.Start() returned null!");
                process.StandardInput.Close();

                var outDoneSignal = new ManualResetEvent(false);
                var errDoneSignal = new ManualResetEvent(false);
                process.OutputDataReceived += (sender, e) => AppendLineOrSignal(e.Data, sbOut, sbMerged, outDoneSignal);
                process.ErrorDataReceived += (sender, e) => AppendLineOrSignal(e.Data, sbErr, sbMerged, errDoneSignal);
                process.BeginOutputReadLine();
                process.BeginErrorReadLine();

                var exitedNotKilled = WaitForExit(process, 60000);
                if (exitedNotKilled)
                {
                    outDoneSignal.WaitOne();
                    errDoneSignal.WaitOne();
                }

                var passed = exitedNotKilled && process.ExitCode == 0;
                outcome = passed ? TestOutcome.Passed : TestOutcome.Failed;

                var timedoutOrKilled = !exitedNotKilled;
                if (timedoutOrKilled)
                {
                    var message = "ExpectGptOutcome: WARNING: Timedout or killed!";
                    sbErr.AppendLine(message);
                    sbMerged.AppendLine(message);
                    Logger.LogWarning(message);
                }
            }
            catch (Exception ex)
            {
                outcome = TestOutcome.Failed;

                var exception = $"ExpectGptOutcome: EXCEPTION: {ex.Message}";
                sbErr.AppendLine(exception);
                sbMerged.AppendLine(exception);
                Logger.Log(exception);
            }

            File.Delete(questionTempFile);
            gptStdOut = sbOut.ToString();
            gptStdErr = sbErr.ToString();
            gptMerged = sbMerged.ToString();

            if (outcome == TestOutcome.Passed)
            {
                Logger.Log($"ExpectGptOutcome: Checking for 'PASS' in '{gptMerged}'");

                var passed = gptMerged.Contains("PASS") || gptMerged.Contains("TRUE") || gptMerged.Contains("YES");
                outcome = passed ? TestOutcome.Passed : TestOutcome.Failed;

                Logger.Log($"ExpectGptOutcome: {outcome}");
            }

            return outcome;
        }