From 878b9711880ba3c7ecb86846fa6ff2d7b40110af Mon Sep 17 00:00:00 2001 From: "PROGRESS\\ykaraman" Date: Fri, 21 Nov 2025 01:25:34 +0200 Subject: [PATCH 1/7] Net Standard GenAI demos. --- .../OllamaEmbeddingsStorage.cs | 67 ----------- .../Properties/launchSettings.json | 11 -- PdfProcessing/AIConnectorDemo/ReadMe.md | 9 -- ...ustomJpegImageConverter_NetStandard.csproj | 2 +- .../AIConnectorDemo.csproj | 0 .../CustomOpenAIEmbedder.cs | 98 ++++++++++++++++ .../Fixed_AIConnectorDemo_NetStandard.csproj} | 4 +- .../John Grisham.pdf | Bin .../Program.cs | 37 +++--- .../Properties/launchSettings.json | 7 ++ PdfProcessing/Fixed_AIConnectorDemo/ReadMe.md | 5 + .../Fixed_AIConnectorDemo/TextLoader.cs | 20 ++++ .../CustomOpenAIEmbedder.cs | 98 ++++++++++++++++ .../Flow_AIConnectorDemo_NetStandard.csproj | 31 +++++ ...GenAI Document Insights Test Document.docx | Bin 0 -> 28934 bytes .../Program.cs | 107 +++++++++++++++++ .../Properties/launchSettings.json | 7 ++ .../ReadMe.md | 5 + .../TextLoader.cs | 2 +- PdfProcessing/PdfProcessing_NetStandard.sln | 16 ++- .../CustomOpenAIEmbedder.cs | 98 ++++++++++++++++ ...GenAI Document Insights Test Document.xlsx | Bin 0 -> 10731 bytes .../Program.cs | 110 ++++++++++++++++++ .../Properties/launchSettings.json | 7 ++ .../ReadMe.md | 5 + .../Spread_AIConnectorDemo_NetStandard.csproj | 32 +++++ .../TextLoader.cs | 20 ++++ 27 files changed, 690 insertions(+), 108 deletions(-) delete mode 100644 PdfProcessing/AIConnectorDemo/OllamaEmbeddingsStorage.cs delete mode 100644 PdfProcessing/AIConnectorDemo/Properties/launchSettings.json delete mode 100644 PdfProcessing/AIConnectorDemo/ReadMe.md rename PdfProcessing/{AIConnectorDemo => Fixed_AIConnectorDemo}/AIConnectorDemo.csproj (100%) create mode 100644 PdfProcessing/Fixed_AIConnectorDemo/CustomOpenAIEmbedder.cs rename PdfProcessing/{AIConnectorDemo/AIConnectorDemo_NetStandard.csproj => Fixed_AIConnectorDemo/Fixed_AIConnectorDemo_NetStandard.csproj} (96%) rename PdfProcessing/{AIConnectorDemo => Fixed_AIConnectorDemo}/John Grisham.pdf (100%) rename PdfProcessing/{AIConnectorDemo => Fixed_AIConnectorDemo}/Program.cs (66%) create mode 100644 PdfProcessing/Fixed_AIConnectorDemo/Properties/launchSettings.json create mode 100644 PdfProcessing/Fixed_AIConnectorDemo/ReadMe.md create mode 100644 PdfProcessing/Fixed_AIConnectorDemo/TextLoader.cs create mode 100644 PdfProcessing/Flow_AIConnectorDemo_NetStandard/CustomOpenAIEmbedder.cs create mode 100644 PdfProcessing/Flow_AIConnectorDemo_NetStandard/Flow_AIConnectorDemo_NetStandard.csproj create mode 100644 PdfProcessing/Flow_AIConnectorDemo_NetStandard/GenAI Document Insights Test Document.docx create mode 100644 PdfProcessing/Flow_AIConnectorDemo_NetStandard/Program.cs create mode 100644 PdfProcessing/Flow_AIConnectorDemo_NetStandard/Properties/launchSettings.json create mode 100644 PdfProcessing/Flow_AIConnectorDemo_NetStandard/ReadMe.md rename PdfProcessing/{AIConnectorDemo => Flow_AIConnectorDemo_NetStandard}/TextLoader.cs (96%) create mode 100644 PdfProcessing/Spread_AIConnectorDemo_NetStandard/CustomOpenAIEmbedder.cs create mode 100644 PdfProcessing/Spread_AIConnectorDemo_NetStandard/GenAI Document Insights Test Document.xlsx create mode 100644 PdfProcessing/Spread_AIConnectorDemo_NetStandard/Program.cs create mode 100644 PdfProcessing/Spread_AIConnectorDemo_NetStandard/Properties/launchSettings.json create mode 100644 PdfProcessing/Spread_AIConnectorDemo_NetStandard/ReadMe.md create mode 100644 PdfProcessing/Spread_AIConnectorDemo_NetStandard/Spread_AIConnectorDemo_NetStandard.csproj create mode 100644 PdfProcessing/Spread_AIConnectorDemo_NetStandard/TextLoader.cs diff --git a/PdfProcessing/AIConnectorDemo/OllamaEmbeddingsStorage.cs b/PdfProcessing/AIConnectorDemo/OllamaEmbeddingsStorage.cs deleted file mode 100644 index c089244..0000000 --- a/PdfProcessing/AIConnectorDemo/OllamaEmbeddingsStorage.cs +++ /dev/null @@ -1,67 +0,0 @@ -using LangChain.Databases; -using LangChain.Databases.Sqlite; -using LangChain.DocumentLoaders; -using LangChain.Extensions; -using LangChain.Providers; -using LangChain.Providers.Ollama; -using Telerik.Documents.AIConnector; - -namespace AIConnectorDemo -{ - // Necessary steps to get this working: - // 1. Install Ollama: https://ollama.com/ - // 2. Pull the all-minilm model we'll use for embeddings: ollama pull all-minilm - // 3. Ensure Ollama is running: ollama serve - internal class OllamaEmbeddingsStorage : IEmbeddingsStorage - { - private const string AllMinilmEmbeddingModelName = "all-minilm"; - private const string DBName = "vectors.db"; - private const int DimensionsForAllMinilm = 384; // Should be 384 for all-minilm - private static readonly string defaultCollectionName = "defaultName"; - - private readonly SqLiteVectorDatabase vectorDatabase; - private readonly OllamaEmbeddingModel embeddingModel; - - IVectorCollection vectorCollection; - - public OllamaEmbeddingsStorage() - { - OllamaProvider provider = new OllamaProvider(); - this.embeddingModel = new OllamaEmbeddingModel(provider, id: AllMinilmEmbeddingModelName); - this.vectorDatabase = new SqLiteVectorDatabase(dataSource: DBName); - } - - public async Task GetQuestionContext(string question) - { - IReadOnlyCollection similarDocuments = await this.vectorCollection.GetSimilarDocuments(this.embeddingModel, question, amount: 5); - - return similarDocuments.AsString(); - } - - public void SetText(string text, PartialContextProcessorSettings settings) - { - MemoryStream memoryStream = new MemoryStream(); - StreamWriter writer = new StreamWriter(memoryStream); - writer.Write(text); - - if (this.vectorDatabase.IsCollectionExistsAsync(defaultCollectionName).Result) - { - this.vectorDatabase.DeleteCollectionAsync(defaultCollectionName).Wait(); - } - - this.vectorCollection = this.vectorDatabase.AddDocumentsFromAsync( - this.embeddingModel, - dimensions: DimensionsForAllMinilm, - dataSource: DataSource.FromBytes(memoryStream.ToArray()), - textSplitter: null, - collectionName: defaultCollectionName, - behavior: AddDocumentsToDatabaseBehavior.JustReturnCollectionIfCollectionIsAlreadyExists).Result; - - } - - public void Dispose() - { - this.vectorDatabase.Dispose(); - } - } -} \ No newline at end of file diff --git a/PdfProcessing/AIConnectorDemo/Properties/launchSettings.json b/PdfProcessing/AIConnectorDemo/Properties/launchSettings.json deleted file mode 100644 index 896fece..0000000 --- a/PdfProcessing/AIConnectorDemo/Properties/launchSettings.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "profiles": { - "AIConnectorDemo": { - "commandName": "Project", - "environmentVariables": { - "AZUREOPENAI_KEY": "key", - "AZUREOPENAI_ENDPOINT": "endpoint" - } - } - } -} \ No newline at end of file diff --git a/PdfProcessing/AIConnectorDemo/ReadMe.md b/PdfProcessing/AIConnectorDemo/ReadMe.md deleted file mode 100644 index e31e9ff..0000000 --- a/PdfProcessing/AIConnectorDemo/ReadMe.md +++ /dev/null @@ -1,9 +0,0 @@ -In order to run the project, you need to replace the key and endpoint with your Azure Open AI key and endpoint. -They are located in the launchSettings.json file in the Properties folder. - -In NetStandard you need to implement IEmbeddingsStorage if you would like to use the PartialContextQuestionProcessor. -There is a sample implementation called OllamaEmbeddingsStorage in the NetStandard project. -For it to work the Ollama server needs to be running locally. You can follow these steps to run it: - 1. Install Ollama: https://ollama.com/ - 2. Pull the all-minilm model we'll use for embeddings: ollama pull all-minilm - 3. Ensure Ollama is running: ollama serve \ No newline at end of file diff --git a/PdfProcessing/CustomJpegImageConverter/CustomJpegImageConverter_NetStandard.csproj b/PdfProcessing/CustomJpegImageConverter/CustomJpegImageConverter_NetStandard.csproj index f247e95..18587b2 100644 --- a/PdfProcessing/CustomJpegImageConverter/CustomJpegImageConverter_NetStandard.csproj +++ b/PdfProcessing/CustomJpegImageConverter/CustomJpegImageConverter_NetStandard.csproj @@ -21,7 +21,7 @@ - + diff --git a/PdfProcessing/AIConnectorDemo/AIConnectorDemo.csproj b/PdfProcessing/Fixed_AIConnectorDemo/AIConnectorDemo.csproj similarity index 100% rename from PdfProcessing/AIConnectorDemo/AIConnectorDemo.csproj rename to PdfProcessing/Fixed_AIConnectorDemo/AIConnectorDemo.csproj diff --git a/PdfProcessing/Fixed_AIConnectorDemo/CustomOpenAIEmbedder.cs b/PdfProcessing/Fixed_AIConnectorDemo/CustomOpenAIEmbedder.cs new file mode 100644 index 0000000..dcd9d72 --- /dev/null +++ b/PdfProcessing/Fixed_AIConnectorDemo/CustomOpenAIEmbedder.cs @@ -0,0 +1,98 @@ +using System.Net.Http.Headers; +using System.Text; +using System.Text.Json; +using Telerik.Documents.AI.Core; + +namespace FixedAIConnectorDemo +{ + public class CustomOpenAIEmbedder : IEmbedder + { + private readonly HttpClient httpClient; + + public CustomOpenAIEmbedder() + { + HttpClient httpClient = new HttpClient(); + httpClient.Timeout = TimeSpan.FromMinutes(5); + string endpoint = Environment.GetEnvironmentVariable("AZUREEMBEDDINGOPENAI_ENDPOINT"); + string apiKey = Environment.GetEnvironmentVariable("AZUREEMBEDDINGOPENAI_KEY"); + + httpClient.BaseAddress = new Uri(endpoint); + httpClient.DefaultRequestHeaders.Add("api-key", apiKey); + httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); + + this.httpClient = httpClient; + } + + public async Task> EmbedAsync(IList fragments) + { + AzureEmbeddingsRequest requestBody = new AzureEmbeddingsRequest + { + Input = fragments.Select(p => p.ToEmbeddingText()).ToArray(), + Dimensions = 3072 + }; + + string json = JsonSerializer.Serialize(requestBody); + StringContent content = new StringContent(json, Encoding.UTF8, "application/json"); + + string apiVersion = Environment.GetEnvironmentVariable("AZUREEMBEDDINGOPENAI_APIVERSION"); + string deploymentName = Environment.GetEnvironmentVariable("AZUREEMBEDDINGOPENAI_DEPLOYMENT"); + string url = $"openai/deployments/{deploymentName}/embeddings?api-version={apiVersion}"; + using HttpResponseMessage response = await this.httpClient.PostAsync(url, content, CancellationToken.None); + + Embedding[] embeddings = new Embedding[fragments.Count]; + + string responseJson = await response.Content.ReadAsStringAsync(CancellationToken.None); + AzureEmbeddingsResponse responseObj = JsonSerializer.Deserialize(responseJson); + + List sorted = responseObj.Data.OrderBy(d => d.Index).ToList(); + List result = new List(sorted.Count); + + for (int i = 0; i < sorted.Count; i++) + { + EmbeddingData item = sorted[i]; + embeddings[i] = new Embedding(fragments[i], item.Embedding); + } + + return embeddings; + } + + private sealed class AzureEmbeddingsRequest + { + [System.Text.Json.Serialization.JsonPropertyName("input")] + public string[] Input { get; set; } = Array.Empty(); + + [System.Text.Json.Serialization.JsonPropertyName("dimensions")] + public int? Dimensions { get; set; } + } + + private sealed class AzureEmbeddingsResponse + { + [System.Text.Json.Serialization.JsonPropertyName("data")] + public EmbeddingData[] Data { get; set; } = Array.Empty(); + + [System.Text.Json.Serialization.JsonPropertyName("model")] + public string? Model { get; set; } + + [System.Text.Json.Serialization.JsonPropertyName("usage")] + public UsageInfo? Usage { get; set; } + } + + private sealed class UsageInfo + { + [System.Text.Json.Serialization.JsonPropertyName("prompt_tokens")] + public int PromptTokens { get; set; } + + [System.Text.Json.Serialization.JsonPropertyName("total_tokens")] + public int TotalTokens { get; set; } + } + + private sealed class EmbeddingData + { + [System.Text.Json.Serialization.JsonPropertyName("embedding")] + public float[] Embedding { get; set; } = Array.Empty(); + + [System.Text.Json.Serialization.JsonPropertyName("index")] + public int Index { get; set; } + } + } +} \ No newline at end of file diff --git a/PdfProcessing/AIConnectorDemo/AIConnectorDemo_NetStandard.csproj b/PdfProcessing/Fixed_AIConnectorDemo/Fixed_AIConnectorDemo_NetStandard.csproj similarity index 96% rename from PdfProcessing/AIConnectorDemo/AIConnectorDemo_NetStandard.csproj rename to PdfProcessing/Fixed_AIConnectorDemo/Fixed_AIConnectorDemo_NetStandard.csproj index feba08d..653811e 100644 --- a/PdfProcessing/AIConnectorDemo/AIConnectorDemo_NetStandard.csproj +++ b/PdfProcessing/Fixed_AIConnectorDemo/Fixed_AIConnectorDemo_NetStandard.csproj @@ -18,8 +18,8 @@ - - + + diff --git a/PdfProcessing/AIConnectorDemo/John Grisham.pdf b/PdfProcessing/Fixed_AIConnectorDemo/John Grisham.pdf similarity index 100% rename from PdfProcessing/AIConnectorDemo/John Grisham.pdf rename to PdfProcessing/Fixed_AIConnectorDemo/John Grisham.pdf diff --git a/PdfProcessing/AIConnectorDemo/Program.cs b/PdfProcessing/Fixed_AIConnectorDemo/Program.cs similarity index 66% rename from PdfProcessing/AIConnectorDemo/Program.cs rename to PdfProcessing/Fixed_AIConnectorDemo/Program.cs index 6194742..b25c5da 100644 --- a/PdfProcessing/AIConnectorDemo/Program.cs +++ b/PdfProcessing/Fixed_AIConnectorDemo/Program.cs @@ -2,6 +2,8 @@ using Microsoft.Extensions.AI; using OpenAI.Chat; using System.IO; +using Telerik.Documents.AI.Core; + #if NETWINDOWS using Telerik.Windows.Documents.AIConnector; #else @@ -11,12 +13,17 @@ using Telerik.Windows.Documents.Fixed.Model; using Telerik.Windows.Documents.TextRepresentation; -namespace AIConnectorDemo +namespace FixedAIConnectorDemo { internal class Program { static int maxTokenCount = 128000; + static int maxNumberOfEmbeddingsSent = 50000; static IChatClient iChatClient; + static string tokenizationEncoding = "cl100k_base"; + static string model = "gpt-4o-mini"; + static string key = Environment.GetEnvironmentVariable("AZUREOPENAI_KEY"); + static string endpoint = Environment.GetEnvironmentVariable("AZUREOPENAI_ENDPOINT"); static void Main(string[] args) { @@ -28,7 +35,7 @@ static void Main(string[] args) { PdfFormatProvider pdfFormatProvider = new PdfFormatProvider(); RadFixedDocument inputPdf = pdfFormatProvider.Import(input, null); - ISimpleTextDocument simpleDocument = inputPdf.ToSimpleTextDocument(); + SimpleTextDocument simpleDocument = inputPdf.ToSimpleTextDocument(TimeSpan.FromSeconds(10)); Summarize(simpleDocument); @@ -44,10 +51,6 @@ static void Main(string[] args) private static void CreateChatClient() { - string key = Environment.GetEnvironmentVariable("AZUREOPENAI_KEY"); - string endpoint = Environment.GetEnvironmentVariable("AZUREOPENAI_ENDPOINT"); - string model = "gpt-4o-mini"; - AzureOpenAIClient azureClient = new( new Uri(endpoint), new Azure.AzureKeyCredential(key), @@ -57,10 +60,12 @@ private static void CreateChatClient() iChatClient = new OpenAIChatClient(chatClient); } - private static void Summarize(ISimpleTextDocument simpleDocument) + private static void Summarize(SimpleTextDocument simpleDocument) { - SummarizationProcessor summarizationProcessor = new SummarizationProcessor(iChatClient, maxTokenCount); - summarizationProcessor.Settings.PromptAddition = "Summarize the text in a few sentences. Be concise and clear."; + string additionalPrompt = "Summarize the text in a few sentences. Be concise and clear."; + SummarizationProcessorSettings summarizationProcessorSettings = new SummarizationProcessorSettings(maxTokenCount, additionalPrompt); + SummarizationProcessor summarizationProcessor = new SummarizationProcessor(iChatClient, summarizationProcessorSettings); + summarizationProcessor.SummaryResourcesCalculated += SummarizationProcessor_SummaryResourcesCalculated; string summary = summarizationProcessor.Summarize(simpleDocument).Result; @@ -73,9 +78,10 @@ private static void SummarizationProcessor_SummaryResourcesCalculated(object? se e.ShouldContinueExecution = true; } - private static void AskQuestion(ISimpleTextDocument simpleDocument) + private static void AskQuestion(SimpleTextDocument simpleDocument) { - CompleteContextQuestionProcessor completeContextQuestionProcessor = new CompleteContextQuestionProcessor(iChatClient, maxTokenCount); + CompleteContextProcessorSettings completeContextProcessorSettings = new CompleteContextProcessorSettings(maxTokenCount, model, tokenizationEncoding, false); + CompleteContextQuestionProcessor completeContextQuestionProcessor = new CompleteContextQuestionProcessor(iChatClient, completeContextProcessorSettings); string question = "How many pages is the document and what is it about?"; string answer = completeContextQuestionProcessor.AnswerQuestion(simpleDocument, question).Result; @@ -83,13 +89,14 @@ private static void AskQuestion(ISimpleTextDocument simpleDocument) Console.WriteLine(answer); } - private static void AskPartialContextQuestion(ISimpleTextDocument simpleDocument) + private static void AskPartialContextQuestion(SimpleTextDocument simpleDocument) { + var settings = EmbeddingSettingsFactory.CreateSettingsForTextDocuments(maxTokenCount, model, tokenizationEncoding, maxNumberOfEmbeddingsSent); #if NETWINDOWS - PartialContextQuestionProcessor partialContextQuestionProcessor = new PartialContextQuestionProcessor(iChatClient, maxTokenCount, simpleDocument); + PartialContextQuestionProcessor partialContextQuestionProcessor = new PartialContextQuestionProcessor(iChatClient, settings, simpleDocument); #else - IEmbeddingsStorage embeddingsStorage = new OllamaEmbeddingsStorage(); - PartialContextQuestionProcessor partialContextQuestionProcessor = new PartialContextQuestionProcessor(iChatClient, embeddingsStorage, maxTokenCount, simpleDocument); + IEmbedder embedder = new CustomOpenAIEmbedder(); + PartialContextQuestionProcessor partialContextQuestionProcessor = new PartialContextQuestionProcessor(iChatClient, embedder, settings, simpleDocument); #endif string question = "What is the last book by John Grisham?"; string answer = partialContextQuestionProcessor.AnswerQuestion(question).Result; diff --git a/PdfProcessing/Fixed_AIConnectorDemo/Properties/launchSettings.json b/PdfProcessing/Fixed_AIConnectorDemo/Properties/launchSettings.json new file mode 100644 index 0000000..3fa9154 --- /dev/null +++ b/PdfProcessing/Fixed_AIConnectorDemo/Properties/launchSettings.json @@ -0,0 +1,7 @@ +{ + "profiles": { + "FixedAIConnectorDemo": { + "commandName": "Project" + } + } +} \ No newline at end of file diff --git a/PdfProcessing/Fixed_AIConnectorDemo/ReadMe.md b/PdfProcessing/Fixed_AIConnectorDemo/ReadMe.md new file mode 100644 index 0000000..a482053 --- /dev/null +++ b/PdfProcessing/Fixed_AIConnectorDemo/ReadMe.md @@ -0,0 +1,5 @@ +In order to run the project, you need to replace the key and endpoint with your Azure Open AI key and endpoint. +They are located in the launchSettings.json file in the Properties folder. + +In NetStandard you need to implement IEmbedder if you would like to use the PartialContextQuestionProcessor. +There is a sample implementation called CustomOpenAIEmbedder in the NetStandard project. \ No newline at end of file diff --git a/PdfProcessing/Fixed_AIConnectorDemo/TextLoader.cs b/PdfProcessing/Fixed_AIConnectorDemo/TextLoader.cs new file mode 100644 index 0000000..816dd93 --- /dev/null +++ b/PdfProcessing/Fixed_AIConnectorDemo/TextLoader.cs @@ -0,0 +1,20 @@ +using LangChain.DocumentLoaders; + +namespace FixedAIConnectorDemo +{ + internal class TextLoader : IDocumentLoader + { + public async Task> LoadAsync(DataSource dataSource, DocumentLoaderSettings? settings = null, CancellationToken cancellationToken = default) + { + using (Stream inputStream = await dataSource.GetStreamAsync(cancellationToken)) + { + StreamReader reader = new StreamReader(inputStream); + string content = reader.ReadToEnd(); + + string[] pages = content.Split(["----------"], System.StringSplitOptions.RemoveEmptyEntries); + + return pages.Select(x => new Document(x)).ToList(); + } + } + } +} \ No newline at end of file diff --git a/PdfProcessing/Flow_AIConnectorDemo_NetStandard/CustomOpenAIEmbedder.cs b/PdfProcessing/Flow_AIConnectorDemo_NetStandard/CustomOpenAIEmbedder.cs new file mode 100644 index 0000000..86cef66 --- /dev/null +++ b/PdfProcessing/Flow_AIConnectorDemo_NetStandard/CustomOpenAIEmbedder.cs @@ -0,0 +1,98 @@ +using System.Net.Http.Headers; +using System.Text; +using System.Text.Json; +using Telerik.Documents.AI.Core; + +namespace FlowAIConnectorDemo +{ + public class CustomOpenAIEmbedder : IEmbedder + { + private readonly HttpClient httpClient; + + public CustomOpenAIEmbedder() + { + HttpClient httpClient = new HttpClient(); + httpClient.Timeout = TimeSpan.FromMinutes(5); + string endpoint = Environment.GetEnvironmentVariable("AZUREEMBEDDINGOPENAI_ENDPOINT"); + string apiKey = Environment.GetEnvironmentVariable("AZUREEMBEDDINGOPENAI_KEY"); + + httpClient.BaseAddress = new Uri(endpoint); + httpClient.DefaultRequestHeaders.Add("api-key", apiKey); + httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); + + this.httpClient = httpClient; + } + + public async Task> EmbedAsync(IList fragments) + { + AzureEmbeddingsRequest requestBody = new AzureEmbeddingsRequest + { + Input = fragments.Select(p => p.ToEmbeddingText()).ToArray(), + Dimensions = 3072 + }; + + string json = JsonSerializer.Serialize(requestBody); + StringContent content = new StringContent(json, Encoding.UTF8, "application/json"); + + string apiVersion = Environment.GetEnvironmentVariable("AZUREEMBEDDINGOPENAI_APIVERSION"); + string deploymentName = Environment.GetEnvironmentVariable("AZUREEMBEDDINGOPENAI_DEPLOYMENT"); + string url = $"openai/deployments/{deploymentName}/embeddings?api-version={apiVersion}"; + using HttpResponseMessage response = await this.httpClient.PostAsync(url, content, CancellationToken.None); + + Embedding[] embeddings = new Embedding[fragments.Count]; + + string responseJson = await response.Content.ReadAsStringAsync(CancellationToken.None); + AzureEmbeddingsResponse responseObj = JsonSerializer.Deserialize(responseJson); + + List sorted = responseObj.Data.OrderBy(d => d.Index).ToList(); + List result = new List(sorted.Count); + + for (int i = 0; i < sorted.Count; i++) + { + EmbeddingData item = sorted[i]; + embeddings[i] = new Embedding(fragments[i], item.Embedding); + } + + return embeddings; + } + + private sealed class AzureEmbeddingsRequest + { + [System.Text.Json.Serialization.JsonPropertyName("input")] + public string[] Input { get; set; } = Array.Empty(); + + [System.Text.Json.Serialization.JsonPropertyName("dimensions")] + public int? Dimensions { get; set; } + } + + private sealed class AzureEmbeddingsResponse + { + [System.Text.Json.Serialization.JsonPropertyName("data")] + public EmbeddingData[] Data { get; set; } = Array.Empty(); + + [System.Text.Json.Serialization.JsonPropertyName("model")] + public string? Model { get; set; } + + [System.Text.Json.Serialization.JsonPropertyName("usage")] + public UsageInfo? Usage { get; set; } + } + + private sealed class UsageInfo + { + [System.Text.Json.Serialization.JsonPropertyName("prompt_tokens")] + public int PromptTokens { get; set; } + + [System.Text.Json.Serialization.JsonPropertyName("total_tokens")] + public int TotalTokens { get; set; } + } + + private sealed class EmbeddingData + { + [System.Text.Json.Serialization.JsonPropertyName("embedding")] + public float[] Embedding { get; set; } = Array.Empty(); + + [System.Text.Json.Serialization.JsonPropertyName("index")] + public int Index { get; set; } + } + } +} \ No newline at end of file diff --git a/PdfProcessing/Flow_AIConnectorDemo_NetStandard/Flow_AIConnectorDemo_NetStandard.csproj b/PdfProcessing/Flow_AIConnectorDemo_NetStandard/Flow_AIConnectorDemo_NetStandard.csproj new file mode 100644 index 0000000..38e50d0 --- /dev/null +++ b/PdfProcessing/Flow_AIConnectorDemo_NetStandard/Flow_AIConnectorDemo_NetStandard.csproj @@ -0,0 +1,31 @@ + + + + Exe + net8.0 + enable + enable + + + + NETSTANDARD;$(DefineConstants) + + + + + + + + + + + + + + + + PreserveNewest + + + + diff --git a/PdfProcessing/Flow_AIConnectorDemo_NetStandard/GenAI Document Insights Test Document.docx b/PdfProcessing/Flow_AIConnectorDemo_NetStandard/GenAI Document Insights Test Document.docx new file mode 100644 index 0000000000000000000000000000000000000000..594a30f11a4dd08fe4d1b8458933c2e049ab3c42 GIT binary patch literal 28934 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 lK9B#7rgr*!4gS~DSxXfg)nm|5c0i> EmbedAsync(IList fragments) + { + AzureEmbeddingsRequest requestBody = new AzureEmbeddingsRequest + { + Input = fragments.Select(p => p.ToEmbeddingText()).ToArray(), + Dimensions = 3072 + }; + + string json = JsonSerializer.Serialize(requestBody); + StringContent content = new StringContent(json, Encoding.UTF8, "application/json"); + + string apiVersion = Environment.GetEnvironmentVariable("AZUREEMBEDDINGOPENAI_APIVERSION"); + string deploymentName = Environment.GetEnvironmentVariable("AZUREEMBEDDINGOPENAI_DEPLOYMENT"); + string url = $"openai/deployments/{deploymentName}/embeddings?api-version={apiVersion}"; + using HttpResponseMessage response = await this.httpClient.PostAsync(url, content, CancellationToken.None); + + Embedding[] embeddings = new Embedding[fragments.Count]; + + string responseJson = await response.Content.ReadAsStringAsync(CancellationToken.None); + AzureEmbeddingsResponse responseObj = JsonSerializer.Deserialize(responseJson); + + List sorted = responseObj.Data.OrderBy(d => d.Index).ToList(); + List result = new List(sorted.Count); + + for (int i = 0; i < sorted.Count; i++) + { + EmbeddingData item = sorted[i]; + embeddings[i] = new Embedding(fragments[i], item.Embedding); + } + + return embeddings; + } + + private sealed class AzureEmbeddingsRequest + { + [System.Text.Json.Serialization.JsonPropertyName("input")] + public string[] Input { get; set; } = Array.Empty(); + + [System.Text.Json.Serialization.JsonPropertyName("dimensions")] + public int? Dimensions { get; set; } + } + + private sealed class AzureEmbeddingsResponse + { + [System.Text.Json.Serialization.JsonPropertyName("data")] + public EmbeddingData[] Data { get; set; } = Array.Empty(); + + [System.Text.Json.Serialization.JsonPropertyName("model")] + public string? Model { get; set; } + + [System.Text.Json.Serialization.JsonPropertyName("usage")] + public UsageInfo? Usage { get; set; } + } + + private sealed class UsageInfo + { + [System.Text.Json.Serialization.JsonPropertyName("prompt_tokens")] + public int PromptTokens { get; set; } + + [System.Text.Json.Serialization.JsonPropertyName("total_tokens")] + public int TotalTokens { get; set; } + } + + private sealed class EmbeddingData + { + [System.Text.Json.Serialization.JsonPropertyName("embedding")] + public float[] Embedding { get; set; } = Array.Empty(); + + [System.Text.Json.Serialization.JsonPropertyName("index")] + public int Index { get; set; } + } + } +} \ No newline at end of file diff --git a/PdfProcessing/Spread_AIConnectorDemo_NetStandard/GenAI Document Insights Test Document.xlsx b/PdfProcessing/Spread_AIConnectorDemo_NetStandard/GenAI Document Insights Test Document.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..6cc70859cffcab7b2d216c32f9a3c4e72dcff608 GIT binary patch literal 10731 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 literal 0 HcmV?d00001 diff --git a/PdfProcessing/Spread_AIConnectorDemo_NetStandard/Program.cs b/PdfProcessing/Spread_AIConnectorDemo_NetStandard/Program.cs new file mode 100644 index 0000000..275781f --- /dev/null +++ b/PdfProcessing/Spread_AIConnectorDemo_NetStandard/Program.cs @@ -0,0 +1,110 @@ +using Azure.AI.OpenAI; +using Microsoft.Extensions.AI; +using OpenAI.Chat; +using System.IO; +using Telerik.Documents.AI.Core; + +#if NETWINDOWS +using Telerik.Windows.Documents.AIConnector; +#else +using Telerik.Documents.AIConnector; +using Telerik.Windows.Documents.Spreadsheet.FormatProviders.Json; +using Telerik.Windows.Documents.Spreadsheet.FormatProviders.OpenXml.Xlsx; +using Telerik.Windows.Documents.Spreadsheet.Model; + + +#endif +using Telerik.Windows.Documents.TextRepresentation; + +namespace SpreadAIConnectorDemo +{ + internal class Program + { + static int maxTokenCount = 128000; + static int maxNumberOfEmbeddingsSent = 50000; + static IChatClient iChatClient; + static string tokenizationEncoding = "cl100k_base"; + static string model = "gpt-4o-mini"; + static string key = Environment.GetEnvironmentVariable("AZUREOPENAI_KEY"); + static string endpoint = Environment.GetEnvironmentVariable("AZUREOPENAI_ENDPOINT"); + + static void Main(string[] args) + { + Console.WriteLine("Hello, World!"); + + CreateChatClient(); + + using (Stream input = File.OpenRead("GenAI Document Insights Test Document.xlsx")) + { + XlsxFormatProvider xlsxFormatProvider = new XlsxFormatProvider(); + Workbook inputXlsx = xlsxFormatProvider.Import(input, null); + SimpleTextDocument simpleDocument = inputXlsx.ToSimpleTextDocument(TimeSpan.FromSeconds(10)); + + Summarize(simpleDocument); + + Console.WriteLine("--------------------------------------------------"); + + AskQuestion(simpleDocument); + + Console.WriteLine("--------------------------------------------------"); + + AskPartialContextQuestion(simpleDocument); + } + } + + private static void CreateChatClient() + { + AzureOpenAIClient azureClient = new( + new Uri(endpoint), + new Azure.AzureKeyCredential(key), + new AzureOpenAIClientOptions()); + ChatClient chatClient = azureClient.GetChatClient(model); + + iChatClient = new OpenAIChatClient(chatClient); + } + + private static void Summarize(SimpleTextDocument simpleDocument) + { + string additionalPrompt = "Summarize the text in a few sentences. Be concise and clear."; + SummarizationProcessorSettings summarizationProcessorSettings = new SummarizationProcessorSettings(maxTokenCount, additionalPrompt); + SummarizationProcessor summarizationProcessor = new SummarizationProcessor(iChatClient, summarizationProcessorSettings); + + summarizationProcessor.SummaryResourcesCalculated += SummarizationProcessor_SummaryResourcesCalculated; + + string summary = summarizationProcessor.Summarize(simpleDocument).Result; + Console.WriteLine(summary); + } + + private static void SummarizationProcessor_SummaryResourcesCalculated(object? sender, SummaryResourcesCalculatedEventArgs e) + { + Console.WriteLine($"The summary will require {e.EstimatedCallsRequired} calls and {e.EstimatedTokensRequired} tokens"); + e.ShouldContinueExecution = true; + } + + private static void AskQuestion(SimpleTextDocument simpleDocument) + { + CompleteContextProcessorSettings completeContextProcessorSettings = new CompleteContextProcessorSettings(maxTokenCount, model, tokenizationEncoding, false); + CompleteContextQuestionProcessor completeContextQuestionProcessor = new CompleteContextQuestionProcessor(iChatClient, completeContextProcessorSettings); + + string question = "How many pages is the document and what is it about?"; + string answer = completeContextQuestionProcessor.AnswerQuestion(simpleDocument, question).Result; + Console.WriteLine(question); + Console.WriteLine(answer); + } + + private static void AskPartialContextQuestion(SimpleTextDocument simpleDocument) + { + var settings = EmbeddingSettingsFactory.CreateSettingsForTextDocuments(maxTokenCount, model, tokenizationEncoding, maxNumberOfEmbeddingsSent); +#if NETWINDOWS + PartialContextQuestionProcessor partialContextQuestionProcessor = new PartialContextQuestionProcessor(iChatClient, settings, simpleDocument); +#else + IEmbedder embedder = new CustomOpenAIEmbedder(); + PartialContextQuestionProcessor partialContextQuestionProcessor = new PartialContextQuestionProcessor(iChatClient, embedder, settings, simpleDocument); +#endif + string question = "Who are the key authors listed in the document?"; + string answer = partialContextQuestionProcessor.AnswerQuestion(question).Result; + Console.WriteLine(question); + Console.WriteLine(answer); + } + } +} diff --git a/PdfProcessing/Spread_AIConnectorDemo_NetStandard/Properties/launchSettings.json b/PdfProcessing/Spread_AIConnectorDemo_NetStandard/Properties/launchSettings.json new file mode 100644 index 0000000..fd72fed --- /dev/null +++ b/PdfProcessing/Spread_AIConnectorDemo_NetStandard/Properties/launchSettings.json @@ -0,0 +1,7 @@ +{ + "profiles": { + "SpreadAIConnectorDemo": { + "commandName": "Project" + } + } +} \ No newline at end of file diff --git a/PdfProcessing/Spread_AIConnectorDemo_NetStandard/ReadMe.md b/PdfProcessing/Spread_AIConnectorDemo_NetStandard/ReadMe.md new file mode 100644 index 0000000..a482053 --- /dev/null +++ b/PdfProcessing/Spread_AIConnectorDemo_NetStandard/ReadMe.md @@ -0,0 +1,5 @@ +In order to run the project, you need to replace the key and endpoint with your Azure Open AI key and endpoint. +They are located in the launchSettings.json file in the Properties folder. + +In NetStandard you need to implement IEmbedder if you would like to use the PartialContextQuestionProcessor. +There is a sample implementation called CustomOpenAIEmbedder in the NetStandard project. \ No newline at end of file diff --git a/PdfProcessing/Spread_AIConnectorDemo_NetStandard/Spread_AIConnectorDemo_NetStandard.csproj b/PdfProcessing/Spread_AIConnectorDemo_NetStandard/Spread_AIConnectorDemo_NetStandard.csproj new file mode 100644 index 0000000..e0453d0 --- /dev/null +++ b/PdfProcessing/Spread_AIConnectorDemo_NetStandard/Spread_AIConnectorDemo_NetStandard.csproj @@ -0,0 +1,32 @@ + + + + Exe + net8.0 + enable + enable + + + + NETSTANDARD;$(DefineConstants) + + + + + + + + + + + + + + + + + PreserveNewest + + + + diff --git a/PdfProcessing/Spread_AIConnectorDemo_NetStandard/TextLoader.cs b/PdfProcessing/Spread_AIConnectorDemo_NetStandard/TextLoader.cs new file mode 100644 index 0000000..6ea49de --- /dev/null +++ b/PdfProcessing/Spread_AIConnectorDemo_NetStandard/TextLoader.cs @@ -0,0 +1,20 @@ +using LangChain.DocumentLoaders; + +namespace SpreadAIConnectorDemo +{ + internal class TextLoader : IDocumentLoader + { + public async Task> LoadAsync(DataSource dataSource, DocumentLoaderSettings? settings = null, CancellationToken cancellationToken = default) + { + using (Stream inputStream = await dataSource.GetStreamAsync(cancellationToken)) + { + StreamReader reader = new StreamReader(inputStream); + string content = reader.ReadToEnd(); + + string[] pages = content.Split(["----------"], System.StringSplitOptions.RemoveEmptyEntries); + + return pages.Select(x => new Document(x)).ToList(); + } + } + } +} \ No newline at end of file From 2e0cfcf993ff8075fa1e80112c43bb8e75e335a2 Mon Sep 17 00:00:00 2001 From: "PROGRESS\\ykaraman" Date: Fri, 21 Nov 2025 01:33:28 +0200 Subject: [PATCH 2/7] named repo folders correctly --- .../CustomOpenAIEmbedder.cs | 0 .../Flow_AIConnectorDemo_NetStandard.csproj | 0 ...GenAI Document Insights Test Document.docx | Bin .../Program.cs | 0 .../Properties/launchSettings.json | 0 .../ReadMe.md | 0 .../TextLoader.cs | 0 PdfProcessing/PdfProcessing_NetStandard.sln | 30 +++++++++--------- .../CustomOpenAIEmbedder.cs | 0 ...GenAI Document Insights Test Document.xlsx | Bin .../Program.cs | 0 .../Properties/launchSettings.json | 0 .../ReadMe.md | 0 .../Spread_AIConnectorDemo_NetStandard.csproj | 0 .../TextLoader.cs | 0 15 files changed, 15 insertions(+), 15 deletions(-) rename PdfProcessing/{Flow_AIConnectorDemo_NetStandard => Flow_AIConnectorDemo}/CustomOpenAIEmbedder.cs (100%) rename PdfProcessing/{Flow_AIConnectorDemo_NetStandard => Flow_AIConnectorDemo}/Flow_AIConnectorDemo_NetStandard.csproj (100%) rename PdfProcessing/{Flow_AIConnectorDemo_NetStandard => Flow_AIConnectorDemo}/GenAI Document Insights Test Document.docx (100%) rename PdfProcessing/{Flow_AIConnectorDemo_NetStandard => Flow_AIConnectorDemo}/Program.cs (100%) rename PdfProcessing/{Flow_AIConnectorDemo_NetStandard => Flow_AIConnectorDemo}/Properties/launchSettings.json (100%) rename PdfProcessing/{Flow_AIConnectorDemo_NetStandard => Flow_AIConnectorDemo}/ReadMe.md (100%) rename PdfProcessing/{Flow_AIConnectorDemo_NetStandard => Flow_AIConnectorDemo}/TextLoader.cs (100%) rename PdfProcessing/{Spread_AIConnectorDemo_NetStandard => Spread_AIConnectorDemo}/CustomOpenAIEmbedder.cs (100%) rename PdfProcessing/{Spread_AIConnectorDemo_NetStandard => Spread_AIConnectorDemo}/GenAI Document Insights Test Document.xlsx (100%) rename PdfProcessing/{Spread_AIConnectorDemo_NetStandard => Spread_AIConnectorDemo}/Program.cs (100%) rename PdfProcessing/{Spread_AIConnectorDemo_NetStandard => Spread_AIConnectorDemo}/Properties/launchSettings.json (100%) rename PdfProcessing/{Spread_AIConnectorDemo_NetStandard => Spread_AIConnectorDemo}/ReadMe.md (100%) rename PdfProcessing/{Spread_AIConnectorDemo_NetStandard => Spread_AIConnectorDemo}/Spread_AIConnectorDemo_NetStandard.csproj (100%) rename PdfProcessing/{Spread_AIConnectorDemo_NetStandard => Spread_AIConnectorDemo}/TextLoader.cs (100%) diff --git a/PdfProcessing/Flow_AIConnectorDemo_NetStandard/CustomOpenAIEmbedder.cs b/PdfProcessing/Flow_AIConnectorDemo/CustomOpenAIEmbedder.cs similarity index 100% rename from PdfProcessing/Flow_AIConnectorDemo_NetStandard/CustomOpenAIEmbedder.cs rename to PdfProcessing/Flow_AIConnectorDemo/CustomOpenAIEmbedder.cs diff --git a/PdfProcessing/Flow_AIConnectorDemo_NetStandard/Flow_AIConnectorDemo_NetStandard.csproj b/PdfProcessing/Flow_AIConnectorDemo/Flow_AIConnectorDemo_NetStandard.csproj similarity index 100% rename from PdfProcessing/Flow_AIConnectorDemo_NetStandard/Flow_AIConnectorDemo_NetStandard.csproj rename to PdfProcessing/Flow_AIConnectorDemo/Flow_AIConnectorDemo_NetStandard.csproj diff --git a/PdfProcessing/Flow_AIConnectorDemo_NetStandard/GenAI Document Insights Test Document.docx b/PdfProcessing/Flow_AIConnectorDemo/GenAI Document Insights Test Document.docx similarity index 100% rename from PdfProcessing/Flow_AIConnectorDemo_NetStandard/GenAI Document Insights Test Document.docx rename to PdfProcessing/Flow_AIConnectorDemo/GenAI Document Insights Test Document.docx diff --git a/PdfProcessing/Flow_AIConnectorDemo_NetStandard/Program.cs b/PdfProcessing/Flow_AIConnectorDemo/Program.cs similarity index 100% rename from PdfProcessing/Flow_AIConnectorDemo_NetStandard/Program.cs rename to PdfProcessing/Flow_AIConnectorDemo/Program.cs diff --git a/PdfProcessing/Flow_AIConnectorDemo_NetStandard/Properties/launchSettings.json b/PdfProcessing/Flow_AIConnectorDemo/Properties/launchSettings.json similarity index 100% rename from PdfProcessing/Flow_AIConnectorDemo_NetStandard/Properties/launchSettings.json rename to PdfProcessing/Flow_AIConnectorDemo/Properties/launchSettings.json diff --git a/PdfProcessing/Flow_AIConnectorDemo_NetStandard/ReadMe.md b/PdfProcessing/Flow_AIConnectorDemo/ReadMe.md similarity index 100% rename from PdfProcessing/Flow_AIConnectorDemo_NetStandard/ReadMe.md rename to PdfProcessing/Flow_AIConnectorDemo/ReadMe.md diff --git a/PdfProcessing/Flow_AIConnectorDemo_NetStandard/TextLoader.cs b/PdfProcessing/Flow_AIConnectorDemo/TextLoader.cs similarity index 100% rename from PdfProcessing/Flow_AIConnectorDemo_NetStandard/TextLoader.cs rename to PdfProcessing/Flow_AIConnectorDemo/TextLoader.cs diff --git a/PdfProcessing/PdfProcessing_NetStandard.sln b/PdfProcessing/PdfProcessing_NetStandard.sln index 0e45d9c..5de8fad 100644 --- a/PdfProcessing/PdfProcessing_NetStandard.sln +++ b/PdfProcessing/PdfProcessing_NetStandard.sln @@ -23,11 +23,11 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CustomJpegImageConverter_Ne EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AddWatermark_NetStandard", "AddWatermark\AddWatermark_NetStandard.csproj", "{5E7AB5A2-E716-4FEE-A30B-5E7167C94013}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Fixed_AIConnectorDemo_NetStandard", "AIConnectorDemo\Fixed_AIConnectorDemo_NetStandard.csproj", "{C948AB2A-A1D5-DE6C-0C36-8E9A4C475033}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Fixed_AIConnectorDemo_NetStandard", "Fixed_AIConnectorDemo\Fixed_AIConnectorDemo_NetStandard.csproj", "{5F819B2F-322F-F3D4-3494-20CE39228273}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Flow_AIConnectorDemo_NetStandard", "Flow_AIConnectorDemo_NetStandard\Flow_AIConnectorDemo_NetStandard.csproj", "{71148996-208F-4552-9827-51961F56BCF6}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Flow_AIConnectorDemo_NetStandard", "Flow_AIConnectorDemo\Flow_AIConnectorDemo_NetStandard.csproj", "{2E0CD20E-F441-B2D9-60B4-E6E98C7462E4}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Spread_AIConnectorDemo_NetStandard", "Spread_AIConnectorDemo_NetStandard\Spread_AIConnectorDemo_NetStandard.csproj", "{7BA0E7A5-AC38-4525-A9CF-BD471AD2ACB6}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Spread_AIConnectorDemo_NetStandard", "Spread_AIConnectorDemo\Spread_AIConnectorDemo_NetStandard.csproj", "{50E33269-2188-AB70-A6E2-43483832951B}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -75,18 +75,18 @@ Global {5E7AB5A2-E716-4FEE-A30B-5E7167C94013}.Debug|Any CPU.Build.0 = Debug|Any CPU {5E7AB5A2-E716-4FEE-A30B-5E7167C94013}.Release|Any CPU.ActiveCfg = Release|Any CPU {5E7AB5A2-E716-4FEE-A30B-5E7167C94013}.Release|Any CPU.Build.0 = Release|Any CPU - {C948AB2A-A1D5-DE6C-0C36-8E9A4C475033}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {C948AB2A-A1D5-DE6C-0C36-8E9A4C475033}.Debug|Any CPU.Build.0 = Debug|Any CPU - {C948AB2A-A1D5-DE6C-0C36-8E9A4C475033}.Release|Any CPU.ActiveCfg = Release|Any CPU - {C948AB2A-A1D5-DE6C-0C36-8E9A4C475033}.Release|Any CPU.Build.0 = Release|Any CPU - {71148996-208F-4552-9827-51961F56BCF6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {71148996-208F-4552-9827-51961F56BCF6}.Debug|Any CPU.Build.0 = Debug|Any CPU - {71148996-208F-4552-9827-51961F56BCF6}.Release|Any CPU.ActiveCfg = Release|Any CPU - {71148996-208F-4552-9827-51961F56BCF6}.Release|Any CPU.Build.0 = Release|Any CPU - {7BA0E7A5-AC38-4525-A9CF-BD471AD2ACB6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {7BA0E7A5-AC38-4525-A9CF-BD471AD2ACB6}.Debug|Any CPU.Build.0 = Debug|Any CPU - {7BA0E7A5-AC38-4525-A9CF-BD471AD2ACB6}.Release|Any CPU.ActiveCfg = Release|Any CPU - {7BA0E7A5-AC38-4525-A9CF-BD471AD2ACB6}.Release|Any CPU.Build.0 = Release|Any CPU + {5F819B2F-322F-F3D4-3494-20CE39228273}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5F819B2F-322F-F3D4-3494-20CE39228273}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5F819B2F-322F-F3D4-3494-20CE39228273}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5F819B2F-322F-F3D4-3494-20CE39228273}.Release|Any CPU.Build.0 = Release|Any CPU + {2E0CD20E-F441-B2D9-60B4-E6E98C7462E4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2E0CD20E-F441-B2D9-60B4-E6E98C7462E4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2E0CD20E-F441-B2D9-60B4-E6E98C7462E4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2E0CD20E-F441-B2D9-60B4-E6E98C7462E4}.Release|Any CPU.Build.0 = Release|Any CPU + {50E33269-2188-AB70-A6E2-43483832951B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {50E33269-2188-AB70-A6E2-43483832951B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {50E33269-2188-AB70-A6E2-43483832951B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {50E33269-2188-AB70-A6E2-43483832951B}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/PdfProcessing/Spread_AIConnectorDemo_NetStandard/CustomOpenAIEmbedder.cs b/PdfProcessing/Spread_AIConnectorDemo/CustomOpenAIEmbedder.cs similarity index 100% rename from PdfProcessing/Spread_AIConnectorDemo_NetStandard/CustomOpenAIEmbedder.cs rename to PdfProcessing/Spread_AIConnectorDemo/CustomOpenAIEmbedder.cs diff --git a/PdfProcessing/Spread_AIConnectorDemo_NetStandard/GenAI Document Insights Test Document.xlsx b/PdfProcessing/Spread_AIConnectorDemo/GenAI Document Insights Test Document.xlsx similarity index 100% rename from PdfProcessing/Spread_AIConnectorDemo_NetStandard/GenAI Document Insights Test Document.xlsx rename to PdfProcessing/Spread_AIConnectorDemo/GenAI Document Insights Test Document.xlsx diff --git a/PdfProcessing/Spread_AIConnectorDemo_NetStandard/Program.cs b/PdfProcessing/Spread_AIConnectorDemo/Program.cs similarity index 100% rename from PdfProcessing/Spread_AIConnectorDemo_NetStandard/Program.cs rename to PdfProcessing/Spread_AIConnectorDemo/Program.cs diff --git a/PdfProcessing/Spread_AIConnectorDemo_NetStandard/Properties/launchSettings.json b/PdfProcessing/Spread_AIConnectorDemo/Properties/launchSettings.json similarity index 100% rename from PdfProcessing/Spread_AIConnectorDemo_NetStandard/Properties/launchSettings.json rename to PdfProcessing/Spread_AIConnectorDemo/Properties/launchSettings.json diff --git a/PdfProcessing/Spread_AIConnectorDemo_NetStandard/ReadMe.md b/PdfProcessing/Spread_AIConnectorDemo/ReadMe.md similarity index 100% rename from PdfProcessing/Spread_AIConnectorDemo_NetStandard/ReadMe.md rename to PdfProcessing/Spread_AIConnectorDemo/ReadMe.md diff --git a/PdfProcessing/Spread_AIConnectorDemo_NetStandard/Spread_AIConnectorDemo_NetStandard.csproj b/PdfProcessing/Spread_AIConnectorDemo/Spread_AIConnectorDemo_NetStandard.csproj similarity index 100% rename from PdfProcessing/Spread_AIConnectorDemo_NetStandard/Spread_AIConnectorDemo_NetStandard.csproj rename to PdfProcessing/Spread_AIConnectorDemo/Spread_AIConnectorDemo_NetStandard.csproj diff --git a/PdfProcessing/Spread_AIConnectorDemo_NetStandard/TextLoader.cs b/PdfProcessing/Spread_AIConnectorDemo/TextLoader.cs similarity index 100% rename from PdfProcessing/Spread_AIConnectorDemo_NetStandard/TextLoader.cs rename to PdfProcessing/Spread_AIConnectorDemo/TextLoader.cs From 21427f528b7693e3cff38b136a7c840c28abd8d2 Mon Sep 17 00:00:00 2001 From: "PROGRESS\\ykaraman" Date: Fri, 21 Nov 2025 02:30:05 +0200 Subject: [PATCH 3/7] Added net8-windows projects --- .../CustomOpenAIEmbedder.cs | 3 +- ...mo.csproj => Fixed_AIConnectorDemo.csproj} | 6 ++-- .../Flow_AIConnectorDemo.csproj | 33 ++++++++++++++++++ PdfProcessing/PdfProcessing.sln | 22 +++++++++--- .../Spread_AIConnectorDemo/Program.cs | 15 ++++---- .../Spread_AIConnectorDemo.csproj | 34 +++++++++++++++++++ 6 files changed, 96 insertions(+), 17 deletions(-) rename PdfProcessing/Fixed_AIConnectorDemo/{AIConnectorDemo.csproj => Fixed_AIConnectorDemo.csproj} (89%) create mode 100644 PdfProcessing/Flow_AIConnectorDemo/Flow_AIConnectorDemo.csproj create mode 100644 PdfProcessing/Spread_AIConnectorDemo/Spread_AIConnectorDemo.csproj diff --git a/PdfProcessing/Fixed_AIConnectorDemo/CustomOpenAIEmbedder.cs b/PdfProcessing/Fixed_AIConnectorDemo/CustomOpenAIEmbedder.cs index dcd9d72..cecad5b 100644 --- a/PdfProcessing/Fixed_AIConnectorDemo/CustomOpenAIEmbedder.cs +++ b/PdfProcessing/Fixed_AIConnectorDemo/CustomOpenAIEmbedder.cs @@ -1,4 +1,5 @@ -using System.Net.Http.Headers; +using System.Net.Http; +using System.Net.Http.Headers; using System.Text; using System.Text.Json; using Telerik.Documents.AI.Core; diff --git a/PdfProcessing/Fixed_AIConnectorDemo/AIConnectorDemo.csproj b/PdfProcessing/Fixed_AIConnectorDemo/Fixed_AIConnectorDemo.csproj similarity index 89% rename from PdfProcessing/Fixed_AIConnectorDemo/AIConnectorDemo.csproj rename to PdfProcessing/Fixed_AIConnectorDemo/Fixed_AIConnectorDemo.csproj index e995d7e..464d370 100644 --- a/PdfProcessing/Fixed_AIConnectorDemo/AIConnectorDemo.csproj +++ b/PdfProcessing/Fixed_AIConnectorDemo/Fixed_AIConnectorDemo.csproj @@ -13,15 +13,15 @@ - + - - + + diff --git a/PdfProcessing/Flow_AIConnectorDemo/Flow_AIConnectorDemo.csproj b/PdfProcessing/Flow_AIConnectorDemo/Flow_AIConnectorDemo.csproj new file mode 100644 index 0000000..907c98d --- /dev/null +++ b/PdfProcessing/Flow_AIConnectorDemo/Flow_AIConnectorDemo.csproj @@ -0,0 +1,33 @@ + + + + Exe + net8.0-windows + enable + enable + true + + + + NETWINDOWS;$(DefineConstants) + + + + + + + + + + + + + + + + + PreserveNewest + + + + diff --git a/PdfProcessing/PdfProcessing.sln b/PdfProcessing/PdfProcessing.sln index 3dfd2d9..f4af97b 100644 --- a/PdfProcessing/PdfProcessing.sln +++ b/PdfProcessing/PdfProcessing.sln @@ -27,7 +27,11 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AddWatermark", "AddWatermar EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ModifyBookmarks_WPF", "ModifyBookmarks\ModifyBookmarks_WPF.csproj", "{BD58EF11-6552-4279-A341-0E200480A201}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AIConnectorDemo", "AIConnectorDemo\AIConnectorDemo.csproj", "{4AC38EDC-AE27-8F2B-5BCB-8E73F27E33F2}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Fixed_AIConnectorDemo", "Fixed_AIConnectorDemo\Fixed_AIConnectorDemo.csproj", "{5D32F058-450A-822F-2476-23B775CCED23}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Flow_AIConnectorDemo", "Flow_AIConnectorDemo\Flow_AIConnectorDemo.csproj", "{03305477-5A80-6218-2A86-B3150CBA94A3}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Spread_AIConnectorDemo", "Spread_AIConnectorDemo\Spread_AIConnectorDemo.csproj", "{420D0473-0D71-F5E1-13F3-3A4FC396CB38}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -83,10 +87,18 @@ Global {BD58EF11-6552-4279-A341-0E200480A201}.Debug|Any CPU.Build.0 = Debug|Any CPU {BD58EF11-6552-4279-A341-0E200480A201}.Release|Any CPU.ActiveCfg = Release|Any CPU {BD58EF11-6552-4279-A341-0E200480A201}.Release|Any CPU.Build.0 = Release|Any CPU - {4AC38EDC-AE27-8F2B-5BCB-8E73F27E33F2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {4AC38EDC-AE27-8F2B-5BCB-8E73F27E33F2}.Debug|Any CPU.Build.0 = Debug|Any CPU - {4AC38EDC-AE27-8F2B-5BCB-8E73F27E33F2}.Release|Any CPU.ActiveCfg = Release|Any CPU - {4AC38EDC-AE27-8F2B-5BCB-8E73F27E33F2}.Release|Any CPU.Build.0 = Release|Any CPU + {5D32F058-450A-822F-2476-23B775CCED23}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5D32F058-450A-822F-2476-23B775CCED23}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5D32F058-450A-822F-2476-23B775CCED23}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5D32F058-450A-822F-2476-23B775CCED23}.Release|Any CPU.Build.0 = Release|Any CPU + {03305477-5A80-6218-2A86-B3150CBA94A3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {03305477-5A80-6218-2A86-B3150CBA94A3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {03305477-5A80-6218-2A86-B3150CBA94A3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {03305477-5A80-6218-2A86-B3150CBA94A3}.Release|Any CPU.Build.0 = Release|Any CPU + {420D0473-0D71-F5E1-13F3-3A4FC396CB38}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {420D0473-0D71-F5E1-13F3-3A4FC396CB38}.Debug|Any CPU.Build.0 = Debug|Any CPU + {420D0473-0D71-F5E1-13F3-3A4FC396CB38}.Release|Any CPU.ActiveCfg = Release|Any CPU + {420D0473-0D71-F5E1-13F3-3A4FC396CB38}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/PdfProcessing/Spread_AIConnectorDemo/Program.cs b/PdfProcessing/Spread_AIConnectorDemo/Program.cs index 275781f..48f3f34 100644 --- a/PdfProcessing/Spread_AIConnectorDemo/Program.cs +++ b/PdfProcessing/Spread_AIConnectorDemo/Program.cs @@ -8,20 +8,19 @@ using Telerik.Windows.Documents.AIConnector; #else using Telerik.Documents.AIConnector; +#endif +using Telerik.Windows.Documents.TextRepresentation; using Telerik.Windows.Documents.Spreadsheet.FormatProviders.Json; using Telerik.Windows.Documents.Spreadsheet.FormatProviders.OpenXml.Xlsx; using Telerik.Windows.Documents.Spreadsheet.Model; - -#endif -using Telerik.Windows.Documents.TextRepresentation; - namespace SpreadAIConnectorDemo { internal class Program { static int maxTokenCount = 128000; - static int maxNumberOfEmbeddingsSent = 50000; + static int embeddingTokenSize = 60000; + static int totalContextTokenLimit = 60000; static IChatClient iChatClient; static string tokenizationEncoding = "cl100k_base"; static string model = "gpt-4o-mini"; @@ -86,7 +85,7 @@ private static void AskQuestion(SimpleTextDocument simpleDocument) CompleteContextProcessorSettings completeContextProcessorSettings = new CompleteContextProcessorSettings(maxTokenCount, model, tokenizationEncoding, false); CompleteContextQuestionProcessor completeContextQuestionProcessor = new CompleteContextQuestionProcessor(iChatClient, completeContextProcessorSettings); - string question = "How many pages is the document and what is it about?"; + string question = "What content does the document contain?"; string answer = completeContextQuestionProcessor.AnswerQuestion(simpleDocument, question).Result; Console.WriteLine(question); Console.WriteLine(answer); @@ -94,14 +93,14 @@ private static void AskQuestion(SimpleTextDocument simpleDocument) private static void AskPartialContextQuestion(SimpleTextDocument simpleDocument) { - var settings = EmbeddingSettingsFactory.CreateSettingsForTextDocuments(maxTokenCount, model, tokenizationEncoding, maxNumberOfEmbeddingsSent); + IEmbeddingSettings settings = EmbeddingSettingsFactory.CreateSettingsForSpreadDocuments(maxTokenCount, model, tokenizationEncoding, embeddingTokenSize, false, totalContextTokenLimit); #if NETWINDOWS PartialContextQuestionProcessor partialContextQuestionProcessor = new PartialContextQuestionProcessor(iChatClient, settings, simpleDocument); #else IEmbedder embedder = new CustomOpenAIEmbedder(); PartialContextQuestionProcessor partialContextQuestionProcessor = new PartialContextQuestionProcessor(iChatClient, embedder, settings, simpleDocument); #endif - string question = "Who are the key authors listed in the document?"; + string question = "What are the main conclusions of the document?"; string answer = partialContextQuestionProcessor.AnswerQuestion(question).Result; Console.WriteLine(question); Console.WriteLine(answer); diff --git a/PdfProcessing/Spread_AIConnectorDemo/Spread_AIConnectorDemo.csproj b/PdfProcessing/Spread_AIConnectorDemo/Spread_AIConnectorDemo.csproj new file mode 100644 index 0000000..3499864 --- /dev/null +++ b/PdfProcessing/Spread_AIConnectorDemo/Spread_AIConnectorDemo.csproj @@ -0,0 +1,34 @@ + + + + Exe + net8.0-windows + enable + enable + true + + + + NETWINDOWS;$(DefineConstants) + + + + + + + + + + + + + + + + + + PreserveNewest + + + + From 2c264285c53cd4a33869396379ae95fe4ac1259a Mon Sep 17 00:00:00 2001 From: "PROGRESS\\ykaraman" Date: Mon, 1 Dec 2025 15:18:23 +0200 Subject: [PATCH 4/7] removed Spread demo an polished Fixed and Flow demos --- .../AIConnectorDemo.csproj} | 0 .../AIConnectorDemo_NetStandard.csproj} | 0 .../CustomOpenAIEmbedder.cs | 0 .../John Grisham.pdf | Bin .../Program.cs | 2 - .../Properties/launchSettings.json | 11 ++ .../ReadMe.md | 0 .../TextLoader.cs | 0 .../Properties/launchSettings.json | 7 -- .../Properties/launchSettings.json | 7 -- PdfProcessing/PdfProcessing.sln | 16 +-- PdfProcessing/PdfProcessing_NetStandard.sln | 16 +-- .../CustomOpenAIEmbedder.cs | 98 ---------------- ...GenAI Document Insights Test Document.xlsx | Bin 10731 -> 0 bytes .../Spread_AIConnectorDemo/Program.cs | 109 ------------------ .../Properties/launchSettings.json | 7 -- .../Spread_AIConnectorDemo/ReadMe.md | 5 - .../Spread_AIConnectorDemo.csproj | 34 ------ .../Spread_AIConnectorDemo_NetStandard.csproj | 32 ----- .../Spread_AIConnectorDemo/TextLoader.cs | 20 ---- .../AIConnectorDemo/AIConnectorDemo.csproj | 0 .../AIConnectorDemo_NetStandard.csproj | 0 .../AIConnectorDemo}/CustomOpenAIEmbedder.cs | 0 ...GenAI Document Insights Test Document.docx | Bin .../AIConnectorDemo}/Program.cs | 2 - .../Properties/launchSettings.json | 11 ++ .../AIConnectorDemo}/ReadMe.md | 0 .../AIConnectorDemo}/TextLoader.cs | 0 WordsProcessing/WordsProcessing.sln | 31 ++--- .../WordsProcessing_NetStandard.sln | 31 ++--- 30 files changed, 48 insertions(+), 391 deletions(-) rename PdfProcessing/{Fixed_AIConnectorDemo/Fixed_AIConnectorDemo.csproj => AIConnectorDemo/AIConnectorDemo.csproj} (100%) rename PdfProcessing/{Fixed_AIConnectorDemo/Fixed_AIConnectorDemo_NetStandard.csproj => AIConnectorDemo/AIConnectorDemo_NetStandard.csproj} (100%) rename PdfProcessing/{Fixed_AIConnectorDemo => AIConnectorDemo}/CustomOpenAIEmbedder.cs (100%) rename PdfProcessing/{Fixed_AIConnectorDemo => AIConnectorDemo}/John Grisham.pdf (100%) rename PdfProcessing/{Fixed_AIConnectorDemo => AIConnectorDemo}/Program.cs (98%) create mode 100644 PdfProcessing/AIConnectorDemo/Properties/launchSettings.json rename PdfProcessing/{Fixed_AIConnectorDemo => AIConnectorDemo}/ReadMe.md (100%) rename PdfProcessing/{Fixed_AIConnectorDemo => AIConnectorDemo}/TextLoader.cs (100%) delete mode 100644 PdfProcessing/Fixed_AIConnectorDemo/Properties/launchSettings.json delete mode 100644 PdfProcessing/Flow_AIConnectorDemo/Properties/launchSettings.json delete mode 100644 PdfProcessing/Spread_AIConnectorDemo/CustomOpenAIEmbedder.cs delete mode 100644 PdfProcessing/Spread_AIConnectorDemo/GenAI Document Insights Test Document.xlsx delete mode 100644 PdfProcessing/Spread_AIConnectorDemo/Program.cs delete mode 100644 PdfProcessing/Spread_AIConnectorDemo/Properties/launchSettings.json delete mode 100644 PdfProcessing/Spread_AIConnectorDemo/ReadMe.md delete mode 100644 PdfProcessing/Spread_AIConnectorDemo/Spread_AIConnectorDemo.csproj delete mode 100644 PdfProcessing/Spread_AIConnectorDemo/Spread_AIConnectorDemo_NetStandard.csproj delete mode 100644 PdfProcessing/Spread_AIConnectorDemo/TextLoader.cs rename PdfProcessing/Flow_AIConnectorDemo/Flow_AIConnectorDemo.csproj => WordsProcessing/AIConnectorDemo/AIConnectorDemo.csproj (100%) rename PdfProcessing/Flow_AIConnectorDemo/Flow_AIConnectorDemo_NetStandard.csproj => WordsProcessing/AIConnectorDemo/AIConnectorDemo_NetStandard.csproj (100%) rename {PdfProcessing/Flow_AIConnectorDemo => WordsProcessing/AIConnectorDemo}/CustomOpenAIEmbedder.cs (100%) rename {PdfProcessing/Flow_AIConnectorDemo => WordsProcessing/AIConnectorDemo}/GenAI Document Insights Test Document.docx (100%) rename {PdfProcessing/Flow_AIConnectorDemo => WordsProcessing/AIConnectorDemo}/Program.cs (98%) create mode 100644 WordsProcessing/AIConnectorDemo/Properties/launchSettings.json rename {PdfProcessing/Flow_AIConnectorDemo => WordsProcessing/AIConnectorDemo}/ReadMe.md (100%) rename {PdfProcessing/Flow_AIConnectorDemo => WordsProcessing/AIConnectorDemo}/TextLoader.cs (100%) diff --git a/PdfProcessing/Fixed_AIConnectorDemo/Fixed_AIConnectorDemo.csproj b/PdfProcessing/AIConnectorDemo/AIConnectorDemo.csproj similarity index 100% rename from PdfProcessing/Fixed_AIConnectorDemo/Fixed_AIConnectorDemo.csproj rename to PdfProcessing/AIConnectorDemo/AIConnectorDemo.csproj diff --git a/PdfProcessing/Fixed_AIConnectorDemo/Fixed_AIConnectorDemo_NetStandard.csproj b/PdfProcessing/AIConnectorDemo/AIConnectorDemo_NetStandard.csproj similarity index 100% rename from PdfProcessing/Fixed_AIConnectorDemo/Fixed_AIConnectorDemo_NetStandard.csproj rename to PdfProcessing/AIConnectorDemo/AIConnectorDemo_NetStandard.csproj diff --git a/PdfProcessing/Fixed_AIConnectorDemo/CustomOpenAIEmbedder.cs b/PdfProcessing/AIConnectorDemo/CustomOpenAIEmbedder.cs similarity index 100% rename from PdfProcessing/Fixed_AIConnectorDemo/CustomOpenAIEmbedder.cs rename to PdfProcessing/AIConnectorDemo/CustomOpenAIEmbedder.cs diff --git a/PdfProcessing/Fixed_AIConnectorDemo/John Grisham.pdf b/PdfProcessing/AIConnectorDemo/John Grisham.pdf similarity index 100% rename from PdfProcessing/Fixed_AIConnectorDemo/John Grisham.pdf rename to PdfProcessing/AIConnectorDemo/John Grisham.pdf diff --git a/PdfProcessing/Fixed_AIConnectorDemo/Program.cs b/PdfProcessing/AIConnectorDemo/Program.cs similarity index 98% rename from PdfProcessing/Fixed_AIConnectorDemo/Program.cs rename to PdfProcessing/AIConnectorDemo/Program.cs index b25c5da..2eb1cfd 100644 --- a/PdfProcessing/Fixed_AIConnectorDemo/Program.cs +++ b/PdfProcessing/AIConnectorDemo/Program.cs @@ -27,8 +27,6 @@ internal class Program static void Main(string[] args) { - Console.WriteLine("Hello, World!"); - CreateChatClient(); using (Stream input = File.OpenRead("John Grisham.pdf")) diff --git a/PdfProcessing/AIConnectorDemo/Properties/launchSettings.json b/PdfProcessing/AIConnectorDemo/Properties/launchSettings.json new file mode 100644 index 0000000..896fece --- /dev/null +++ b/PdfProcessing/AIConnectorDemo/Properties/launchSettings.json @@ -0,0 +1,11 @@ +{ + "profiles": { + "AIConnectorDemo": { + "commandName": "Project", + "environmentVariables": { + "AZUREOPENAI_KEY": "key", + "AZUREOPENAI_ENDPOINT": "endpoint" + } + } + } +} \ No newline at end of file diff --git a/PdfProcessing/Fixed_AIConnectorDemo/ReadMe.md b/PdfProcessing/AIConnectorDemo/ReadMe.md similarity index 100% rename from PdfProcessing/Fixed_AIConnectorDemo/ReadMe.md rename to PdfProcessing/AIConnectorDemo/ReadMe.md diff --git a/PdfProcessing/Fixed_AIConnectorDemo/TextLoader.cs b/PdfProcessing/AIConnectorDemo/TextLoader.cs similarity index 100% rename from PdfProcessing/Fixed_AIConnectorDemo/TextLoader.cs rename to PdfProcessing/AIConnectorDemo/TextLoader.cs diff --git a/PdfProcessing/Fixed_AIConnectorDemo/Properties/launchSettings.json b/PdfProcessing/Fixed_AIConnectorDemo/Properties/launchSettings.json deleted file mode 100644 index 3fa9154..0000000 --- a/PdfProcessing/Fixed_AIConnectorDemo/Properties/launchSettings.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "profiles": { - "FixedAIConnectorDemo": { - "commandName": "Project" - } - } -} \ No newline at end of file diff --git a/PdfProcessing/Flow_AIConnectorDemo/Properties/launchSettings.json b/PdfProcessing/Flow_AIConnectorDemo/Properties/launchSettings.json deleted file mode 100644 index 8b63479..0000000 --- a/PdfProcessing/Flow_AIConnectorDemo/Properties/launchSettings.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "profiles": { - "FlowAIConnectorDemo": { - "commandName": "Project" - } - } -} \ No newline at end of file diff --git a/PdfProcessing/PdfProcessing.sln b/PdfProcessing/PdfProcessing.sln index f4af97b..60a6c44 100644 --- a/PdfProcessing/PdfProcessing.sln +++ b/PdfProcessing/PdfProcessing.sln @@ -27,11 +27,9 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AddWatermark", "AddWatermar EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ModifyBookmarks_WPF", "ModifyBookmarks\ModifyBookmarks_WPF.csproj", "{BD58EF11-6552-4279-A341-0E200480A201}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Fixed_AIConnectorDemo", "Fixed_AIConnectorDemo\Fixed_AIConnectorDemo.csproj", "{5D32F058-450A-822F-2476-23B775CCED23}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Flow_AIConnectorDemo", "Flow_AIConnectorDemo\Flow_AIConnectorDemo.csproj", "{03305477-5A80-6218-2A86-B3150CBA94A3}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Spread_AIConnectorDemo", "Spread_AIConnectorDemo\Spread_AIConnectorDemo.csproj", "{420D0473-0D71-F5E1-13F3-3A4FC396CB38}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AIConnectorDemo", "AIConnectorDemo\AIConnectorDemo.csproj", "{4AC38EDC-AE27-8F2B-5BCB-8E73F27E33F2}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -87,18 +85,14 @@ Global {BD58EF11-6552-4279-A341-0E200480A201}.Debug|Any CPU.Build.0 = Debug|Any CPU {BD58EF11-6552-4279-A341-0E200480A201}.Release|Any CPU.ActiveCfg = Release|Any CPU {BD58EF11-6552-4279-A341-0E200480A201}.Release|Any CPU.Build.0 = Release|Any CPU - {5D32F058-450A-822F-2476-23B775CCED23}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {5D32F058-450A-822F-2476-23B775CCED23}.Debug|Any CPU.Build.0 = Debug|Any CPU - {5D32F058-450A-822F-2476-23B775CCED23}.Release|Any CPU.ActiveCfg = Release|Any CPU - {5D32F058-450A-822F-2476-23B775CCED23}.Release|Any CPU.Build.0 = Release|Any CPU {03305477-5A80-6218-2A86-B3150CBA94A3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {03305477-5A80-6218-2A86-B3150CBA94A3}.Debug|Any CPU.Build.0 = Debug|Any CPU {03305477-5A80-6218-2A86-B3150CBA94A3}.Release|Any CPU.ActiveCfg = Release|Any CPU {03305477-5A80-6218-2A86-B3150CBA94A3}.Release|Any CPU.Build.0 = Release|Any CPU - {420D0473-0D71-F5E1-13F3-3A4FC396CB38}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {420D0473-0D71-F5E1-13F3-3A4FC396CB38}.Debug|Any CPU.Build.0 = Debug|Any CPU - {420D0473-0D71-F5E1-13F3-3A4FC396CB38}.Release|Any CPU.ActiveCfg = Release|Any CPU - {420D0473-0D71-F5E1-13F3-3A4FC396CB38}.Release|Any CPU.Build.0 = Release|Any CPU + {4AC38EDC-AE27-8F2B-5BCB-8E73F27E33F2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4AC38EDC-AE27-8F2B-5BCB-8E73F27E33F2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4AC38EDC-AE27-8F2B-5BCB-8E73F27E33F2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4AC38EDC-AE27-8F2B-5BCB-8E73F27E33F2}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/PdfProcessing/PdfProcessing_NetStandard.sln b/PdfProcessing/PdfProcessing_NetStandard.sln index 5de8fad..07c74eb 100644 --- a/PdfProcessing/PdfProcessing_NetStandard.sln +++ b/PdfProcessing/PdfProcessing_NetStandard.sln @@ -23,11 +23,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CustomJpegImageConverter_Ne EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AddWatermark_NetStandard", "AddWatermark\AddWatermark_NetStandard.csproj", "{5E7AB5A2-E716-4FEE-A30B-5E7167C94013}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Fixed_AIConnectorDemo_NetStandard", "Fixed_AIConnectorDemo\Fixed_AIConnectorDemo_NetStandard.csproj", "{5F819B2F-322F-F3D4-3494-20CE39228273}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Flow_AIConnectorDemo_NetStandard", "Flow_AIConnectorDemo\Flow_AIConnectorDemo_NetStandard.csproj", "{2E0CD20E-F441-B2D9-60B4-E6E98C7462E4}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Spread_AIConnectorDemo_NetStandard", "Spread_AIConnectorDemo\Spread_AIConnectorDemo_NetStandard.csproj", "{50E33269-2188-AB70-A6E2-43483832951B}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AIConnectorDemo_NetStandard", "AIConnectorDemo\AIConnectorDemo_NetStandard.csproj", "{C948AB2A-A1D5-DE6C-0C36-8E9A4C475033}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -75,18 +73,14 @@ Global {5E7AB5A2-E716-4FEE-A30B-5E7167C94013}.Debug|Any CPU.Build.0 = Debug|Any CPU {5E7AB5A2-E716-4FEE-A30B-5E7167C94013}.Release|Any CPU.ActiveCfg = Release|Any CPU {5E7AB5A2-E716-4FEE-A30B-5E7167C94013}.Release|Any CPU.Build.0 = Release|Any CPU - {5F819B2F-322F-F3D4-3494-20CE39228273}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {5F819B2F-322F-F3D4-3494-20CE39228273}.Debug|Any CPU.Build.0 = Debug|Any CPU - {5F819B2F-322F-F3D4-3494-20CE39228273}.Release|Any CPU.ActiveCfg = Release|Any CPU - {5F819B2F-322F-F3D4-3494-20CE39228273}.Release|Any CPU.Build.0 = Release|Any CPU {2E0CD20E-F441-B2D9-60B4-E6E98C7462E4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {2E0CD20E-F441-B2D9-60B4-E6E98C7462E4}.Debug|Any CPU.Build.0 = Debug|Any CPU {2E0CD20E-F441-B2D9-60B4-E6E98C7462E4}.Release|Any CPU.ActiveCfg = Release|Any CPU {2E0CD20E-F441-B2D9-60B4-E6E98C7462E4}.Release|Any CPU.Build.0 = Release|Any CPU - {50E33269-2188-AB70-A6E2-43483832951B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {50E33269-2188-AB70-A6E2-43483832951B}.Debug|Any CPU.Build.0 = Debug|Any CPU - {50E33269-2188-AB70-A6E2-43483832951B}.Release|Any CPU.ActiveCfg = Release|Any CPU - {50E33269-2188-AB70-A6E2-43483832951B}.Release|Any CPU.Build.0 = Release|Any CPU + {C948AB2A-A1D5-DE6C-0C36-8E9A4C475033}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C948AB2A-A1D5-DE6C-0C36-8E9A4C475033}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C948AB2A-A1D5-DE6C-0C36-8E9A4C475033}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C948AB2A-A1D5-DE6C-0C36-8E9A4C475033}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/PdfProcessing/Spread_AIConnectorDemo/CustomOpenAIEmbedder.cs b/PdfProcessing/Spread_AIConnectorDemo/CustomOpenAIEmbedder.cs deleted file mode 100644 index 2e8f187..0000000 --- a/PdfProcessing/Spread_AIConnectorDemo/CustomOpenAIEmbedder.cs +++ /dev/null @@ -1,98 +0,0 @@ -using System.Net.Http.Headers; -using System.Text; -using System.Text.Json; -using Telerik.Documents.AI.Core; - -namespace SpreadAIConnectorDemo -{ - public class CustomOpenAIEmbedder : IEmbedder - { - private readonly HttpClient httpClient; - - public CustomOpenAIEmbedder() - { - HttpClient httpClient = new HttpClient(); - httpClient.Timeout = TimeSpan.FromMinutes(5); - string endpoint = Environment.GetEnvironmentVariable("AZUREEMBEDDINGOPENAI_ENDPOINT"); - string apiKey = Environment.GetEnvironmentVariable("AZUREEMBEDDINGOPENAI_KEY"); - - httpClient.BaseAddress = new Uri(endpoint); - httpClient.DefaultRequestHeaders.Add("api-key", apiKey); - httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); - - this.httpClient = httpClient; - } - - public async Task> EmbedAsync(IList fragments) - { - AzureEmbeddingsRequest requestBody = new AzureEmbeddingsRequest - { - Input = fragments.Select(p => p.ToEmbeddingText()).ToArray(), - Dimensions = 3072 - }; - - string json = JsonSerializer.Serialize(requestBody); - StringContent content = new StringContent(json, Encoding.UTF8, "application/json"); - - string apiVersion = Environment.GetEnvironmentVariable("AZUREEMBEDDINGOPENAI_APIVERSION"); - string deploymentName = Environment.GetEnvironmentVariable("AZUREEMBEDDINGOPENAI_DEPLOYMENT"); - string url = $"openai/deployments/{deploymentName}/embeddings?api-version={apiVersion}"; - using HttpResponseMessage response = await this.httpClient.PostAsync(url, content, CancellationToken.None); - - Embedding[] embeddings = new Embedding[fragments.Count]; - - string responseJson = await response.Content.ReadAsStringAsync(CancellationToken.None); - AzureEmbeddingsResponse responseObj = JsonSerializer.Deserialize(responseJson); - - List sorted = responseObj.Data.OrderBy(d => d.Index).ToList(); - List result = new List(sorted.Count); - - for (int i = 0; i < sorted.Count; i++) - { - EmbeddingData item = sorted[i]; - embeddings[i] = new Embedding(fragments[i], item.Embedding); - } - - return embeddings; - } - - private sealed class AzureEmbeddingsRequest - { - [System.Text.Json.Serialization.JsonPropertyName("input")] - public string[] Input { get; set; } = Array.Empty(); - - [System.Text.Json.Serialization.JsonPropertyName("dimensions")] - public int? Dimensions { get; set; } - } - - private sealed class AzureEmbeddingsResponse - { - [System.Text.Json.Serialization.JsonPropertyName("data")] - public EmbeddingData[] Data { get; set; } = Array.Empty(); - - [System.Text.Json.Serialization.JsonPropertyName("model")] - public string? Model { get; set; } - - [System.Text.Json.Serialization.JsonPropertyName("usage")] - public UsageInfo? Usage { get; set; } - } - - private sealed class UsageInfo - { - [System.Text.Json.Serialization.JsonPropertyName("prompt_tokens")] - public int PromptTokens { get; set; } - - [System.Text.Json.Serialization.JsonPropertyName("total_tokens")] - public int TotalTokens { get; set; } - } - - private sealed class EmbeddingData - { - [System.Text.Json.Serialization.JsonPropertyName("embedding")] - public float[] Embedding { get; set; } = Array.Empty(); - - [System.Text.Json.Serialization.JsonPropertyName("index")] - public int Index { get; set; } - } - } -} \ No newline at end of file diff --git a/PdfProcessing/Spread_AIConnectorDemo/GenAI Document Insights Test Document.xlsx b/PdfProcessing/Spread_AIConnectorDemo/GenAI Document Insights Test Document.xlsx deleted file mode 100644 index 6cc70859cffcab7b2d216c32f9a3c4e72dcff608..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10731 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 diff --git a/PdfProcessing/Spread_AIConnectorDemo/Program.cs b/PdfProcessing/Spread_AIConnectorDemo/Program.cs deleted file mode 100644 index 48f3f34..0000000 --- a/PdfProcessing/Spread_AIConnectorDemo/Program.cs +++ /dev/null @@ -1,109 +0,0 @@ -using Azure.AI.OpenAI; -using Microsoft.Extensions.AI; -using OpenAI.Chat; -using System.IO; -using Telerik.Documents.AI.Core; - -#if NETWINDOWS -using Telerik.Windows.Documents.AIConnector; -#else -using Telerik.Documents.AIConnector; -#endif -using Telerik.Windows.Documents.TextRepresentation; -using Telerik.Windows.Documents.Spreadsheet.FormatProviders.Json; -using Telerik.Windows.Documents.Spreadsheet.FormatProviders.OpenXml.Xlsx; -using Telerik.Windows.Documents.Spreadsheet.Model; - -namespace SpreadAIConnectorDemo -{ - internal class Program - { - static int maxTokenCount = 128000; - static int embeddingTokenSize = 60000; - static int totalContextTokenLimit = 60000; - static IChatClient iChatClient; - static string tokenizationEncoding = "cl100k_base"; - static string model = "gpt-4o-mini"; - static string key = Environment.GetEnvironmentVariable("AZUREOPENAI_KEY"); - static string endpoint = Environment.GetEnvironmentVariable("AZUREOPENAI_ENDPOINT"); - - static void Main(string[] args) - { - Console.WriteLine("Hello, World!"); - - CreateChatClient(); - - using (Stream input = File.OpenRead("GenAI Document Insights Test Document.xlsx")) - { - XlsxFormatProvider xlsxFormatProvider = new XlsxFormatProvider(); - Workbook inputXlsx = xlsxFormatProvider.Import(input, null); - SimpleTextDocument simpleDocument = inputXlsx.ToSimpleTextDocument(TimeSpan.FromSeconds(10)); - - Summarize(simpleDocument); - - Console.WriteLine("--------------------------------------------------"); - - AskQuestion(simpleDocument); - - Console.WriteLine("--------------------------------------------------"); - - AskPartialContextQuestion(simpleDocument); - } - } - - private static void CreateChatClient() - { - AzureOpenAIClient azureClient = new( - new Uri(endpoint), - new Azure.AzureKeyCredential(key), - new AzureOpenAIClientOptions()); - ChatClient chatClient = azureClient.GetChatClient(model); - - iChatClient = new OpenAIChatClient(chatClient); - } - - private static void Summarize(SimpleTextDocument simpleDocument) - { - string additionalPrompt = "Summarize the text in a few sentences. Be concise and clear."; - SummarizationProcessorSettings summarizationProcessorSettings = new SummarizationProcessorSettings(maxTokenCount, additionalPrompt); - SummarizationProcessor summarizationProcessor = new SummarizationProcessor(iChatClient, summarizationProcessorSettings); - - summarizationProcessor.SummaryResourcesCalculated += SummarizationProcessor_SummaryResourcesCalculated; - - string summary = summarizationProcessor.Summarize(simpleDocument).Result; - Console.WriteLine(summary); - } - - private static void SummarizationProcessor_SummaryResourcesCalculated(object? sender, SummaryResourcesCalculatedEventArgs e) - { - Console.WriteLine($"The summary will require {e.EstimatedCallsRequired} calls and {e.EstimatedTokensRequired} tokens"); - e.ShouldContinueExecution = true; - } - - private static void AskQuestion(SimpleTextDocument simpleDocument) - { - CompleteContextProcessorSettings completeContextProcessorSettings = new CompleteContextProcessorSettings(maxTokenCount, model, tokenizationEncoding, false); - CompleteContextQuestionProcessor completeContextQuestionProcessor = new CompleteContextQuestionProcessor(iChatClient, completeContextProcessorSettings); - - string question = "What content does the document contain?"; - string answer = completeContextQuestionProcessor.AnswerQuestion(simpleDocument, question).Result; - Console.WriteLine(question); - Console.WriteLine(answer); - } - - private static void AskPartialContextQuestion(SimpleTextDocument simpleDocument) - { - IEmbeddingSettings settings = EmbeddingSettingsFactory.CreateSettingsForSpreadDocuments(maxTokenCount, model, tokenizationEncoding, embeddingTokenSize, false, totalContextTokenLimit); -#if NETWINDOWS - PartialContextQuestionProcessor partialContextQuestionProcessor = new PartialContextQuestionProcessor(iChatClient, settings, simpleDocument); -#else - IEmbedder embedder = new CustomOpenAIEmbedder(); - PartialContextQuestionProcessor partialContextQuestionProcessor = new PartialContextQuestionProcessor(iChatClient, embedder, settings, simpleDocument); -#endif - string question = "What are the main conclusions of the document?"; - string answer = partialContextQuestionProcessor.AnswerQuestion(question).Result; - Console.WriteLine(question); - Console.WriteLine(answer); - } - } -} diff --git a/PdfProcessing/Spread_AIConnectorDemo/Properties/launchSettings.json b/PdfProcessing/Spread_AIConnectorDemo/Properties/launchSettings.json deleted file mode 100644 index fd72fed..0000000 --- a/PdfProcessing/Spread_AIConnectorDemo/Properties/launchSettings.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "profiles": { - "SpreadAIConnectorDemo": { - "commandName": "Project" - } - } -} \ No newline at end of file diff --git a/PdfProcessing/Spread_AIConnectorDemo/ReadMe.md b/PdfProcessing/Spread_AIConnectorDemo/ReadMe.md deleted file mode 100644 index a482053..0000000 --- a/PdfProcessing/Spread_AIConnectorDemo/ReadMe.md +++ /dev/null @@ -1,5 +0,0 @@ -In order to run the project, you need to replace the key and endpoint with your Azure Open AI key and endpoint. -They are located in the launchSettings.json file in the Properties folder. - -In NetStandard you need to implement IEmbedder if you would like to use the PartialContextQuestionProcessor. -There is a sample implementation called CustomOpenAIEmbedder in the NetStandard project. \ No newline at end of file diff --git a/PdfProcessing/Spread_AIConnectorDemo/Spread_AIConnectorDemo.csproj b/PdfProcessing/Spread_AIConnectorDemo/Spread_AIConnectorDemo.csproj deleted file mode 100644 index 3499864..0000000 --- a/PdfProcessing/Spread_AIConnectorDemo/Spread_AIConnectorDemo.csproj +++ /dev/null @@ -1,34 +0,0 @@ - - - - Exe - net8.0-windows - enable - enable - true - - - - NETWINDOWS;$(DefineConstants) - - - - - - - - - - - - - - - - - - PreserveNewest - - - - diff --git a/PdfProcessing/Spread_AIConnectorDemo/Spread_AIConnectorDemo_NetStandard.csproj b/PdfProcessing/Spread_AIConnectorDemo/Spread_AIConnectorDemo_NetStandard.csproj deleted file mode 100644 index e0453d0..0000000 --- a/PdfProcessing/Spread_AIConnectorDemo/Spread_AIConnectorDemo_NetStandard.csproj +++ /dev/null @@ -1,32 +0,0 @@ - - - - Exe - net8.0 - enable - enable - - - - NETSTANDARD;$(DefineConstants) - - - - - - - - - - - - - - - - - PreserveNewest - - - - diff --git a/PdfProcessing/Spread_AIConnectorDemo/TextLoader.cs b/PdfProcessing/Spread_AIConnectorDemo/TextLoader.cs deleted file mode 100644 index 6ea49de..0000000 --- a/PdfProcessing/Spread_AIConnectorDemo/TextLoader.cs +++ /dev/null @@ -1,20 +0,0 @@ -using LangChain.DocumentLoaders; - -namespace SpreadAIConnectorDemo -{ - internal class TextLoader : IDocumentLoader - { - public async Task> LoadAsync(DataSource dataSource, DocumentLoaderSettings? settings = null, CancellationToken cancellationToken = default) - { - using (Stream inputStream = await dataSource.GetStreamAsync(cancellationToken)) - { - StreamReader reader = new StreamReader(inputStream); - string content = reader.ReadToEnd(); - - string[] pages = content.Split(["----------"], System.StringSplitOptions.RemoveEmptyEntries); - - return pages.Select(x => new Document(x)).ToList(); - } - } - } -} \ No newline at end of file diff --git a/PdfProcessing/Flow_AIConnectorDemo/Flow_AIConnectorDemo.csproj b/WordsProcessing/AIConnectorDemo/AIConnectorDemo.csproj similarity index 100% rename from PdfProcessing/Flow_AIConnectorDemo/Flow_AIConnectorDemo.csproj rename to WordsProcessing/AIConnectorDemo/AIConnectorDemo.csproj diff --git a/PdfProcessing/Flow_AIConnectorDemo/Flow_AIConnectorDemo_NetStandard.csproj b/WordsProcessing/AIConnectorDemo/AIConnectorDemo_NetStandard.csproj similarity index 100% rename from PdfProcessing/Flow_AIConnectorDemo/Flow_AIConnectorDemo_NetStandard.csproj rename to WordsProcessing/AIConnectorDemo/AIConnectorDemo_NetStandard.csproj diff --git a/PdfProcessing/Flow_AIConnectorDemo/CustomOpenAIEmbedder.cs b/WordsProcessing/AIConnectorDemo/CustomOpenAIEmbedder.cs similarity index 100% rename from PdfProcessing/Flow_AIConnectorDemo/CustomOpenAIEmbedder.cs rename to WordsProcessing/AIConnectorDemo/CustomOpenAIEmbedder.cs diff --git a/PdfProcessing/Flow_AIConnectorDemo/GenAI Document Insights Test Document.docx b/WordsProcessing/AIConnectorDemo/GenAI Document Insights Test Document.docx similarity index 100% rename from PdfProcessing/Flow_AIConnectorDemo/GenAI Document Insights Test Document.docx rename to WordsProcessing/AIConnectorDemo/GenAI Document Insights Test Document.docx diff --git a/PdfProcessing/Flow_AIConnectorDemo/Program.cs b/WordsProcessing/AIConnectorDemo/Program.cs similarity index 98% rename from PdfProcessing/Flow_AIConnectorDemo/Program.cs rename to WordsProcessing/AIConnectorDemo/Program.cs index c8654fa..cde4fb7 100644 --- a/PdfProcessing/Flow_AIConnectorDemo/Program.cs +++ b/WordsProcessing/AIConnectorDemo/Program.cs @@ -27,8 +27,6 @@ internal class Program static void Main(string[] args) { - Console.WriteLine("Hello, World!"); - CreateChatClient(); using (Stream input = File.OpenRead("GenAI Document Insights Test Document.docx")) diff --git a/WordsProcessing/AIConnectorDemo/Properties/launchSettings.json b/WordsProcessing/AIConnectorDemo/Properties/launchSettings.json new file mode 100644 index 0000000..896fece --- /dev/null +++ b/WordsProcessing/AIConnectorDemo/Properties/launchSettings.json @@ -0,0 +1,11 @@ +{ + "profiles": { + "AIConnectorDemo": { + "commandName": "Project", + "environmentVariables": { + "AZUREOPENAI_KEY": "key", + "AZUREOPENAI_ENDPOINT": "endpoint" + } + } + } +} \ No newline at end of file diff --git a/PdfProcessing/Flow_AIConnectorDemo/ReadMe.md b/WordsProcessing/AIConnectorDemo/ReadMe.md similarity index 100% rename from PdfProcessing/Flow_AIConnectorDemo/ReadMe.md rename to WordsProcessing/AIConnectorDemo/ReadMe.md diff --git a/PdfProcessing/Flow_AIConnectorDemo/TextLoader.cs b/WordsProcessing/AIConnectorDemo/TextLoader.cs similarity index 100% rename from PdfProcessing/Flow_AIConnectorDemo/TextLoader.cs rename to WordsProcessing/AIConnectorDemo/TextLoader.cs diff --git a/WordsProcessing/WordsProcessing.sln b/WordsProcessing/WordsProcessing.sln index 3f097cf..46f2a64 100644 --- a/WordsProcessing/WordsProcessing.sln +++ b/WordsProcessing/WordsProcessing.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.26923.0 +# Visual Studio Version 17 +VisualStudioVersion = 17.14.36603.0 d17.14 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GenerateDocument", "GenerateDocument\GenerateDocument.csproj", "{6BD0AD6A-35D5-4194-9C8A-438E27942792}" EndProject @@ -13,6 +13,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConvertDocuments", "Convert EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ContentControls", "ContentControls\ContentControls.csproj", "{576D340B-8809-4256-809C-575B1907283C}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AIConnectorDemo", "AIConnectorDemo\AIConnectorDemo.csproj", "{4AC38EDC-AE27-8F2B-5BCB-8E73F27E33F2}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -39,6 +41,10 @@ Global {576D340B-8809-4256-809C-575B1907283C}.Debug|Any CPU.Build.0 = Debug|Any CPU {576D340B-8809-4256-809C-575B1907283C}.Release|Any CPU.ActiveCfg = Release|Any CPU {576D340B-8809-4256-809C-575B1907283C}.Release|Any CPU.Build.0 = Release|Any CPU + {4AC38EDC-AE27-8F2B-5BCB-8E73F27E33F2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4AC38EDC-AE27-8F2B-5BCB-8E73F27E33F2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4AC38EDC-AE27-8F2B-5BCB-8E73F27E33F2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4AC38EDC-AE27-8F2B-5BCB-8E73F27E33F2}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -46,25 +52,4 @@ Global GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {74049E11-3060-446D-BA19-C820938235B3} EndGlobalSection - GlobalSection(TeamFoundationVersionControl) = preSolution - SccNumberOfProjects = 6 - SccEnterpriseProvider = {4CA58AB2-18FA-4F8D-95D4-32DDF27D184C} - SccTeamFoundationServer = https://tfsemea.progress.com/defaultcollection - SccLocalPath0 = . - SccProjectUniqueName1 = GenerateDocument\\GenerateDocument.csproj - SccProjectName1 = GenerateDocument - SccLocalPath1 = GenerateDocument - SccProjectUniqueName2 = HtmlGenerator\\HtmlGenerator.csproj - SccProjectName2 = HtmlGenerator - SccLocalPath2 = HtmlGenerator - SccProjectUniqueName3 = MailMerge\\MailMerge.csproj - SccProjectName3 = MailMerge - SccLocalPath3 = MailMerge - SccProjectUniqueName4 = ConvertDocuments\\ConvertDocuments.csproj - SccProjectName4 = ConvertDocuments - SccLocalPath4 = ConvertDocuments - SccProjectUniqueName5 = ContentControls\\ContentControls.csproj - SccProjectName5 = ContentControls - SccLocalPath5 = ContentControls - EndGlobalSection EndGlobal diff --git a/WordsProcessing/WordsProcessing_NetStandard.sln b/WordsProcessing/WordsProcessing_NetStandard.sln index 640c8f5..9b9d759 100644 --- a/WordsProcessing/WordsProcessing_NetStandard.sln +++ b/WordsProcessing/WordsProcessing_NetStandard.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.29709.97 +# Visual Studio Version 17 +VisualStudioVersion = 17.14.36603.0 d17.14 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConvertDocuments_NetStandard", "ConvertDocuments\ConvertDocuments_NetStandard.csproj", "{AF2C14E7-B3FD-4B1B-8B49-148B63BC7F3D}" EndProject @@ -13,6 +13,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MailMerge_NetStandard", "Ma EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ContentControls_NetStandard", "ContentControls\ContentControls_NetStandard.csproj", "{0E6E81DD-BD06-4FDA-8B68-0AA4E8865F30}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AIConnectorDemo_NetStandard", "AIConnectorDemo\AIConnectorDemo_NetStandard.csproj", "{C948AB2A-A1D5-DE6C-0C36-8E9A4C475033}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -39,6 +41,10 @@ Global {0E6E81DD-BD06-4FDA-8B68-0AA4E8865F30}.Debug|Any CPU.Build.0 = Debug|Any CPU {0E6E81DD-BD06-4FDA-8B68-0AA4E8865F30}.Release|Any CPU.ActiveCfg = Release|Any CPU {0E6E81DD-BD06-4FDA-8B68-0AA4E8865F30}.Release|Any CPU.Build.0 = Release|Any CPU + {C948AB2A-A1D5-DE6C-0C36-8E9A4C475033}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C948AB2A-A1D5-DE6C-0C36-8E9A4C475033}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C948AB2A-A1D5-DE6C-0C36-8E9A4C475033}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C948AB2A-A1D5-DE6C-0C36-8E9A4C475033}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -46,25 +52,4 @@ Global GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {D254DCB0-A6CA-4F77-8A49-131BA4359514} EndGlobalSection - GlobalSection(TeamFoundationVersionControl) = preSolution - SccNumberOfProjects = 6 - SccEnterpriseProvider = {4CA58AB2-18FA-4F8D-95D4-32DDF27D184C} - SccTeamFoundationServer = https://tfsemea.progress.com/defaultcollection - SccLocalPath0 = . - SccProjectUniqueName1 = ConvertDocuments\\ConvertDocuments_NetStandard.csproj - SccProjectName1 = ConvertDocuments - SccLocalPath1 = ConvertDocuments - SccProjectUniqueName2 = GenerateDocument\\GenerateDocument_NetStandard.csproj - SccProjectName2 = GenerateDocument - SccLocalPath2 = GenerateDocument - SccProjectUniqueName3 = HtmlGenerator\\HtmlGenerator_NetStandard.csproj - SccProjectName3 = HtmlGenerator - SccLocalPath3 = HtmlGenerator - SccProjectUniqueName4 = MailMerge\\MailMerge_NetStandard.csproj - SccProjectName4 = MailMerge - SccLocalPath4 = MailMerge - SccProjectUniqueName5 = ContentControls\\ContentControls_NetStandard.csproj - SccProjectName5 = ContentControls - SccLocalPath5 = ContentControls - EndGlobalSection EndGlobal From 7ff9a35efab25d89b0122d9a7de7f17abcee946a Mon Sep 17 00:00:00 2001 From: "PROGRESS\\ykaraman" Date: Mon, 1 Dec 2025 15:23:35 +0200 Subject: [PATCH 5/7] FIxed namespaces --- PdfProcessing/AIConnectorDemo/CustomOpenAIEmbedder.cs | 2 +- PdfProcessing/AIConnectorDemo/Program.cs | 2 +- PdfProcessing/AIConnectorDemo/TextLoader.cs | 2 +- PdfProcessing/PdfProcessing.sln | 6 ------ PdfProcessing/PdfProcessing_NetStandard.sln | 6 ------ WordsProcessing/AIConnectorDemo/CustomOpenAIEmbedder.cs | 2 +- WordsProcessing/AIConnectorDemo/Program.cs | 2 +- WordsProcessing/AIConnectorDemo/TextLoader.cs | 2 +- 8 files changed, 6 insertions(+), 18 deletions(-) diff --git a/PdfProcessing/AIConnectorDemo/CustomOpenAIEmbedder.cs b/PdfProcessing/AIConnectorDemo/CustomOpenAIEmbedder.cs index cecad5b..c3b8669 100644 --- a/PdfProcessing/AIConnectorDemo/CustomOpenAIEmbedder.cs +++ b/PdfProcessing/AIConnectorDemo/CustomOpenAIEmbedder.cs @@ -4,7 +4,7 @@ using System.Text.Json; using Telerik.Documents.AI.Core; -namespace FixedAIConnectorDemo +namespace AIConnectorDemo { public class CustomOpenAIEmbedder : IEmbedder { diff --git a/PdfProcessing/AIConnectorDemo/Program.cs b/PdfProcessing/AIConnectorDemo/Program.cs index 2eb1cfd..33e93be 100644 --- a/PdfProcessing/AIConnectorDemo/Program.cs +++ b/PdfProcessing/AIConnectorDemo/Program.cs @@ -13,7 +13,7 @@ using Telerik.Windows.Documents.Fixed.Model; using Telerik.Windows.Documents.TextRepresentation; -namespace FixedAIConnectorDemo +namespace AIConnectorDemo { internal class Program { diff --git a/PdfProcessing/AIConnectorDemo/TextLoader.cs b/PdfProcessing/AIConnectorDemo/TextLoader.cs index 816dd93..ad8732b 100644 --- a/PdfProcessing/AIConnectorDemo/TextLoader.cs +++ b/PdfProcessing/AIConnectorDemo/TextLoader.cs @@ -1,6 +1,6 @@ using LangChain.DocumentLoaders; -namespace FixedAIConnectorDemo +namespace AIConnectorDemo { internal class TextLoader : IDocumentLoader { diff --git a/PdfProcessing/PdfProcessing.sln b/PdfProcessing/PdfProcessing.sln index 60a6c44..3dfd2d9 100644 --- a/PdfProcessing/PdfProcessing.sln +++ b/PdfProcessing/PdfProcessing.sln @@ -27,8 +27,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AddWatermark", "AddWatermar EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ModifyBookmarks_WPF", "ModifyBookmarks\ModifyBookmarks_WPF.csproj", "{BD58EF11-6552-4279-A341-0E200480A201}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Flow_AIConnectorDemo", "Flow_AIConnectorDemo\Flow_AIConnectorDemo.csproj", "{03305477-5A80-6218-2A86-B3150CBA94A3}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AIConnectorDemo", "AIConnectorDemo\AIConnectorDemo.csproj", "{4AC38EDC-AE27-8F2B-5BCB-8E73F27E33F2}" EndProject Global @@ -85,10 +83,6 @@ Global {BD58EF11-6552-4279-A341-0E200480A201}.Debug|Any CPU.Build.0 = Debug|Any CPU {BD58EF11-6552-4279-A341-0E200480A201}.Release|Any CPU.ActiveCfg = Release|Any CPU {BD58EF11-6552-4279-A341-0E200480A201}.Release|Any CPU.Build.0 = Release|Any CPU - {03305477-5A80-6218-2A86-B3150CBA94A3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {03305477-5A80-6218-2A86-B3150CBA94A3}.Debug|Any CPU.Build.0 = Debug|Any CPU - {03305477-5A80-6218-2A86-B3150CBA94A3}.Release|Any CPU.ActiveCfg = Release|Any CPU - {03305477-5A80-6218-2A86-B3150CBA94A3}.Release|Any CPU.Build.0 = Release|Any CPU {4AC38EDC-AE27-8F2B-5BCB-8E73F27E33F2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {4AC38EDC-AE27-8F2B-5BCB-8E73F27E33F2}.Debug|Any CPU.Build.0 = Debug|Any CPU {4AC38EDC-AE27-8F2B-5BCB-8E73F27E33F2}.Release|Any CPU.ActiveCfg = Release|Any CPU diff --git a/PdfProcessing/PdfProcessing_NetStandard.sln b/PdfProcessing/PdfProcessing_NetStandard.sln index 07c74eb..e198638 100644 --- a/PdfProcessing/PdfProcessing_NetStandard.sln +++ b/PdfProcessing/PdfProcessing_NetStandard.sln @@ -23,8 +23,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CustomJpegImageConverter_Ne EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AddWatermark_NetStandard", "AddWatermark\AddWatermark_NetStandard.csproj", "{5E7AB5A2-E716-4FEE-A30B-5E7167C94013}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Flow_AIConnectorDemo_NetStandard", "Flow_AIConnectorDemo\Flow_AIConnectorDemo_NetStandard.csproj", "{2E0CD20E-F441-B2D9-60B4-E6E98C7462E4}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AIConnectorDemo_NetStandard", "AIConnectorDemo\AIConnectorDemo_NetStandard.csproj", "{C948AB2A-A1D5-DE6C-0C36-8E9A4C475033}" EndProject Global @@ -73,10 +71,6 @@ Global {5E7AB5A2-E716-4FEE-A30B-5E7167C94013}.Debug|Any CPU.Build.0 = Debug|Any CPU {5E7AB5A2-E716-4FEE-A30B-5E7167C94013}.Release|Any CPU.ActiveCfg = Release|Any CPU {5E7AB5A2-E716-4FEE-A30B-5E7167C94013}.Release|Any CPU.Build.0 = Release|Any CPU - {2E0CD20E-F441-B2D9-60B4-E6E98C7462E4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {2E0CD20E-F441-B2D9-60B4-E6E98C7462E4}.Debug|Any CPU.Build.0 = Debug|Any CPU - {2E0CD20E-F441-B2D9-60B4-E6E98C7462E4}.Release|Any CPU.ActiveCfg = Release|Any CPU - {2E0CD20E-F441-B2D9-60B4-E6E98C7462E4}.Release|Any CPU.Build.0 = Release|Any CPU {C948AB2A-A1D5-DE6C-0C36-8E9A4C475033}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {C948AB2A-A1D5-DE6C-0C36-8E9A4C475033}.Debug|Any CPU.Build.0 = Debug|Any CPU {C948AB2A-A1D5-DE6C-0C36-8E9A4C475033}.Release|Any CPU.ActiveCfg = Release|Any CPU diff --git a/WordsProcessing/AIConnectorDemo/CustomOpenAIEmbedder.cs b/WordsProcessing/AIConnectorDemo/CustomOpenAIEmbedder.cs index 86cef66..080ab1d 100644 --- a/WordsProcessing/AIConnectorDemo/CustomOpenAIEmbedder.cs +++ b/WordsProcessing/AIConnectorDemo/CustomOpenAIEmbedder.cs @@ -3,7 +3,7 @@ using System.Text.Json; using Telerik.Documents.AI.Core; -namespace FlowAIConnectorDemo +namespace AIConnectorDemo { public class CustomOpenAIEmbedder : IEmbedder { diff --git a/WordsProcessing/AIConnectorDemo/Program.cs b/WordsProcessing/AIConnectorDemo/Program.cs index cde4fb7..7a265f3 100644 --- a/WordsProcessing/AIConnectorDemo/Program.cs +++ b/WordsProcessing/AIConnectorDemo/Program.cs @@ -13,7 +13,7 @@ using Telerik.Windows.Documents.Flow.Model; using Telerik.Windows.Documents.TextRepresentation; -namespace FlowAIConnectorDemo +namespace AIConnectorDemo { internal class Program { diff --git a/WordsProcessing/AIConnectorDemo/TextLoader.cs b/WordsProcessing/AIConnectorDemo/TextLoader.cs index 20d42e4..ad8732b 100644 --- a/WordsProcessing/AIConnectorDemo/TextLoader.cs +++ b/WordsProcessing/AIConnectorDemo/TextLoader.cs @@ -1,6 +1,6 @@ using LangChain.DocumentLoaders; -namespace FlowAIConnectorDemo +namespace AIConnectorDemo { internal class TextLoader : IDocumentLoader { From 04f5282c79a53128a9286d2870feaa5ffc95144b Mon Sep 17 00:00:00 2001 From: "PROGRESS\\ykaraman" Date: Wed, 10 Dec 2025 17:57:57 +0200 Subject: [PATCH 6/7] Removed unused references and files. --- .../AIConnectorDemo_NetStandard.csproj | 4 ---- PdfProcessing/AIConnectorDemo/TextLoader.cs | 20 ------------------- 2 files changed, 24 deletions(-) delete mode 100644 PdfProcessing/AIConnectorDemo/TextLoader.cs diff --git a/PdfProcessing/AIConnectorDemo/AIConnectorDemo_NetStandard.csproj b/PdfProcessing/AIConnectorDemo/AIConnectorDemo_NetStandard.csproj index 653811e..4fb70ac 100644 --- a/PdfProcessing/AIConnectorDemo/AIConnectorDemo_NetStandard.csproj +++ b/PdfProcessing/AIConnectorDemo/AIConnectorDemo_NetStandard.csproj @@ -13,10 +13,6 @@ - - - - diff --git a/PdfProcessing/AIConnectorDemo/TextLoader.cs b/PdfProcessing/AIConnectorDemo/TextLoader.cs deleted file mode 100644 index ad8732b..0000000 --- a/PdfProcessing/AIConnectorDemo/TextLoader.cs +++ /dev/null @@ -1,20 +0,0 @@ -using LangChain.DocumentLoaders; - -namespace AIConnectorDemo -{ - internal class TextLoader : IDocumentLoader - { - public async Task> LoadAsync(DataSource dataSource, DocumentLoaderSettings? settings = null, CancellationToken cancellationToken = default) - { - using (Stream inputStream = await dataSource.GetStreamAsync(cancellationToken)) - { - StreamReader reader = new StreamReader(inputStream); - string content = reader.ReadToEnd(); - - string[] pages = content.Split(["----------"], System.StringSplitOptions.RemoveEmptyEntries); - - return pages.Select(x => new Document(x)).ToList(); - } - } - } -} \ No newline at end of file From ba39cb1dc610bd12aad03d1e135ec4bc9832dbaf Mon Sep 17 00:00:00 2001 From: "PROGRESS\\ykaraman" Date: Wed, 10 Dec 2025 19:48:41 +0200 Subject: [PATCH 7/7] Flow Demo: Removed unused references and file. --- .../AIConnectorDemo_NetStandard.csproj | 4 ---- WordsProcessing/AIConnectorDemo/TextLoader.cs | 20 ------------------- 2 files changed, 24 deletions(-) delete mode 100644 WordsProcessing/AIConnectorDemo/TextLoader.cs diff --git a/WordsProcessing/AIConnectorDemo/AIConnectorDemo_NetStandard.csproj b/WordsProcessing/AIConnectorDemo/AIConnectorDemo_NetStandard.csproj index 38e50d0..aa2a792 100644 --- a/WordsProcessing/AIConnectorDemo/AIConnectorDemo_NetStandard.csproj +++ b/WordsProcessing/AIConnectorDemo/AIConnectorDemo_NetStandard.csproj @@ -13,10 +13,6 @@ - - - - diff --git a/WordsProcessing/AIConnectorDemo/TextLoader.cs b/WordsProcessing/AIConnectorDemo/TextLoader.cs deleted file mode 100644 index ad8732b..0000000 --- a/WordsProcessing/AIConnectorDemo/TextLoader.cs +++ /dev/null @@ -1,20 +0,0 @@ -using LangChain.DocumentLoaders; - -namespace AIConnectorDemo -{ - internal class TextLoader : IDocumentLoader - { - public async Task> LoadAsync(DataSource dataSource, DocumentLoaderSettings? settings = null, CancellationToken cancellationToken = default) - { - using (Stream inputStream = await dataSource.GetStreamAsync(cancellationToken)) - { - StreamReader reader = new StreamReader(inputStream); - string content = reader.ReadToEnd(); - - string[] pages = content.Split(["----------"], System.StringSplitOptions.RemoveEmptyEntries); - - return pages.Select(x => new Document(x)).ToList(); - } - } - } -} \ No newline at end of file