chore: import upstream snapshot with attribution
CodeQL / Analyze (csharp) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled

This commit is contained in:
wehub-resource-sync
2026-07-13 13:21:23 +08:00
commit b957a53def
5423 changed files with 863745 additions and 0 deletions
@@ -0,0 +1,26 @@
// Copyright (c) Microsoft. All rights reserved.
using Microsoft.SemanticKernel;
using Step02.Models;
namespace Step02.Steps;
/// <summary>
/// Mock step that emulates the creation of a new CRM entry
/// </summary>
public class CRMRecordCreationStep : KernelProcessStep
{
public static class ProcessStepFunctions
{
public const string CreateCRMEntry = nameof(CreateCRMEntry);
}
[KernelFunction(ProcessStepFunctions.CreateCRMEntry)]
public async Task CreateCRMEntryAsync(KernelProcessStepContext context, AccountUserInteractionDetails userInteractionDetails, Kernel _kernel)
{
Console.WriteLine($"[CRM ENTRY CREATION] New Account {userInteractionDetails.AccountId} created");
// Placeholder for a call to API to create new CRM entry
await context.EmitEventAsync(new() { Id = AccountOpeningEvents.CRMRecordInfoEntryCreated, Data = true });
}
}
@@ -0,0 +1,215 @@
// Copyright (c) Microsoft. All rights reserved.
using System.ComponentModel;
using System.Text.Json;
using System.Text.Json.Serialization;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.ChatCompletion;
using Microsoft.SemanticKernel.Connectors.OpenAI;
using Step02.Models;
namespace Step02.Steps;
/// <summary>
/// Step that is helps the user fill up a new account form.<br/>
/// Also provides a welcome message for the user.
/// </summary>
public class CompleteNewCustomerFormStep : KernelProcessStep<NewCustomerFormState>
{
public static class ProcessStepFunctions
{
public const string NewAccountProcessUserInfo = nameof(NewAccountProcessUserInfo);
public const string NewAccountWelcome = nameof(NewAccountWelcome);
}
internal NewCustomerFormState? _state;
internal string _formCompletionSystemPrompt = """
The goal is to fill up all the fields needed for a form.
The user may provide information to fill up multiple fields of the form in one message.
The user needs to fill up a form, all the fields of the form are necessary
<CURRENT_FORM_STATE>
{{current_form_state}}
<CURRENT_FORM_STATE>
GUIDANCE:
- If there are missing details, give the user a useful message that will help fill up the remaining fields.
- Your goal is to help guide the user to provide the missing details on the current form.
- Encourage the user to provide the remainingdetails with examples if necessary.
- Fields with value 'Unanswered' need to be answered by the user.
- Format phone numbers and user ids correctly if the user does not provide the expected format.
- If the user does not make use of parenthesis in the phone number, add them.
- For date fields, confirm with the user first if the date format is not clear. Example 02/03 03/02 could be March 2nd or February 3rd.
""";
internal string _welcomeMessage = """
Hello there, I can help you out fill out the information needed to open a new account with us.
Please provide some personal information like first name and last name to get started.
""";
private readonly JsonSerializerOptions _jsonOptions = new()
{
DefaultIgnoreCondition = JsonIgnoreCondition.Never
};
public override ValueTask ActivateAsync(KernelProcessStepState<NewCustomerFormState> state)
{
_state = state.State;
return ValueTask.CompletedTask;
}
[KernelFunction(ProcessStepFunctions.NewAccountWelcome)]
public async Task NewAccountWelcomeMessageAsync(KernelProcessStepContext context, Kernel _kernel)
{
_state?.conversation.Add(new ChatMessageContent { Role = AuthorRole.Assistant, Content = _welcomeMessage });
await context.EmitEventAsync(new() { Id = AccountOpeningEvents.NewCustomerFormWelcomeMessageComplete, Data = _welcomeMessage });
}
private Kernel CreateNewCustomerFormKernel(Kernel _baseKernel)
{
// Creating another kernel that only makes use private functions to fill up the new customer form
Kernel kernel = new(_baseKernel.Services);
kernel.ImportPluginFromFunctions("FillForm", [
KernelFunctionFactory.CreateFromMethod(OnUserProvidedFirstName, functionName: nameof(OnUserProvidedFirstName)),
KernelFunctionFactory.CreateFromMethod(OnUserProvidedLastName, functionName: nameof(OnUserProvidedLastName)),
KernelFunctionFactory.CreateFromMethod(OnUserProvidedDOBDetails, functionName: nameof(OnUserProvidedDOBDetails)),
KernelFunctionFactory.CreateFromMethod(OnUserProvidedStateOfResidence, functionName: nameof(OnUserProvidedStateOfResidence)),
KernelFunctionFactory.CreateFromMethod(OnUserProvidedPhoneNumber, functionName: nameof(OnUserProvidedPhoneNumber)),
KernelFunctionFactory.CreateFromMethod(OnUserProvidedUserId, functionName: nameof(OnUserProvidedUserId)),
KernelFunctionFactory.CreateFromMethod(OnUserProvidedEmailAddress, functionName: nameof(OnUserProvidedEmailAddress)),
]);
return kernel;
}
[KernelFunction(ProcessStepFunctions.NewAccountProcessUserInfo)]
public async Task CompleteNewCustomerFormAsync(KernelProcessStepContext context, string userMessage, Kernel _kernel)
{
// Keeping track of all user interactions
_state?.conversation.Add(new ChatMessageContent { Role = AuthorRole.User, Content = userMessage });
Kernel kernel = CreateNewCustomerFormKernel(_kernel);
OpenAIPromptExecutionSettings settings = new()
{
ToolCallBehavior = ToolCallBehavior.AutoInvokeKernelFunctions,
Temperature = 0.7,
MaxTokens = 2048
};
ChatHistory chatHistory = [];
chatHistory.AddSystemMessage(_formCompletionSystemPrompt
.Replace("{{current_form_state}}", JsonSerializer.Serialize(_state!.newCustomerForm.CopyWithDefaultValues(), _jsonOptions)));
chatHistory.AddRange(_state.conversation);
IChatCompletionService chatService = kernel.Services.GetRequiredService<IChatCompletionService>();
ChatMessageContent response = await chatService.GetChatMessageContentAsync(chatHistory, settings, kernel).ConfigureAwait(false);
var assistantResponse = "";
if (response != null)
{
assistantResponse = response.Items[0].ToString();
// Keeping track of all assistant interactions
_state?.conversation.Add(new ChatMessageContent { Role = AuthorRole.Assistant, Content = assistantResponse });
}
if (_state?.newCustomerForm != null && _state.newCustomerForm.IsFormCompleted())
{
Console.WriteLine($"[NEW_USER_FORM_COMPLETED]: {JsonSerializer.Serialize(_state?.newCustomerForm)}");
// All user information is gathered to proceed to the next step
await context.EmitEventAsync(new() { Id = AccountOpeningEvents.NewCustomerFormCompleted, Data = _state?.newCustomerForm, Visibility = KernelProcessEventVisibility.Public });
await context.EmitEventAsync(new() { Id = AccountOpeningEvents.CustomerInteractionTranscriptReady, Data = _state?.conversation, Visibility = KernelProcessEventVisibility.Public });
return;
}
// emit event: NewCustomerFormNeedsMoreDetails
await context.EmitEventAsync(new() { Id = AccountOpeningEvents.NewCustomerFormNeedsMoreDetails, Data = assistantResponse });
}
[Description("User provided details of first name")]
private Task OnUserProvidedFirstName(string firstName)
{
if (!string.IsNullOrEmpty(firstName) && _state != null)
{
_state.newCustomerForm.UserFirstName = firstName;
}
return Task.CompletedTask;
}
[Description("User provided details of last name")]
private Task OnUserProvidedLastName(string lastName)
{
if (!string.IsNullOrEmpty(lastName) && _state != null)
{
_state.newCustomerForm.UserLastName = lastName;
}
return Task.CompletedTask;
}
[Description("User provided details of USA State the user lives in, must be in 2-letter Uppercase State Abbreviation format")]
private Task OnUserProvidedStateOfResidence(string stateAbbreviation)
{
if (!string.IsNullOrEmpty(stateAbbreviation) && _state != null)
{
_state.newCustomerForm.UserState = stateAbbreviation;
}
return Task.CompletedTask;
}
[Description("User provided details of date of birth, must be in the format MM/DD/YYYY")]
private Task OnUserProvidedDOBDetails(string date)
{
if (!string.IsNullOrEmpty(date) && _state != null)
{
_state.newCustomerForm.UserDateOfBirth = date;
}
return Task.CompletedTask;
}
[Description("User provided details of phone number, must be in the format (\\d{3})-\\d{3}-\\d{4}")]
private Task OnUserProvidedPhoneNumber(string phoneNumber)
{
if (!string.IsNullOrEmpty(phoneNumber) && _state != null)
{
_state.newCustomerForm.UserPhoneNumber = phoneNumber;
}
return Task.CompletedTask;
}
[Description("User provided details of userId, must be in the format \\d{3}-\\d{3}-\\d{4}")]
private Task OnUserProvidedUserId(string userId)
{
if (!string.IsNullOrEmpty(userId) && _state != null)
{
_state.newCustomerForm.UserId = userId;
}
return Task.CompletedTask;
}
[Description("User provided email address, must be in the an email valid format")]
private Task OnUserProvidedEmailAddress(string emailAddress)
{
if (!string.IsNullOrEmpty(emailAddress) && _state != null)
{
_state.newCustomerForm.UserEmail = emailAddress;
}
return Task.CompletedTask;
}
}
/// <summary>
/// The state object for the <see cref="CompleteNewCustomerFormStep"/>
/// </summary>
public class NewCustomerFormState
{
internal NewCustomerForm newCustomerForm { get; set; } = new();
internal List<ChatMessageContent> conversation { get; set; } = [];
}
@@ -0,0 +1,40 @@
// Copyright (c) Microsoft. All rights reserved.
using Microsoft.SemanticKernel;
using Step02.Models;
namespace Step02.Steps;
/// <summary>
/// Mock step that emulates User Credit Score check, based on the date of birth the score will be enough or insufficient
/// </summary>
public class CreditScoreCheckStep : KernelProcessStep
{
public static class ProcessStepFunctions
{
public const string DetermineCreditScore = nameof(DetermineCreditScore);
}
private const int MinCreditScore = 600;
[KernelFunction(ProcessStepFunctions.DetermineCreditScore)]
public async Task DetermineCreditScoreAsync(KernelProcessStepContext context, NewCustomerForm customerDetails, Kernel _kernel)
{
// Placeholder for a call to API to validate credit score with customerDetails
var creditScore = customerDetails.UserDateOfBirth == "02/03/1990" ? 700 : 500;
if (creditScore >= MinCreditScore)
{
Console.WriteLine("[CREDIT CHECK] Credit Score Check Passed");
await context.EmitEventAsync(new() { Id = AccountOpeningEvents.CreditScoreCheckApproved, Data = true });
return;
}
Console.WriteLine("[CREDIT CHECK] Credit Score Check Failed");
await context.EmitEventAsync(new()
{
Id = AccountOpeningEvents.CreditScoreCheckRejected,
Data = $"We regret to inform you that your credit score of {creditScore} is insufficient to apply for an account of the type PRIME ABC",
Visibility = KernelProcessEventVisibility.Public,
});
}
}
@@ -0,0 +1,37 @@
// Copyright (c) Microsoft. All rights reserved.
using Microsoft.SemanticKernel;
using Step02.Models;
namespace Step02.Steps;
/// <summary>
/// Mock step that emulates a Fraud detection check, based on the userId the fraud detection will pass or fail.
/// </summary>
public class FraudDetectionStep : KernelProcessStep
{
public static class ProcessStepFunctions
{
public const string FraudDetectionCheck = nameof(FraudDetectionCheck);
}
[KernelFunction(ProcessStepFunctions.FraudDetectionCheck)]
public async Task FraudDetectionCheckAsync(KernelProcessStepContext context, bool previousCheckSucceeded, NewCustomerForm customerDetails, Kernel _kernel)
{
// Placeholder for a call to API to validate user details for fraud detection
if (customerDetails.UserId == "123-456-7890")
{
Console.WriteLine("[FRAUD CHECK] Fraud Check Failed");
await context.EmitEventAsync(new()
{
Id = AccountOpeningEvents.FraudDetectionCheckFailed,
Data = "We regret to inform you that we found some inconsistent details regarding the information you provided regarding the new account of the type PRIME ABC you applied.",
Visibility = KernelProcessEventVisibility.Public,
});
return;
}
Console.WriteLine("[FRAUD CHECK] Fraud Check Passed");
await context.EmitEventAsync(new() { Id = AccountOpeningEvents.FraudDetectionCheckPassed, Data = true, Visibility = KernelProcessEventVisibility.Public });
}
}
@@ -0,0 +1,27 @@
// Copyright (c) Microsoft. All rights reserved.
using Microsoft.SemanticKernel;
using Step02.Models;
namespace Step02.Steps;
/// <summary>
/// Mock step that emulates Mail Service with a message for the user.
/// </summary>
public class MailServiceStep : KernelProcessStep
{
public static class ProcessStepFunctions
{
public const string SendMailToUserWithDetails = nameof(SendMailToUserWithDetails);
}
[KernelFunction(ProcessStepFunctions.SendMailToUserWithDetails)]
public async Task SendMailServiceAsync(KernelProcessStepContext context, string message)
{
Console.WriteLine("======== MAIL SERVICE ======== ");
Console.WriteLine(message);
Console.WriteLine("============================== ");
await context.EmitEventAsync(new() { Id = AccountOpeningEvents.MailServiceSent, Data = message });
}
}
@@ -0,0 +1,67 @@
// Copyright (c) Microsoft. All rights reserved.
using Microsoft.SemanticKernel;
using Step02.Models;
namespace Step02.Steps;
/// <summary>
/// Mock step that emulates the creation of a new account that triggers other services after a new account id creation
/// </summary>
public class NewAccountStep : KernelProcessStep
{
public static class ProcessStepFunctions
{
public const string CreateNewAccount = nameof(CreateNewAccount);
}
[KernelFunction(ProcessStepFunctions.CreateNewAccount)]
public async Task CreateNewAccountAsync(KernelProcessStepContext context, bool previousCheckSucceeded, NewCustomerForm customerDetails, List<ChatMessageContent> interactionTranscript, Kernel _kernel)
{
// Placeholder for a call to API to create new account for user
var accountId = new Guid();
AccountDetails accountDetails = new()
{
UserDateOfBirth = customerDetails.UserDateOfBirth,
UserFirstName = customerDetails.UserFirstName,
UserLastName = customerDetails.UserLastName,
UserId = customerDetails.UserId,
UserPhoneNumber = customerDetails.UserPhoneNumber,
UserState = customerDetails.UserState,
UserEmail = customerDetails.UserEmail,
AccountId = accountId,
AccountType = AccountType.PrimeABC,
};
Console.WriteLine($"[ACCOUNT CREATION] New Account {accountId} created");
await context.EmitEventAsync(new()
{
Id = AccountOpeningEvents.NewMarketingRecordInfoReady,
Data = new MarketingNewEntryDetails
{
AccountId = accountId,
Name = $"{customerDetails.UserFirstName} {customerDetails.UserLastName}",
PhoneNumber = customerDetails.UserPhoneNumber,
Email = customerDetails.UserEmail,
}
});
await context.EmitEventAsync(new()
{
Id = AccountOpeningEvents.CRMRecordInfoReady,
Data = new AccountUserInteractionDetails
{
AccountId = accountId,
UserInteractionType = UserInteractionType.OpeningNewAccount,
InteractionTranscript = interactionTranscript
}
});
await context.EmitEventAsync(new()
{
Id = AccountOpeningEvents.NewAccountDetailsReady,
Data = accountDetails,
});
}
}
@@ -0,0 +1,26 @@
// Copyright (c) Microsoft. All rights reserved.
using Microsoft.SemanticKernel;
using Step02.Models;
namespace Step02.Steps;
/// <summary>
/// Mock step that emulates the creation a new marketing user entry.
/// </summary>
public class NewMarketingEntryStep : KernelProcessStep
{
public static class ProcessStepFunctions
{
public const string CreateNewMarketingEntry = nameof(CreateNewMarketingEntry);
}
[KernelFunction(ProcessStepFunctions.CreateNewMarketingEntry)]
public async Task CreateNewMarketingEntryAsync(KernelProcessStepContext context, MarketingNewEntryDetails userDetails, Kernel _kernel)
{
Console.WriteLine($"[MARKETING ENTRY CREATION] New Account {userDetails.AccountId} created");
// Placeholder for a call to API to create new entry of user for marketing purposes
await context.EmitEventAsync(new() { Id = AccountOpeningEvents.NewMarketingEntryCreated, Data = true });
}
}
@@ -0,0 +1,20 @@
// Copyright (c) Microsoft. All rights reserved.
using SharedSteps;
namespace Step02.Steps;
/// <summary>
/// <see cref="ScriptedUserInputStep"/> Step with interactions that makes the Process fail due credit score failure
/// </summary>
public sealed class UserInputCreditScoreFailureInteractionStep : ScriptedUserInputStep
{
public override void PopulateUserInputs(UserInputState state)
{
state.UserInputs.Add("I would like to open an account");
state.UserInputs.Add("My name is John Contoso, dob 01/01/1990");
state.UserInputs.Add("I live in Washington and my phone number es 222-222-1234");
state.UserInputs.Add("My userId is 987-654-3210");
state.UserInputs.Add("My email is john.contoso@contoso.com, what else do you need?");
}
}
@@ -0,0 +1,20 @@
// Copyright (c) Microsoft. All rights reserved.
using SharedSteps;
namespace Step02.Steps;
/// <summary>
/// <see cref="ScriptedUserInputStep"/> Step with interactions that makes the Process fail due fraud detection failure
/// </summary>
public sealed class UserInputFraudFailureInteractionStep : ScriptedUserInputStep
{
public override void PopulateUserInputs(UserInputState state)
{
state.UserInputs.Add("I would like to open an account");
state.UserInputs.Add("My name is John Contoso, dob 02/03/1990");
state.UserInputs.Add("I live in Washington and my phone number es 222-222-1234");
state.UserInputs.Add("My userId is 123-456-7890");
state.UserInputs.Add("My email is john.contoso@contoso.com, what else do you need?");
}
}
@@ -0,0 +1,20 @@
// Copyright (c) Microsoft. All rights reserved.
using SharedSteps;
namespace Step02.Steps;
/// <summary>
/// <see cref="ScriptedUserInputStep"/> Step with interactions that makes the Process pass all steps and successfully open a new account
/// </summary>
public sealed class UserInputSuccessfulInteractionStep : ScriptedUserInputStep
{
public override void PopulateUserInputs(UserInputState state)
{
state.UserInputs.Add("I would like to open an account");
state.UserInputs.Add("My name is John Contoso, dob 02/03/1990");
state.UserInputs.Add("I live in Washington and my phone number es 222-222-1234");
state.UserInputs.Add("My userId is 987-654-3210");
state.UserInputs.Add("My email is john.contoso@contoso.com, what else do you need?");
}
}
@@ -0,0 +1,48 @@
// Copyright (c) Microsoft. All rights reserved.
using Microsoft.SemanticKernel;
using Step02.Models;
namespace Step02.Steps;
/// <summary>
/// Mock step that emulates the creation of a Welcome Packet for a new user after account creation
/// </summary>
public class WelcomePacketStep : KernelProcessStep
{
public static class ProcessStepFunctions
{
public const string CreateWelcomePacket = nameof(CreateWelcomePacket);
}
[KernelFunction(ProcessStepFunctions.CreateWelcomePacket)]
public async Task CreateWelcomePacketAsync(KernelProcessStepContext context, bool marketingEntryCreated, bool crmRecordCreated, AccountDetails accountDetails, Kernel _kernel)
{
Console.WriteLine($"[WELCOME PACKET] New Account {accountDetails.AccountId} created");
var mailMessage = $"""
Dear {accountDetails.UserFirstName} {accountDetails.UserLastName}
We are thrilled to inform you that you have successfully created a new PRIME ABC Account with us!
Account Details:
Account Number: {accountDetails.AccountId}
Account Type: {accountDetails.AccountType}
Please keep this confidential for security purposes.
Here is the contact information we have in file:
Email: {accountDetails.UserEmail}
Phone: {accountDetails.UserPhoneNumber}
Thank you for opening an account with us!
""";
await context.EmitEventAsync(new()
{
Id = AccountOpeningEvents.WelcomePacketCreated,
Data = mailMessage,
Visibility = KernelProcessEventVisibility.Public,
});
}
}