Skip to content

Added smart document summarization sample #29

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file added AI Demos/Summarizer/.vs/Summarizer/v17/.futdcache.v2
Binary file not shown.
Binary file added AI Demos/Summarizer/.vs/Summarizer/v17/.suo
Binary file not shown.
142 changes: 142 additions & 0 deletions AI Demos/Summarizer/.vs/Summarizer/v17/DocumentLayout.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
{
"Version": 1,
"WorkspaceRootPath": "D:\\ForGitHub\\maui-pdf-viewer-examples\\AI Demos\\Summarizer\\",
"Documents": [
{
"AbsoluteMoniker": "D:0:0:{CD42BBF8-9F64-4E6F-BB42-F00ED07A35C1}|Summarizer\\Summarizer.csproj|d:\\forgithub\\maui-pdf-viewer-examples\\ai demos\\summarizer\\summarizer\\mainpage.xaml.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{CD42BBF8-9F64-4E6F-BB42-F00ED07A35C1}|Summarizer\\Summarizer.csproj|solutionrelative:summarizer\\mainpage.xaml.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{CD42BBF8-9F64-4E6F-BB42-F00ED07A35C1}|Summarizer\\Summarizer.csproj|d:\\forgithub\\maui-pdf-viewer-examples\\ai demos\\summarizer\\summarizer\\mauiprogram.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{CD42BBF8-9F64-4E6F-BB42-F00ED07A35C1}|Summarizer\\Summarizer.csproj|solutionrelative:summarizer\\mauiprogram.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{CD42BBF8-9F64-4E6F-BB42-F00ED07A35C1}|Summarizer\\Summarizer.csproj|d:\\forgithub\\maui-pdf-viewer-examples\\ai demos\\summarizer\\summarizer\\mainpage.xaml||{F11ACC28-31D1-4C80-A34B-F4E09D3D753C}",
"RelativeMoniker": "D:0:0:{CD42BBF8-9F64-4E6F-BB42-F00ED07A35C1}|Summarizer\\Summarizer.csproj|solutionrelative:summarizer\\mainpage.xaml||{F11ACC28-31D1-4C80-A34B-F4E09D3D753C}"
},
{
"AbsoluteMoniker": "D:0:0:{CD42BBF8-9F64-4E6F-BB42-F00ED07A35C1}|Summarizer\\Summarizer.csproj|d:\\forgithub\\maui-pdf-viewer-examples\\ai demos\\summarizer\\summarizer\\viewmodel\\pdfviewerviewmodel.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{CD42BBF8-9F64-4E6F-BB42-F00ED07A35C1}|Summarizer\\Summarizer.csproj|solutionrelative:summarizer\\viewmodel\\pdfviewerviewmodel.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{CD42BBF8-9F64-4E6F-BB42-F00ED07A35C1}|Summarizer\\Summarizer.csproj|d:\\forgithub\\maui-pdf-viewer-examples\\ai demos\\summarizer\\summarizer\\assistservices.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{CD42BBF8-9F64-4E6F-BB42-F00ED07A35C1}|Summarizer\\Summarizer.csproj|solutionrelative:summarizer\\assistservices.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{CD42BBF8-9F64-4E6F-BB42-F00ED07A35C1}|Summarizer\\Summarizer.csproj|d:\\forgithub\\maui-pdf-viewer-examples\\ai demos\\summarizer\\summarizer\\summarizer.csproj||{FA3CD31E-987B-443A-9B81-186104E8DAC1}|",
"RelativeMoniker": "D:0:0:{CD42BBF8-9F64-4E6F-BB42-F00ED07A35C1}|Summarizer\\Summarizer.csproj|solutionrelative:summarizer\\summarizer.csproj||{FA3CD31E-987B-443A-9B81-186104E8DAC1}|"
}
],
"DocumentGroupContainers": [
{
"Orientation": 0,
"VerticalTabListWidth": 256,
"DocumentGroups": [
{
"DockedWidth": 200,
"SelectedChildIndex": 6,
"Children": [
{
"$type": "Bookmark",
"Name": "ST:0:0:{34e76e81-ee4a-11d0-ae2e-00a0c90fffc3}"
},
{
"$type": "Bookmark",
"Name": "ST:0:0:{0ad07096-bba9-4900-a651-0598d26f6d24}"
},
{
"$type": "Bookmark",
"Name": "ST:0:0:{eefa5220-e298-11d0-8f78-00a0c9110057}"
},
{
"$type": "Bookmark",
"Name": "ST:1:0:{d212f56b-c48a-434c-a121-1c5d80b59b9f}"
},
{
"$type": "Bookmark",
"Name": "ST:0:0:{d78612c7-9962-4b83-95d9-268046dad23a}"
},
{
"$type": "Document",
"DocumentIndex": 1,
"Title": "MauiProgram.cs",
"DocumentMoniker": "D:\\ForGitHub\\maui-pdf-viewer-examples\\AI Demos\\Summarizer\\Summarizer\\MauiProgram.cs",
"RelativeDocumentMoniker": "Summarizer\\MauiProgram.cs",
"ToolTip": "D:\\ForGitHub\\maui-pdf-viewer-examples\\AI Demos\\Summarizer\\Summarizer\\MauiProgram.cs",
"RelativeToolTip": "Summarizer\\MauiProgram.cs",
"ViewState": "AQIAAAAAAAAAAAAAAAAAABYAAAAwAAAA",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2024-09-18T12:16:48.383Z",
"EditorCaption": ""
},
{
"$type": "Document",
"DocumentIndex": 0,
"Title": "MainPage.xaml.cs",
"DocumentMoniker": "D:\\ForGitHub\\maui-pdf-viewer-examples\\AI Demos\\Summarizer\\Summarizer\\MainPage.xaml.cs",
"RelativeDocumentMoniker": "Summarizer\\MainPage.xaml.cs",
"ToolTip": "D:\\ForGitHub\\maui-pdf-viewer-examples\\AI Demos\\Summarizer\\Summarizer\\MainPage.xaml.cs",
"RelativeToolTip": "Summarizer\\MainPage.xaml.cs",
"ViewState": "AQIAABIAAAAAAAAAAAAYwDMAAAAAAAAA",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2024-09-18T12:16:05.93Z",
"EditorCaption": ""
},
{
"$type": "Document",
"DocumentIndex": 2,
"Title": "MainPage.xaml",
"DocumentMoniker": "D:\\ForGitHub\\maui-pdf-viewer-examples\\AI Demos\\Summarizer\\Summarizer\\MainPage.xaml",
"RelativeDocumentMoniker": "Summarizer\\MainPage.xaml",
"ToolTip": "D:\\ForGitHub\\maui-pdf-viewer-examples\\AI Demos\\Summarizer\\Summarizer\\MainPage.xaml",
"RelativeToolTip": "Summarizer\\MainPage.xaml",
"ViewState": "AQIAAAAAAAAAAAAAAAAAAIwAAAAAAAAA",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.003549|",
"WhenOpened": "2024-09-18T12:15:30.33Z",
"EditorCaption": ""
},
{
"$type": "Document",
"DocumentIndex": 3,
"Title": "PdfViewerViewModel.cs",
"DocumentMoniker": "D:\\ForGitHub\\maui-pdf-viewer-examples\\AI Demos\\Summarizer\\Summarizer\\ViewModel\\PdfViewerViewModel.cs",
"RelativeDocumentMoniker": "Summarizer\\ViewModel\\PdfViewerViewModel.cs",
"ToolTip": "D:\\ForGitHub\\maui-pdf-viewer-examples\\AI Demos\\Summarizer\\Summarizer\\ViewModel\\PdfViewerViewModel.cs",
"RelativeToolTip": "Summarizer\\ViewModel\\PdfViewerViewModel.cs",
"ViewState": "AQIAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2024-09-18T12:15:20.014Z",
"EditorCaption": ""
},
{
"$type": "Document",
"DocumentIndex": 4,
"Title": "AssistServices.cs",
"DocumentMoniker": "D:\\ForGitHub\\maui-pdf-viewer-examples\\AI Demos\\Summarizer\\Summarizer\\AssistServices.cs",
"RelativeDocumentMoniker": "Summarizer\\AssistServices.cs",
"ToolTip": "D:\\ForGitHub\\maui-pdf-viewer-examples\\AI Demos\\Summarizer\\Summarizer\\AssistServices.cs",
"RelativeToolTip": "Summarizer\\AssistServices.cs",
"ViewState": "AQIAABMAAAAAAAAAAAAQwAAAAAAAAAAA",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2024-09-18T12:15:07.799Z",
"EditorCaption": ""
},
{
"$type": "Document",
"DocumentIndex": 5,
"Title": "Summarizer",
"DocumentMoniker": "D:\\ForGitHub\\maui-pdf-viewer-examples\\AI Demos\\Summarizer\\Summarizer\\Summarizer.csproj",
"RelativeDocumentMoniker": "Summarizer\\Summarizer.csproj",
"ToolTip": "D:\\ForGitHub\\maui-pdf-viewer-examples\\AI Demos\\Summarizer\\Summarizer\\Summarizer.csproj",
"RelativeToolTip": "Summarizer\\Summarizer.csproj",
"ViewState": "AQIAACQAAAAAAAAAAAAAAE8AAAAEAAAA",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000758|",
"WhenOpened": "2024-09-18T12:14:31.732Z",
"EditorCaption": ""
}
]
}
]
}
]
}
27 changes: 27 additions & 0 deletions AI Demos/Summarizer/Summarizer.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.10.35122.118
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Summarizer", "Summarizer\Summarizer.csproj", "{CD42BBF8-9F64-4E6F-BB42-F00ED07A35C1}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{CD42BBF8-9F64-4E6F-BB42-F00ED07A35C1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{CD42BBF8-9F64-4E6F-BB42-F00ED07A35C1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CD42BBF8-9F64-4E6F-BB42-F00ED07A35C1}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
{CD42BBF8-9F64-4E6F-BB42-F00ED07A35C1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CD42BBF8-9F64-4E6F-BB42-F00ED07A35C1}.Release|Any CPU.Build.0 = Release|Any CPU
{CD42BBF8-9F64-4E6F-BB42-F00ED07A35C1}.Release|Any CPU.Deploy.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {A2477ADB-5676-475F-A831-8327EC2C8B92}
EndGlobalSection
EndGlobal
14 changes: 14 additions & 0 deletions AI Demos/Summarizer/Summarizer/App.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?xml version = "1.0" encoding = "UTF-8" ?>
<Application xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:Summarizer"
x:Class="Summarizer.App">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Resources/Styles/Colors.xaml" />
<ResourceDictionary Source="Resources/Styles/Styles.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
12 changes: 12 additions & 0 deletions AI Demos/Summarizer/Summarizer/App.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
namespace Summarizer
{
public partial class App : Application
{
public App()
{
InitializeComponent();

MainPage = new AppShell();
}
}
}
15 changes: 15 additions & 0 deletions AI Demos/Summarizer/Summarizer/AppShell.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Shell
x:Class="Summarizer.AppShell"
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:Summarizer"
Shell.FlyoutBehavior="Disabled"
Title="Summarizer">

<ShellContent
Title="Home"
ContentTemplate="{DataTemplate local:MainPage}"
Route="MainPage" />

</Shell>
10 changes: 10 additions & 0 deletions AI Demos/Summarizer/Summarizer/AppShell.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace Summarizer
{
public partial class AppShell : Shell
{
public AppShell()
{
InitializeComponent();
}
}
}
Binary file not shown.
162 changes: 162 additions & 0 deletions AI Demos/Summarizer/Summarizer/AssistServices.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
using Syncfusion.Maui.AIAssistView;
using System.Collections.ObjectModel;
using Azure.AI.OpenAI;
using Azure;

namespace Summarizer
{
/// <summary>
/// Represents a class providing AI assistance services for text extraction,
/// prompt generation, and chat completion functionalities using OpenAI's GPT model.
/// </summary>
internal class AssistServices
{

/// <summary>
/// Gets or sets the extracted text from a document.
/// </summary>
internal string? ExtractedText { get; set; }

/// <summary>
/// The EndPoint
/// </summary>
private const string endpoint = "https://blazorpdf-ai.openai.azure.com/";

/// <summary>
/// The Deployment name
/// </summary>
internal string deploymentName = "gpt-4-0";

/// <summary>
/// The API key
/// </summary>
private const string key = "7f164d6ba53e4df784ecddabbf73d5a8";

/// <summary>
/// The AzureOpenAI client
/// </summary>
internal OpenAIClient? client;

/// <summary>
/// The ChatCompletion option
/// </summary>
private ChatCompletionsOptions? chatCompletions;

internal AssistServices()
{
chatCompletions = new ChatCompletionsOptions
{
DeploymentName = deploymentName,
Temperature = (float)1.2f,
NucleusSamplingFactor = (float)0.9,
FrequencyPenalty = 0.8f,
PresencePenalty = 0.8f
};
client = new OpenAIClient(new Uri(endpoint), new AzureKeyCredential(key));
}

/// <summary>
/// Generates a static prompt message.
/// </summary>
/// <param name="prompt">The input prompt string.</param>
/// <returns>A predefined message requesting OpenAI connection for real-time queries.</returns>
internal async Task<string> GetPrompt(string prompt)
{
if (client != null && chatCompletions != null && key!= "AI_KEY")
{
chatCompletions.Messages.Clear();
chatCompletions.Messages.Add(new ChatRequestSystemMessage("Please provide the prompt for responce" + prompt));
chatCompletions.Messages.Add(new ChatRequestUserMessage(prompt));
var response = await client.GetChatCompletionsAsync(chatCompletions);
return response.Value.Choices[0].Message.Content;
}
else
{
return "Please connect OpenAI for real time queries";
}
}

/// <summary>
/// Gets a solution to a given prompt by using either local embeddings or extracted text,
/// depending on the platform.
/// </summary>
/// <param name="question">The user's question to be processed.</param>
/// <returns>A task representing the asynchronous operation, with a solution string as the result.</returns>
internal async Task<string> GetSolutionToPrompt(string question)
{
try
{
// Use extracted text
if (ExtractedText != null && client != null && chatCompletions != null && key != "AI_KEY")
{
string message = ExtractedText;
var systemPrompt = "You are a helpful assistant. Use the provided PDF document pages and pick a precise page to answer the user question,Ignore about iTextSharp related points in the details, Strictly don't bold any text all text need to plain text. Pages: " + message;
chatCompletions.Messages.Clear();
chatCompletions.Messages.Add(new ChatRequestSystemMessage(systemPrompt));
chatCompletions.Messages.Add(new ChatRequestUserMessage(question));
var response = await client.GetChatCompletionsAsync(chatCompletions);
return response.Value.Choices[0].Message.Content;
}
return "Please connect OpenAI for real time queries";
}
catch
{
return "Please connect OpenAI for real time queries";
}
}

/// <summary>
/// Generates suggestions based on a given prompt.
/// </summary>
/// <param name="prompt">The input prompt string.</param>
/// <returns>A task representing the asynchronous operation, with an <see cref="AssistItemSuggestion"/> object as the result.</returns>
internal async Task<AssistItemSuggestion> GetSuggestion(string prompt)
{
var chatSuggestions = new AssistItemSuggestion();

var suggestions = new ObservableCollection<ISuggestion>();
var suggestion = await GetAnswerFromGPT("You are a helpful assistant. Your task is to analyze the provided text and generate 3 short diverse questions and each question should not exceed 10 words.");
if (suggestion != "Please connect OpenAI for real time queries")
{
string[] parts = suggestion.Split(new string[] { "1. ", "2. ", "3. " }, StringSplitOptions.RemoveEmptyEntries);
// Store the parts in separate variables
string question1 = parts.Length > 0 ? parts[0].Trim() : string.Empty;
string question2 = parts.Length > 1 ? parts[1].Trim() : string.Empty;
string question3 = parts.Length > 2 ? parts[2].Trim() : string.Empty;
suggestions.Add(new AssistSuggestion() { Text = question1 });
suggestions.Add(new AssistSuggestion() { Text = question2 });
suggestions.Add(new AssistSuggestion() { Text = question3 });
chatSuggestions.Items = suggestions;
}
return chatSuggestions;
}

/// <summary>
/// Gets an answer from the GPT model using only a system prompt.
/// </summary>
/// <param name="systemPrompt">The system prompt to guide the AI.</param>
/// <returns>A task representing the asynchronous operation, with the answer string as the result.</returns>
internal async Task<string> GetAnswerFromGPT(string systemPrompt)
{
try
{
if (ExtractedText != null && chatCompletions != null && client != null && key != "AI_KEY")
{
chatCompletions.Messages.Clear();
chatCompletions.Messages.Add(new ChatRequestSystemMessage(systemPrompt));
chatCompletions.Messages.Add(new ChatRequestUserMessage(ExtractedText));
var response = await client.GetChatCompletionsAsync(chatCompletions);
return response.Value.Choices[0].Message.Content;
}
else
{
return "Please connect OpenAI for real time queries";
}
}
catch
{
return "Please connect OpenAI for real time queries";
}
}
}
}
Loading
Loading