< Summary

Information
Class: OpenAiIntegration.PredictionPromptComposer
Assembly: OpenAiIntegration
File(s): /home/runner/work/KicktippAi/KicktippAi/src/OpenAiIntegration/PredictionPromptComposer.cs
Line coverage
100%
Covered lines: 41
Uncovered lines: 0
Coverable lines: 41
Total lines: 88
Line coverage: 100%
Branch coverage
100%
Covered branches: 12
Total branches: 12
Branch coverage: 100%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
BuildSystemPrompt(...)100%44100%
BuildContextDocumentsSection(...)100%66100%
CreateMatchJson(...)100%11100%
CreateBonusQuestionJson(...)100%22100%

File(s)

/home/runner/work/KicktippAi/KicktippAi/src/OpenAiIntegration/PredictionPromptComposer.cs

#LineLine coverage
 1using System.Text;
 2using System.Text.Json;
 3using EHonda.KicktippAi.Core;
 4
 5namespace OpenAiIntegration;
 6
 7/// <summary>
 8/// Shared helpers for building prompt inputs used by prediction and reconstruction flows.
 9/// </summary>
 10public static class PredictionPromptComposer
 11{
 12    private const string ContextDocumentsPlaceholder = "{{context_documents}}";
 13
 14    public static string BuildSystemPrompt(string template, IEnumerable<DocumentContext> contextDocuments)
 15    {
 116        var contextList = contextDocuments.ToList();
 117        if (template.Contains(ContextDocumentsPlaceholder, StringComparison.Ordinal))
 18        {
 119            return template.Replace(
 120                ContextDocumentsPlaceholder,
 121                BuildContextDocumentsSection(contextList, includeLeadingNewLine: false),
 122                StringComparison.Ordinal);
 23        }
 24
 125        if (contextList.Count == 0)
 26        {
 127            return template;
 28        }
 29
 130        return template + BuildContextDocumentsSection(contextList, includeLeadingNewLine: true);
 31    }
 32
 33    private static string BuildContextDocumentsSection(
 34        IReadOnlyList<DocumentContext> contextDocuments,
 35        bool includeLeadingNewLine)
 36    {
 137        if (contextDocuments.Count == 0)
 38        {
 139            return string.Empty;
 40        }
 41
 142        var contextSection = new StringBuilder();
 143        if (includeLeadingNewLine)
 44        {
 145            contextSection.Append('\n');
 46        }
 47
 148        foreach (var doc in contextDocuments)
 49        {
 150            contextSection.Append("---\n");
 151            contextSection.Append(doc.Name);
 152            contextSection.Append("\n\n");
 153            contextSection.Append(doc.Content);
 154            contextSection.Append('\n');
 55        }
 56
 157        contextSection.Append("---");
 158        return contextSection.ToString();
 59    }
 60
 61    public static string CreateMatchJson(Match match)
 62    {
 163        return JsonSerializer.Serialize(new
 164        {
 165            homeTeam = match.HomeTeam,
 166            awayTeam = match.AwayTeam,
 167            startsAt = match.StartsAt.ToString()
 168        }, new JsonSerializerOptions
 169        {
 170            Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping
 171        });
 72    }
 73
 74    public static string CreateBonusQuestionJson(BonusQuestion question)
 75    {
 176        var questionData = new
 177        {
 178            text = question.Text,
 179            options = question.Options.Select(o => new { id = o.Id, text = o.Text }).ToArray(),
 180            maxSelections = question.MaxSelections
 181        };
 82
 183        return JsonSerializer.Serialize(questionData, new JsonSerializerOptions
 184        {
 185            Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping
 186        });
 87    }
 88}