using AIStudio.Chat; using AIStudio.Settings; namespace AIStudio.Agents; public sealed class AgentTextContentCleaner(ILogger logger, SettingsManager settingsManager, ThreadSafeRandom rng) : AgentBase(logger, settingsManager, rng) { private static readonly ContentBlock EMPTY_BLOCK = new() { Content = null, ContentType = ContentType.NONE, Role = ChatRole.AGENT, Time = DateTimeOffset.UtcNow, }; private readonly List context = new(); private readonly List answers = new(); #region Overrides of AgentBase public override AIStudio.Settings.Provider? ProviderSettings { get; set; } protected override Type Type => Type.SYSTEM; public override string Id => "Text Content Cleaner"; protected override string JobDescription => """ You receive a Markdown document as input. Your goal is to identify the main content of the document and return it including Markdown formatting. Remove areas that do not belong to the main part of the document. For a blog article, return only the text of the article with its formatting. For a scientific paper, only the contents of the paper. Delete elements of navigation, advertisements, HTML artifacts, cookie banners, etc. If the content contains images, these images remain. The same applies to links. Ensure that links and images are present as valid Markdown: - Syntax of links: [link text](URL) - Syntax of images: ![alt text](URL) If you find relative links or images with relative paths, correct them to absolute paths. For this purpose, here is the source URL: """; protected override string SystemPrompt(string additionalData) => $"{this.JobDescription} `{additionalData}`."; /// public override async Task ProcessContext(ChatThread chatThread, IDictionary additionalData) { // We process the last block of the chat thread. Then, we add the result // to the chat thread as the last block: var answer = await this.ProcessInput(chatThread.Blocks[^1], additionalData); chatThread.Blocks.Add(answer); this.context.Clear(); this.context.AddRange(chatThread.Blocks); return chatThread; } // public override async Task ProcessInput(ContentBlock input, IDictionary additionalData) { if (input.Content is not ContentText text) return EMPTY_BLOCK; if(text.InitialRemoteWait || text.IsStreaming) return EMPTY_BLOCK; if(string.IsNullOrWhiteSpace(text.Text)) return EMPTY_BLOCK; if(!additionalData.TryGetValue("sourceURL", out var sourceURL) || string.IsNullOrWhiteSpace(sourceURL)) return EMPTY_BLOCK; var thread = this.CreateChatThread(this.SystemPrompt(sourceURL)); var time = this.AddUserRequest(thread, text.Text); await this.AddAIResponseAsync(thread, time); var answer = thread.Blocks[^1]; this.answers.Add(answer); return answer; } // public override Task MadeDecision(ContentBlock input) => Task.FromResult(true); // public override IReadOnlyCollection GetContext() => this.context; // public override IReadOnlyCollection GetAnswers() => this.answers; #endregion }