diff --git a/src/TimesheetGPT.Core/Interfaces/IAiService.cs b/src/TimesheetGPT.Core/Interfaces/IAiService.cs index 5d66559..3f83919 100644 --- a/src/TimesheetGPT.Core/Interfaces/IAiService.cs +++ b/src/TimesheetGPT.Core/Interfaces/IAiService.cs @@ -2,5 +2,5 @@ namespace TimesheetGPT.Core.Interfaces; public interface IAiService { - public Task GetSummary(string text, string extraPrompts); + public Task GetSummary(string text, string extraPrompts, string additionalNotes); } diff --git a/src/TimesheetGPT.Core/Prompts.cs b/src/TimesheetGPT.Core/Prompts.cs index 4a46a34..f952dcb 100644 --- a/src/TimesheetGPT.Core/Prompts.cs +++ b/src/TimesheetGPT.Core/Prompts.cs @@ -24,9 +24,12 @@ Use the emails to determine tasks complete. Only output a Markdown unordered list. If there is no meetings or emails, respond with a joke about the user not doing any work on this day :) + {{${{{PromptVariables.Input}}}}} + {{${{{PromptVariables.ExtraPrompts}}}}} + + {{${{{PromptVariables.AdditionalNotes}}}}} - {{${{{PromptVariables.Input}}}}} """; } @@ -35,5 +38,6 @@ Only output a Markdown unordered list. public static class PromptVariables { public const string ExtraPrompts = "extraPrompts"; + public const string AdditionalNotes = "additionalNotes"; public const string Input = "inputContent"; } \ No newline at end of file diff --git a/src/TimesheetGPT.Core/Services/LangChainAiService.cs b/src/TimesheetGPT.Core/Services/LangChainAiService.cs index 62cdd1e..96a308c 100644 --- a/src/TimesheetGPT.Core/Services/LangChainAiService.cs +++ b/src/TimesheetGPT.Core/Services/LangChainAiService.cs @@ -4,7 +4,7 @@ namespace TimesheetGPT.Core.Services; public class LangChainAiService : IAiService { - public async Task GetSummary(string text, string extraPrompts) + public async Task GetSummary(string text, string extraPrompts, string additionalNotes) { throw new NotImplementedException(); } diff --git a/src/TimesheetGPT.Core/Services/SemKerAiService.cs b/src/TimesheetGPT.Core/Services/SemKerAiService.cs index 7c5fe5d..1f96e5b 100644 --- a/src/TimesheetGPT.Core/Services/SemKerAiService.cs +++ b/src/TimesheetGPT.Core/Services/SemKerAiService.cs @@ -15,7 +15,7 @@ public SemKerAiService(IConfiguration configuration) _apiKey = configuration["OpenAI:ApiKey"] ?? ""; } - public async Task GetSummary(string text, string extraPrompts) + public async Task GetSummary(string text, string extraPrompts, string additionalNotes = "") { Console.WriteLine(text); var builder = new KernelBuilder(); @@ -32,11 +32,13 @@ public async Task GetSummary(string text, string extraPrompts) var kernel = builder.Build(); + // Note: Token limit hurts things like additional notes. If you don't have enough, the prompt will suck var summarizeFunction = kernel.CreateSemanticFunction(Prompts.SummarizeEmailsAndCalendar, maxTokens: 400, temperature: 0, topP: 0.5); var context = kernel.CreateNewContext(); context.Variables.TryAdd(PromptVariables.Input, text); + context.Variables.TryAdd(PromptVariables.AdditionalNotes, additionalNotes); context.Variables.TryAdd(PromptVariables.ExtraPrompts, extraPrompts); var summary = await summarizeFunction.InvokeAsync(context); diff --git a/src/TimesheetGPT.Core/Services/TimesheetService.cs b/src/TimesheetGPT.Core/Services/TimesheetService.cs index eb1987e..6fd5166 100644 --- a/src/TimesheetGPT.Core/Services/TimesheetService.cs +++ b/src/TimesheetGPT.Core/Services/TimesheetService.cs @@ -1,3 +1,4 @@ +using System.Collections; using Microsoft.Graph; using TimesheetGPT.Core.Interfaces; using TimesheetGPT.Core.Models; @@ -13,14 +14,14 @@ public TimesheetService(IAiService aiService) _aiService = aiService; } - public async Task GenerateSummary(DateTime date, GraphServiceClient client, string extraPrompts = "") + public async Task GenerateSummary(DateTime date, GraphServiceClient client, string extraPrompts = "", string additionalNotes = "") { IGraphService graphService = new GraphService(client); var emailSubjects = await graphService.GetEmailSubjects(date); var meetings = await graphService.GetMeetings(date); - var summary = await _aiService.GetSummary(StringifyData(emailSubjects, meetings), extraPrompts); + var summary = await _aiService.GetSummary(StringifyData(emailSubjects, meetings), extraPrompts, additionalNotes); return new SummaryWithRaw { @@ -31,7 +32,7 @@ public async Task GenerateSummary(DateTime date, GraphServiceCli }; } - private string StringifyData(IList emails, IList meetings) + private string StringifyData(List emails, List meetings) { var result = "Sent emails (subject) \n"; foreach (var email in emails) @@ -43,6 +44,7 @@ private string StringifyData(IList emails, IList meetings) { result += $"{meeting.Name} - {meeting.Length} \n"; } + return result; } } diff --git a/src/TimesheetGPT.WebUI/Pages/Index.razor b/src/TimesheetGPT.WebUI/Pages/Index.razor index ad7c45c..2f4788b 100644 --- a/src/TimesheetGPT.WebUI/Pages/Index.razor +++ b/src/TimesheetGPT.WebUI/Pages/Index.razor @@ -41,12 +41,17 @@ + @if (additionalNotesError) + { + Additional notes too long. You have @_additionalNotes.Length characters. We only accept 400 max. + } + + Lines="7"/> @@ -133,6 +138,8 @@ string _additionalNotes = string.Empty; string _generateButtonText = "Generate"; + bool additionalNotesError; + protected override async Task OnInitializedAsync() { try @@ -151,8 +158,14 @@ _loading = true; try { + additionalNotesError = false; + additionalNotesError = CheckAdditionalNotesIsntTooBig(); + if (additionalNotesError) + { + return; + } var dateTime = _date ?? DateTime.Today; - var summary = await TimesheetService.GenerateSummary(dateTime, GraphServiceClient, _extraPrompt ?? ""); + var summary = await TimesheetService.GenerateSummary(dateTime, GraphServiceClient, _extraPrompt ?? "", _additionalNotes); _emailSubjects = summary.Emails; _meetings = summary.Meetings; @@ -170,4 +183,9 @@ } } + + private bool CheckAdditionalNotesIsntTooBig() + { + return _additionalNotes.Length > 400; + } } \ No newline at end of file