-
Notifications
You must be signed in to change notification settings - Fork 4k
.Net: Add Sessions (Code Interpreter) Core Plugin and Demo Project #6160
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
RogerBarreto
merged 10 commits into
microsoft:main
from
RogerBarreto:features/code-interpreter-plugin
May 9, 2024
Merged
Changes from 6 commits
Commits
Show all changes
10 commits
Select commit
Hold shift + click to select a range
378115a
.Net Code Interpreter Plugin
RogerBarreto 9e8a325
Changing the App Info
RogerBarreto e9334dd
Include project into Readme.md
RogerBarreto 1fac383
Fix warnings
RogerBarreto 4063df5
Addressing PR comments
RogerBarreto b1e9778
Addressing PR comments
RogerBarreto 364639b
Added Unit Tests
RogerBarreto c2c04cc
Addressing PR feedback + More unit tests
RogerBarreto f06cb9a
Full stop
RogerBarreto 4cd3e2e
Merge branch 'main' into features/code-interpreter-plugin
RogerBarreto File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
26 changes: 26 additions & 0 deletions
26
dotnet/samples/Demos/CodeInterpreterPlugin/CodeInterpreterPlugin.csproj
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<OutputType>Exe</OutputType> | ||
<TargetFramework>net8.0</TargetFramework> | ||
<ImplicitUsings>enable</ImplicitUsings> | ||
<Nullable>enable</Nullable> | ||
<UserSecretsId>5ee045b0-aea3-4f08-8d31-32d1a6f8fed0</UserSecretsId> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="Azure.Identity" /> | ||
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" /> | ||
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" /> | ||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" /> | ||
<PackageReference Include="Microsoft.Extensions.Http" /> | ||
<PackageReference Include="Microsoft.Extensions.Logging.Console" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<ProjectReference Include="..\..\..\src\Connectors\Connectors.OpenAI\Connectors.OpenAI.csproj" /> | ||
<ProjectReference Include="..\..\..\src\Plugins\Plugins.Core\Plugins.Core.csproj" /> | ||
<ProjectReference Include="..\..\..\src\SemanticKernel.Abstractions\SemanticKernel.Abstractions.csproj" /> | ||
<ProjectReference Include="..\..\..\src\SemanticKernel.Core\SemanticKernel.Core.csproj" /> | ||
</ItemGroup> | ||
</Project> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
// Copyright (c) Microsoft. All rights reserved. | ||
|
||
using System.Text; | ||
using Azure.Identity; | ||
using Microsoft.Extensions.Configuration; | ||
using Microsoft.Extensions.DependencyInjection; | ||
using Microsoft.Extensions.Logging; | ||
using Microsoft.Extensions.Logging.Abstractions; | ||
using Microsoft.SemanticKernel; | ||
using Microsoft.SemanticKernel.ChatCompletion; | ||
using Microsoft.SemanticKernel.Connectors.OpenAI; | ||
using Microsoft.SemanticKernel.Plugins.Core.CodeInterpreter; | ||
|
||
#pragma warning disable SKEXP0050 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. | ||
|
||
var configuration = new ConfigurationBuilder() | ||
.AddUserSecrets<Program>() | ||
.AddEnvironmentVariables() | ||
.Build(); | ||
|
||
var apiKey = configuration["OpenAI:ApiKey"]; | ||
var modelId = configuration["OpenAI:ChatModelId"]; | ||
var endpoint = configuration["AzureContainerApps:Endpoint"]; | ||
|
||
// Cached token for the Azure Container Apps service | ||
string? cachedToken = null; | ||
|
||
// Logger for program scope | ||
ILogger logger = NullLogger.Instance; | ||
|
||
ArgumentNullException.ThrowIfNull(apiKey); | ||
ArgumentNullException.ThrowIfNull(modelId); | ||
ArgumentNullException.ThrowIfNull(endpoint); | ||
|
||
/// <summary> | ||
/// Acquire a token for the Azure Container Apps service | ||
/// </summary> | ||
async Task<string> TokenProvider() | ||
{ | ||
if (cachedToken is null) | ||
{ | ||
string resource = "https://acasessions.io/.default"; | ||
var credential = new InteractiveBrowserCredential(); | ||
|
||
// Attempt to get the token | ||
var accessToken = await credential.GetTokenAsync(new Azure.Core.TokenRequestContext([resource])).ConfigureAwait(false); | ||
if (logger.IsEnabled(LogLevel.Information)) | ||
{ | ||
logger.LogInformation("Access token obtained successfully"); | ||
} | ||
cachedToken = accessToken.Token; | ||
} | ||
|
||
return cachedToken; | ||
} | ||
|
||
var settings = new SessionPythonSettings() | ||
{ | ||
Endpoint = new Uri(endpoint), | ||
SessionId = Guid.NewGuid().ToString() | ||
}; | ||
|
||
Console.WriteLine("=== Code Interpreter With Azure Container Apps Plugin Demo ==="); | ||
|
||
var builder = | ||
Kernel.CreateBuilder() | ||
.AddOpenAIChatCompletion(modelId, apiKey); | ||
|
||
// Change the log level to Trace to see more detailed logs | ||
builder.Services.AddLogging(loggingBuilder => loggingBuilder.AddConsole().SetMinimumLevel(LogLevel.Information)); | ||
builder.Services.AddHttpClient(); | ||
builder.Services.AddSingleton((sp) | ||
=> new SessionsPythonPlugin( | ||
settings, | ||
TokenProvider, | ||
sp.GetRequiredService<IHttpClientFactory>(), | ||
sp.GetRequiredService<ILoggerFactory>())); | ||
var kernel = builder.Build(); | ||
|
||
logger = kernel.GetRequiredService<ILoggerFactory>().CreateLogger<Program>(); | ||
kernel.Plugins.AddFromObject(kernel.GetRequiredService<SessionsPythonPlugin>()); | ||
var chatCompletion = kernel.GetRequiredService<IChatCompletionService>(); | ||
|
||
var chatHistory = new ChatHistory(); | ||
|
||
StringBuilder fullAssistantContent = new(); | ||
|
||
do | ||
{ | ||
Console.Write("\nUser: "); | ||
var input = Console.ReadLine(); | ||
if (string.IsNullOrWhiteSpace(input)) { break; } | ||
|
||
chatHistory.AddUserMessage(input); | ||
|
||
Console.WriteLine("Assistant: "); | ||
fullAssistantContent.Clear(); | ||
await foreach (var content in chatCompletion.GetStreamingChatMessageContentsAsync( | ||
chatHistory, | ||
new OpenAIPromptExecutionSettings { ToolCallBehavior = ToolCallBehavior.AutoInvokeKernelFunctions }, | ||
kernel) | ||
.ConfigureAwait(false)) | ||
{ | ||
Console.Write(content.Content); | ||
fullAssistantContent.Append(content.Content); | ||
} | ||
chatHistory.AddAssistantMessage(fullAssistantContent.ToString()); | ||
} while (true); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
# Semantic Kernel - Code Interpreter Plugin with Azure Container Apps | ||
|
||
This example demonstrates how to do AI Code Interpretetion using a Plugin with Azure Container Apps to execute python code in a container. | ||
|
||
## Configuring Secrets | ||
|
||
The example require credentials to access OpenAI and Azure Container Apps (ACA) | ||
|
||
If you have set up those credentials as secrets within Secret Manager or through environment variables for other samples from the solution in which this project is found, they will be re-used. | ||
|
||
### To set your secrets with Secret Manager: | ||
|
||
``` | ||
dotnet user-secrets init | ||
|
||
dotnet user-secrets set "OpenAI:ApiKey" "..." | ||
dotnet user-secrets set "OpenAI:ChatModelId" "gpt-3.5-turbo" # or any other function callable model. | ||
|
||
dotnet user-secrets set "AzureContainerApps:Endpoint" " .. endpoint .. " | ||
``` | ||
|
||
### To set your secrets with environment variables | ||
|
||
Use these names: | ||
|
||
``` | ||
# OpenAI | ||
OpenAI__ApiKey | ||
OpenAI__ChatModelId | ||
|
||
# Azure Container Apps | ||
AzureContainerApps__Endpoint | ||
``` |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
98 changes: 98 additions & 0 deletions
98
dotnet/src/Plugins/Plugins.Core/CodeInterpreter/SessionPythonSettings.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
// Copyright (c) Microsoft. All rights reserved. | ||
|
||
using System; | ||
using System.ComponentModel; | ||
using System.Text.Json.Serialization; | ||
|
||
namespace Microsoft.SemanticKernel.Plugins.Core.CodeInterpreter; | ||
|
||
/// <summary> | ||
/// Settings for a Python session. | ||
/// </summary> | ||
public class SessionPythonSettings | ||
{ | ||
/// <summary> | ||
/// Determines if the input should be sanitized. | ||
/// </summary> | ||
[JsonIgnore] | ||
public bool SanitizeInput { get; set; } | ||
|
||
/// <summary> | ||
/// The target endpoint. | ||
/// </summary> | ||
[JsonIgnore] | ||
public Uri? Endpoint { get; init; } | ||
|
||
/// <summary> | ||
/// The session identifier. | ||
/// </summary> | ||
[JsonPropertyName("identifier")] | ||
public string? SessionId { get; init; } | ||
|
||
/// <summary> | ||
/// Code input type. | ||
/// </summary> | ||
[JsonPropertyName("codeInputType")] | ||
public CodeInputTypeSetting CodeInputType { get; set; } | ||
|
||
/// <summary> | ||
/// Code execution type. | ||
/// </summary> | ||
[JsonPropertyName("executionType")] | ||
public CodeExecutionTypeSetting CodeExecutionType { get; set; } | ||
|
||
/// <summary> | ||
/// Timeout in seconds for the code execution. | ||
/// </summary> | ||
[JsonPropertyName("timeoutInSeconds")] | ||
public int TimeoutInSeconds { get; set; } = 100; | ||
|
||
/// <summary> | ||
/// The Python code to execute. | ||
/// </summary> | ||
[JsonPropertyName("pythonCode")] | ||
public string? PythonCode { get; set; } | ||
|
||
/// <summary> | ||
/// Code input type. | ||
/// </summary> | ||
[Description("Code input type.")] | ||
[JsonConverter(typeof(JsonStringEnumConverter))] | ||
public enum CodeInputTypeSetting | ||
{ | ||
/// <summary> | ||
/// Code is provided as a inline string. | ||
/// </summary> | ||
[Description("Code is provided as a inline string.")] | ||
[JsonPropertyName("inline")] | ||
Inline | ||
} | ||
|
||
/// <summary> | ||
/// Code input type. | ||
/// </summary> | ||
[Description("Code input type.")] | ||
[JsonConverter(typeof(JsonStringEnumConverter))] | ||
public enum CodeExecutionTypeSetting | ||
{ | ||
/// <summary> | ||
/// Code is provided as a inline string. | ||
/// </summary> | ||
[Description("Code is provided as a inline string.")] | ||
[JsonPropertyName("synchronous")] | ||
Synchronous | ||
} | ||
|
||
internal SessionPythonSettings CloneForRequest(string pythonCode) | ||
{ | ||
return new SessionPythonSettings | ||
{ | ||
SanitizeInput = this.SanitizeInput, | ||
SessionId = this.SessionId, | ||
CodeInputType = this.CodeInputType, | ||
CodeExecutionType = this.CodeExecutionType, | ||
TimeoutInSeconds = this.TimeoutInSeconds, | ||
PythonCode = pythonCode | ||
}; | ||
} | ||
} |
50 changes: 50 additions & 0 deletions
50
dotnet/src/Plugins/Plugins.Core/CodeInterpreter/SessionRemoteFileMetadata.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
// Copyright (c) Microsoft. All rights reserved. | ||
|
||
using System; | ||
using System.ComponentModel; | ||
using System.Text.Json.Serialization; | ||
|
||
namespace Microsoft.SemanticKernel.Plugins.Core.CodeInterpreter; | ||
|
||
/// <summary> | ||
/// Metadata for a file in the session. | ||
/// </summary> | ||
public class SessionRemoteFileMetadata | ||
{ | ||
/// <summary> | ||
/// Initializes a new instance of the SessionRemoteFileMetadata class. | ||
/// </summary> | ||
[JsonConstructor] | ||
public SessionRemoteFileMetadata(string filename, int size) | ||
{ | ||
this.Filename = filename; | ||
this.Size = size; | ||
} | ||
|
||
/// <summary> | ||
/// The filename relative to `/mnt/data`. | ||
/// </summary> | ||
[Description("The filename relative to `/mnt/data`.")] | ||
[JsonPropertyName("filename")] | ||
public string Filename { get; set; } | ||
|
||
/// <summary> | ||
/// The size of the file in bytes. | ||
/// </summary> | ||
[Description("The size of the file in bytes.")] | ||
[JsonPropertyName("size")] | ||
public int Size { get; set; } | ||
|
||
/// <summary> | ||
/// The last modified time. | ||
/// </summary> | ||
[Description("Last modified time.")] | ||
[JsonPropertyName("last_modified_time")] | ||
public DateTime? LastModifiedTime { get; set; } | ||
|
||
/// <summary> | ||
/// The full path of the file. | ||
/// </summary> | ||
[Description("The full path of the file.")] | ||
public string FullPath => $"/mnt/data/{this.Filename}"; | ||
} |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.