Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions 03-CoreGenerativeAITechniques/src/CoreGenerativeAITechniques.sln
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,11 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "11 Video Generation", "11 V
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VideoGeneration-AzureSora-01", "VideoGeneration-AzureSora-01\VideoGeneration-AzureSora-01.csproj", "{20C3DA44-FAF4-41FB-9B3D-1782A250A0B8}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "12 Files", "12 Files", "{E224737A-CFFB-4292-8F73-A543A0387938}"
EndProject
Comment on lines +88 to +89
Copy link

Copilot AI Jun 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This solution entry references a "12 Files" folder without a project file; it won’t build. Remove or update this stub entry to avoid confusion.

Suggested change
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "12 Files", "12 Files", "{E224737A-CFFB-4292-8F73-A543A0387938}"
EndProject

Copilot uses AI. Check for mistakes.
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenAI-FileProcessing-Pdf-01", "OpenAI-FileProcessing-Pdf-01\OpenAI-FileProcessing-Pdf-01.csproj", "{4266A1B3-94FF-482E-A292-F1A36E0777D9}"
EndProject

Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -455,6 +460,19 @@ Global
{20C3DA44-FAF4-41FB-9B3D-1782A250A0B8}.Release|x64.Build.0 = Release|Any CPU
{20C3DA44-FAF4-41FB-9B3D-1782A250A0B8}.Release|x86.ActiveCfg = Release|Any CPU
{20C3DA44-FAF4-41FB-9B3D-1782A250A0B8}.Release|x86.Build.0 = Release|Any CPU
{4266A1B3-94FF-482E-A292-F1A36E0777D9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4266A1B3-94FF-482E-A292-F1A36E0777D9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4266A1B3-94FF-482E-A292-F1A36E0777D9}.Debug|x64.ActiveCfg = Debug|Any CPU
{4266A1B3-94FF-482E-A292-F1A36E0777D9}.Debug|x64.Build.0 = Debug|Any CPU
{4266A1B3-94FF-482E-A292-F1A36E0777D9}.Debug|x86.ActiveCfg = Debug|Any CPU
{4266A1B3-94FF-482E-A292-F1A36E0777D9}.Debug|x86.Build.0 = Debug|Any CPU
{4266A1B3-94FF-482E-A292-F1A36E0777D9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4266A1B3-94FF-482E-A292-F1A36E0777D9}.Release|Any CPU.Build.0 = Release|Any CPU
{4266A1B3-94FF-482E-A292-F1A36E0777D9}.Release|x64.ActiveCfg = Release|Any CPU
{4266A1B3-94FF-482E-A292-F1A36E0777D9}.Release|x64.Build.0 = Release|Any CPU
{4266A1B3-94FF-482E-A292-F1A36E0777D9}.Release|x86.ActiveCfg = Release|Any CPU
{4266A1B3-94FF-482E-A292-F1A36E0777D9}.Release|x86.Build.0 = Release|Any CPU

EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net9.0</TargetFramework>
<RootNamespace>OpenAI_FileProcessing_Pdf_01</RootNamespace>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<UserSecretsId>0ef9e832-4d1e-45cf-acff-f7bb41388649</UserSecretsId>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="6.0.1" />
<PackageReference Include="Microsoft.SemanticKernel" Version="1.55.0" />
<PackageReference Include="Microsoft.SemanticKernel.Connectors.OpenAI" Version="1.55.0" />
</ItemGroup>

<ItemGroup>
<None Update="docs\real-state-contract-1.pdf">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="docs\real-state-contract-2.pdf">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>


</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
// based on the original sample for Semantic Kernel and Gemini
// https://medium.com/@johnidouglasmarangon/generating-structured-outputs-from-pdfs-with-semantic-kernel-and-gemini-aa4d4382e339

using Microsoft.Extensions.Configuration;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.ChatCompletion;
using Microsoft.SemanticKernel.Connectors.OpenAI;
using System.ComponentModel;
using System.Text.Json;

// load OpenAI api_key value
var configBuilder = new ConfigurationBuilder().AddUserSecrets<Program>();
var configuration = configBuilder.Build();
string modelId = "gpt-4.1";
string apiKey = configuration["api_key"];

var builder = Kernel.CreateBuilder();
builder.AddOpenAIChatCompletion(modelId, apiKey);
var kernel = builder.Build();
var chatService = kernel.GetRequiredService<IChatCompletionService>();

var filePath = Path.Combine(Directory.GetCurrentDirectory(), "docs", "real-state-contract-1.pdf");
Copy link

Copilot AI Jun 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] The filename uses "real-state" but the domain term is "real-estate"; consider renaming the file and references to real-estate-contract-1.pdf for clarity.

Suggested change
var filePath = Path.Combine(Directory.GetCurrentDirectory(), "docs", "real-state-contract-1.pdf");
var filePath = Path.Combine(Directory.GetCurrentDirectory(), "docs", "real-estate-contract-1.pdf");

Copilot uses AI. Check for mistakes.
var bytes = File.ReadAllBytes(filePath);

var history = new ChatHistory();
history.AddSystemMessage(
"""
You are an expert real estate contract analyst.
Your task is to extract key information from the provided real estate purchase agreement.
Pay close attention to detail and extract the following data points.
If a data point is not explicitly mentioned in the document, mark it as "N/A".
Format your response as a JSON object, where the keys are the data point names and the values are the extracted information.
Do not include any explanatory text or comments in your response, just the raw JSON.
The real estate purchase agreement is provided below.
Process it carefully and provide the JSON output.
"""
);

#pragma warning disable SKEXP0001
history.AddUserMessage([
new TextContent("This is the PDF file"),
new BinaryContent(bytes, "application/pdf")
]);

var executionSettings = new OpenAIPromptExecutionSettings
{
MaxTokens = null
};

executionSettings.ResponseFormat = typeof(Contract);


var response = await chatService.GetChatMessageContentAsync(history, executionSettings);
Console.WriteLine("Response received from OpenAI API:");
Console.WriteLine(response.Content);
Console.WriteLine("---");

var contract = JsonSerializer.Deserialize<Contract>(response.ToString());
Copy link

Copilot AI Jun 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You’re passing response.ToString() into the deserializer, which may not be the raw JSON. Use response.Content instead to deserialize the actual payload.

Suggested change
var contract = JsonSerializer.Deserialize<Contract>(response.ToString());
var contract = JsonSerializer.Deserialize<Contract>(response.Content);

Copilot uses AI. Check for mistakes.
Console.WriteLine("Extracted Contract Information:");
Console.WriteLine(JsonSerializer.Serialize(contract, new JsonSerializerOptions { WriteIndented = true }));

public class Seller
{
[Description("The full legal name of the seller")]
public string Name { get; set; }

[Description("The full address of the seller")]
public string Address { get; set; }
}

public class Buyer
{
[Description("The full legal name of the buyer")]
public string Name { get; set; }

[Description("The full address of the buyer")]
public string Address { get; set; }
}

public class Contract
{
[Description("The full street address of the property")]
public string PropertyAddress { get; set; }

[Description("The total purchase price of the property")]
public string PropertyPrice { get; set; }

[Description("The full legal description of the property")]
public string PropertyDescription { get; set; }

[Description("The date the agreement was signed")]
public string Date { get; set; }

public Seller Seller { get; set; }
public Buyer Buyer { get; set; }
}
Binary file not shown.
Binary file not shown.