remove vestigal workflows app (#217)

This commit is contained in:
Ryan Sweet 2024-07-15 11:04:20 -07:00 committed by GitHub
parent ec500a31b8
commit e409f020e6
16 changed files with 0 additions and 874 deletions

View File

@ -1,8 +0,0 @@
# Replace with your own values
export SERVICETYPE=AzureOpenAI
export SERVICEID=gpt-4
export DEPLOYMENTORMODELID=gpt-4
export EMBEDDINGDEPLOYMENTORMODELID=text-embedding-ada-002
export ENDPOINT="Error - you mus update your OpenAI Endpoint"
export APIKEY="Error - you must update your OpenAPI or Azure API key"

View File

@ -1,204 +0,0 @@
using System.Reflection;
using Azure;
using Azure.AI.OpenAI;
using Elsa.Extensions;
using Elsa.Workflows;
using Elsa.Workflows.Contracts;
using Elsa.Workflows.Models;
using Elsa.Workflows.UIHints;
using Microsoft.Extensions.Http.Resilience;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.Connectors.OpenAI;
using Microsoft.SKDevTeam;
namespace Elsa.SemanticKernel;
//<summary>
// Loads the Semantic Kernel skills and then generates activites for each skill
//</summary>
public class SemanticKernelActivityProvider : IActivityProvider
{
private readonly IActivityFactory _activityFactory;
private readonly IActivityDescriber _activityDescriber;
public SemanticKernelActivityProvider(IActivityFactory activityFactory, IActivityDescriber activityDescriber)
{
_activityFactory = activityFactory;
_activityDescriber = activityDescriber;
}
public ValueTask<IEnumerable<ActivityDescriptor>> GetDescriptorsAsync(CancellationToken cancellationToken = default)
{
// get the kernel
var kernel = KernelBuilder();
// get a list of skills in the assembly
_ = LoadSkillsFromAssemblyAsync("skills", kernel);
var functionsAvailable = kernel.Plugins.GetFunctionsMetadata();
// create activity descriptors for each skill and function
var activities = new List<ActivityDescriptor>();
foreach (var function in functionsAvailable)
{
Console.WriteLine($"Creating Activities for Plugin: {function.PluginName}");
activities.Add(CreateActivityDescriptorFromSkillAndFunction(function));
}
return new(activities);
}
/// <summary>
/// Creates an activity descriptor from a skill and function.
/// </summary>
/// <param name="function">The semantic kernel function</param>
/// <returns>An activity descriptor.</returns>
private ActivityDescriptor CreateActivityDescriptorFromSkillAndFunction(KernelFunctionMetadata function)
{
// Create a fully qualified type name for the activity
var thisNamespace = GetType().Namespace;
var fullTypeName = $"{thisNamespace}.{function.PluginName}.{function.Name}";
Console.WriteLine($"Creating Activity: {fullTypeName}");
// create inputs from the function parameters - the SemanticKernelSkill activity will be the base for each activity
var inputs = new List<InputDescriptor>();
foreach (var p in function.Parameters) { inputs.Add(CreateInputDescriptorFromSKParameter(p)); }
inputs.Add(CreateInputDescriptor(typeof(string), "SkillName", function.PluginName!, "The name of the skill to use (generated, do not change)"));
inputs.Add(CreateInputDescriptor(typeof(string), "FunctionName", function.Name, "The name of the function to use (generated, do not change)"));
inputs.Add(CreateInputDescriptor(typeof(int), "MaxRetries", KernelSettings.DefaultMaxRetries, "Max Retries to contact AI Service"));
return new ActivityDescriptor
{
Kind = ActivityKind.Task,
Category = "Semantic Kernel",
Description = function.Description,
Name = function.Name,
TypeName = fullTypeName,
Namespace = $"{thisNamespace}.{function.PluginName}",
DisplayName = $"{function.PluginName}.{function.Name}",
Inputs = inputs,
Outputs = new[] { new OutputDescriptor() },
Constructor = context =>
{
// The constructor is called when an activity instance of this type is requested.
// Create the activity instance.
var activityInstance = _activityFactory.Create<SemanticKernelSkill>(context);
// Customize the activity type name.
activityInstance.Type = fullTypeName;
// Configure the activity's URL and method properties.
activityInstance.SkillName = new Input<string>(function.PluginName!);
activityInstance.FunctionName = new Input<string>(function.Name);
return activityInstance;
}
};
}
/// <summary>
/// Creates an input descriptor for a single line string
/// </summary>
/// <param name="inputType">The input type.</param>
/// <param name="name">The name of the input field</param>
/// <param name="defaultValue">The default value.</param>
/// <param name="description">The description of the input field</param>
private static InputDescriptor CreateInputDescriptor(Type inputType, string name, object defaultValue, string description)
{
var inputDescriptor = new InputDescriptor
{
Description = description,
DefaultValue = defaultValue,
Type = inputType,
Name = name,
DisplayName = name,
IsSynthetic = true, // This is a synthetic property, i.e. it is not part of the activity's .NET type.
IsWrapped = true, // This property is wrapped within an Input<T> object.
UIHint = InputUIHints.SingleLine,
ValueGetter = activity => activity.SyntheticProperties.GetValueOrDefault(name),
ValueSetter = (activity, value) => activity.SyntheticProperties[name] = value!,
};
return inputDescriptor;
}
/// <summary>
/// Creates an input descriptor from an sk funciton parameter definition.
/// </summary>
/// <param name="parameter">The function parameter.</param>
/// <returns>An input descriptor.</returns>
private static InputDescriptor CreateInputDescriptorFromSKParameter(KernelParameterMetadata parameter)
{
var inputDescriptor = new InputDescriptor
{
Description = string.IsNullOrEmpty(parameter.Description) ? parameter.Name : parameter.Description,
DefaultValue = parameter.DefaultValue ?? string.Empty,
Type = typeof(string),
Name = parameter.Name,
DisplayName = parameter.Name,
IsSynthetic = true, // This is a synthetic property, i.e. it is not part of the activity's .NET type.
IsWrapped = true, // This property is wrapped within an Input<T> object.
UIHint = InputUIHints.MultiLine,
ValueGetter = activity => activity.SyntheticProperties.GetValueOrDefault(parameter.Name),
ValueSetter = (activity, value) => activity.SyntheticProperties[parameter.Name] = value!,
};
return inputDescriptor;
}
///<summary>
/// Gets a list of the skills in the assembly
///</summary>
private static IEnumerable<string> LoadSkillsFromAssemblyAsync(string assemblyName, Kernel kernel)
{
var skills = new List<string>();
var assembly = Assembly.Load(assemblyName);
Type[] skillTypes = assembly.GetTypes().ToArray();
foreach (Type skillType in skillTypes)
{
if (string.Equals("Microsoft.AI.DevTeam", skillType.Namespace))
{
skills.Add(skillType.Name);
var functions = skillType.GetFields();
foreach (var function in functions)
{
string field = function.FieldType.ToString();
if (field.Equals("Microsoft.AI.DevTeam.SemanticFunctionConfig"))
{
var promptTemplate = SemanticFunctionConfig.ForSkillAndFunction(skillType.Name, function.Name);
var skfunc = kernel.CreateFunctionFromPrompt(
promptTemplate.PromptTemplate, new OpenAIPromptExecutionSettings { MaxTokens = 8000, Temperature = 0.4, TopP = 1 });
Console.WriteLine($"SKActivityProvider Added SK function: {skfunc.Metadata.PluginName}.{skfunc.Name}");
}
}
}
}
return skills;
}
/// <summary>
/// Gets a semantic kernel instance
/// </summary>
/// <returns>Microsoft.SemanticKernel.IKernel</returns>
private static Kernel KernelBuilder()
{
var kernelSettings = KernelSettings.LoadSettings();
var clientOptions = new OpenAIClientOptions();
clientOptions.Retry.NetworkTimeout = TimeSpan.FromMinutes(5);
var openAIClient = new OpenAIClient(new Uri(kernelSettings.Endpoint), new AzureKeyCredential(kernelSettings.ApiKey), clientOptions);
var builder = Kernel.CreateBuilder();
builder.Services.AddLogging(c => c.AddConsole().AddDebug().SetMinimumLevel(LogLevel.Debug));
builder.Services.AddAzureOpenAIChatCompletion(kernelSettings.DeploymentOrModelId, openAIClient);
builder.Services.ConfigureHttpClientDefaults(c =>
{
c.AddStandardResilienceHandler().Configure(o =>
{
o.Retry.MaxRetryAttempts = 5;
o.Retry.BackoffType = Polly.DelayBackoffType.Exponential;
});
});
return builder.Build();
}
}

View File

@ -1,187 +0,0 @@
using Elsa.Extensions;
using JetBrains.Annotations;
using System.Text;
using System.Reflection;
using Elsa.Workflows;
using Elsa.Workflows.Attributes;
using Elsa.Workflows.UIHints;
using Elsa.Workflows.Models;
using Microsoft.SKDevTeam;
using Microsoft.SemanticKernel.Connectors.OpenAI;
using Microsoft.SemanticKernel;
using Azure.AI.OpenAI;
using Azure;
using Microsoft.Extensions.Http.Resilience;
using System.Globalization;
namespace Elsa.SemanticKernel;
/// <summary>
/// Invoke a Semantic Kernel skill.
/// </summary>
[Activity("Elsa", "Semantic Kernel", "Invoke a Semantic Kernel skill. ", DisplayName = "Generic Semantic Kernel Skill", Kind = ActivityKind.Task)]
[PublicAPI]
public class SemanticKernelSkill : CodeActivity<string>
{
[Input(
Description = "System Prompt",
UIHint = InputUIHints.MultiLine,
DefaultValue = PromptDefaults.SystemPrompt)]
public Input<string> SysPrompt { get; set; } = default!;
[Input(
Description = "User Input Prompt",
UIHint = InputUIHints.MultiLine,
DefaultValue = PromptDefaults.UserPrompt)]
public Input<string> Prompt { get; set; } = default!;
[Input(
Description = "The skill to invoke from the semantic kernel",
UIHint = InputUIHints.SingleLine,
DefaultValue = "Chat")]
public Input<string> SkillName { get; set; } = default!;
[Input(
Description = "The function to invoke from the skill",
UIHint = InputUIHints.SingleLine,
DefaultValue = "ChatCompletion")]
public Input<string> FunctionName { get; set; } = default!;
/* [Input(
Description = "Mockup - don't actually call the AI, just output the prompts",
UIHint = InputUIHints.Checkbox,
DefaultValue = false)]
public Input<bool> Mockup { get; set; } */
/// <inheritdoc />
protected override async ValueTask ExecuteAsync(ActivityExecutionContext workflowContext)
{
var skillName = SkillName.Get(workflowContext);
var functionName = FunctionName.Get(workflowContext);
var prompt = Prompt.Get(workflowContext);
//var mockup = Mockup.Get(workflowContext);
var mockup = false;
string info = ($"#################\nSkill: {skillName}\nFunction: {functionName}\nPrompt: {prompt}\n#################\n\n");
if (mockup)
{
workflowContext.SetResult(info);
}
else
{
// get the kernel
var kernel = KernelBuilder();
// load the skill
var promptTemplate = SemanticFunctionConfig.ForSkillAndFunction(skillName, functionName);
var function = kernel.CreateFunctionFromPrompt(promptTemplate.PromptTemplate, new OpenAIPromptExecutionSettings { MaxTokens = 8000, Temperature = 0.4, TopP = 1 });
// set the context (our prompt)
var arguments = new KernelArguments
{
["input"] = prompt
};
var answer = await kernel.InvokeAsync(function, arguments);
workflowContext.SetResult(answer);
}
}
/// <summary>
/// Load the skills into the kernel
/// </summary>
private string ListSkillsInKernel(Kernel kernel)
{
_ = LoadSkillsFromAssemblyAsync("skills", kernel);
var functionsAvailable = kernel.Plugins.GetFunctionsMetadata();
var list = new StringBuilder();
foreach (var function in functionsAvailable)
{
Console.WriteLine($"Skill: {function.PluginName}");
// Function description
if (function.Description != null)
{
list.AppendLine($"// {function.Description}");
}
else
{
Console.WriteLine("{0}.{1} is missing a description", function.PluginName, function.Name);
list.AppendLine($"// Function {function.PluginName}.{function.Name}.");
}
// Function name
list.AppendLine($"{function.PluginName}.{function.Name}");
// Function parameters
foreach (var p in function.Parameters)
{
var description = string.IsNullOrEmpty(p.Description) ? p.Name : p.Description;
var defaultValueString = p.DefaultValue == null ? string.Empty : $" (default value: {p.DefaultValue})";
list.AppendLine(CultureInfo.InvariantCulture, $"Parameter \"{p.Name}\": {description} {defaultValueString}");
}
}
Console.WriteLine($"List of all skills ----- {list.ToString()}");
return list.ToString();
}
/// <summary>
/// Gets a semantic kernel instance
/// </summary>
/// <returns>Microsoft.SemanticKernel.IKernel</returns>
private static Kernel KernelBuilder()
{
var kernelSettings = KernelSettings.LoadSettings();
var clientOptions = new OpenAIClientOptions();
clientOptions.Retry.NetworkTimeout = TimeSpan.FromMinutes(5);
var openAIClient = new OpenAIClient(new Uri(kernelSettings.Endpoint), new AzureKeyCredential(kernelSettings.ApiKey), clientOptions);
var builder = Kernel.CreateBuilder();
builder.Services.AddLogging(c => c.AddConsole().AddDebug().SetMinimumLevel(LogLevel.Debug));
builder.Services.AddAzureOpenAIChatCompletion(kernelSettings.DeploymentOrModelId, openAIClient);
builder.Services.ConfigureHttpClientDefaults(c =>
{
c.AddStandardResilienceHandler().Configure(o =>
{
o.Retry.MaxRetryAttempts = 5;
o.Retry.BackoffType = Polly.DelayBackoffType.Exponential;
});
});
return builder.Build();
}
///<summary>
/// Gets a list of the skills in the assembly
///</summary>
private static IEnumerable<string> LoadSkillsFromAssemblyAsync(string assemblyName, Kernel kernel)
{
var skills = new List<string>();
var assembly = Assembly.Load(assemblyName);
Type[] skillTypes = assembly.GetTypes().ToArray();
foreach (Type skillType in skillTypes)
{
if (string.Equals("Microsoft.SKDevTeam", skillType.Namespace))
{
skills.Add(skillType.Name);
var functions = skillType.GetFields();
foreach (var function in functions)
{
string field = function.FieldType.ToString();
if (field.Equals("Microsoft.SKDevTeam.SemanticFunctionConfig"))
{
var prompt = SemanticFunctionConfig.ForSkillAndFunction(skillType.Name, function.Name);
var skfunc = kernel.CreateFunctionFromPrompt(
prompt.PromptTemplate, new OpenAIPromptExecutionSettings { MaxTokens = 8000, Temperature = 0.4, TopP = 1 });
Console.WriteLine($"SK Added function: {skfunc.Metadata.PluginName}.{skfunc.Metadata.Name}");
}
}
}
}
return skills;
}
}

View File

@ -1,91 +0,0 @@
using System.Text.Json.Serialization;
internal sealed class KernelSettings
{
public const string DefaultConfigFile = "config/appsettings.json";
public const string OpenAI = "OPENAI";
public const string AzureOpenAI = "AZUREOPENAI";
public const int DefaultMaxRetries = 9;
[JsonPropertyName("serviceType")]
public string ServiceType { get; set; } = string.Empty;
[JsonPropertyName("serviceId")]
public string ServiceId { get; set; } = string.Empty;
[JsonPropertyName("deploymentOrModelId")]
public string DeploymentOrModelId { get; set; } = string.Empty;
[JsonPropertyName("embeddingDeploymentOrModelId")]
public string EmbeddingDeploymentOrModelId { get; set; } = string.Empty;
[JsonPropertyName("endpoint")]
public string Endpoint { get; set; } = string.Empty;
[JsonPropertyName("apiKey")]
public string ApiKey { get; set; } = string.Empty;
[JsonPropertyName("orgId")]
public string OrgId { get; set; } = string.Empty;
[JsonPropertyName("logLevel")]
public LogLevel? LogLevel { get; set; }
/// <summary>
/// Load the kernel settings from settings.json if the file exists and if not attempt to use user secrets.
/// </summary>
internal static KernelSettings LoadSettings()
{
try
{
if (File.Exists(DefaultConfigFile))
{
return FromFile(DefaultConfigFile);
}
Console.WriteLine($"Semantic kernel settings '{DefaultConfigFile}' not found, attempting to load configuration from user secrets.");
return FromUserSecrets();
}
catch (InvalidDataException ide)
{
Console.Error.WriteLine(
"Unable to load semantic kernel settings, please provide configuration settings using instructions in the README.\n" +
"Please refer to: https://github.com/microsoft/semantic-kernel-starters/blob/main/sk-csharp-hello-world/README.md#configuring-the-starter"
);
throw new InvalidOperationException(ide.Message);
}
}
/// <summary>
/// Load the kernel settings from the specified configuration file if it exists.
/// </summary>
internal static KernelSettings FromFile(string configFile = DefaultConfigFile)
{
if (!File.Exists(configFile))
{
throw new FileNotFoundException($"Configuration not found: {configFile}");
}
var configuration = new ConfigurationBuilder()
.SetBasePath(System.IO.Directory.GetCurrentDirectory())
.AddJsonFile(configFile, optional: true, reloadOnChange: true)
.Build();
return configuration.Get<KernelSettings>()
?? throw new InvalidDataException($"Invalid semantic kernel settings in '{configFile}', please provide configuration settings using instructions in the README.");
}
/// <summary>
/// Load the kernel settings from user secrets.
/// </summary>
internal static KernelSettings FromUserSecrets()
{
var configuration = new ConfigurationBuilder()
.AddUserSecrets<KernelSettings>()
.AddEnvironmentVariables()
.Build();
return configuration.Get<KernelSettings>()
?? throw new InvalidDataException("Invalid semantic kernel settings in user secrets, please provide configuration settings using instructions in the README.");
}
}

View File

@ -1,8 +0,0 @@
internal static class PromptDefaults
{
public const string SystemPrompt = @"You are fulfilling roles on a software development team.
Provide a response to the following prompt, do not provide any additional output.";
public const string UserPrompt = @"Let's build a ToDoList Application!";
}

View File

@ -1,22 +0,0 @@
@page "/"
@{
var serverUrl = $"{Request.Scheme}://{Request.Host}{Request.PathBase}{Request.Path}";
var apiUrl = serverUrl + "elsa/api";
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>Elsa Workflows 3.0</title>
<link rel="stylesheet" href="https://rsms.me/inter/inter.css">
<link rel="stylesheet" href="_content/Elsa.Workflows.Designer/elsa-workflows-designer/elsa-workflows-designer.css">
<script src="_content/Elsa.Workflows.Designer/monaco-editor/min/vs/loader.js"></script>
<script type="module" src="_content/Elsa.Workflows.Designer/elsa-workflows-designer/elsa-workflows-designer.esm.js"></script>
</head>
<body>
<elsa-studio server="@apiUrl" monaco-lib-path="/_content/Elsa.Workflows.Designer/monaco-editor/min"></elsa-studio>
</body>
</html>

View File

@ -1,2 +0,0 @@
@namespace WorkflowsApp.Pages
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

View File

@ -1,54 +0,0 @@
using Elsa.EntityFrameworkCore.Extensions;
using Elsa.EntityFrameworkCore.Modules.Management;
using Elsa.EntityFrameworkCore.Modules.Runtime;
using Elsa.Extensions;
using Elsa.SemanticKernel;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddElsa(elsa =>
{
// Configure management feature to use EF Core.
elsa.UseWorkflowManagement(management => management.UseEntityFrameworkCore(ef => ef.UseSqlite()));
elsa.UseWorkflowRuntime(runtime => runtime.UseEntityFrameworkCore());
// Expose API endpoints.
elsa.UseWorkflowsApi();
// Add services for HTTP activities and workflow middleware.
elsa.UseHttp();
// Configure identity so that we can create a default admin user.
elsa.UseIdentity(identity =>
{
identity.UseAdminUserProvider();
identity.TokenOptions = options => options.SigningKey = "secret-token-signing-key";
});
// Use default authentication (JWT + API Key).
elsa.UseDefaultAuthentication(auth => auth.UseAdminApiKey());
// Add Semantic Kernel skill.
elsa.AddActivity<SemanticKernelSkill>();
});
// Add dynamic Activity Provider for SK skills.
builder.Services.AddActivityProvider<SemanticKernelActivityProvider>();
// Add Razor pages.
builder.Services.AddRazorPages();
var app = builder.Build();
// Configure the HTTP request pipeline.
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseAuthentication();
app.UseAuthorization();
app.UseWorkflowsApi();
app.UseWorkflows();
app.MapRazorPages();
app.Run();

View File

@ -1,37 +0,0 @@
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:10492",
"sslPort": 44312
}
},
"profiles": {
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"applicationUrl": "http://localhost:5181",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"https": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"applicationUrl": "https://localhost:7077;http://localhost:5181",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}

View File

@ -1,64 +0,0 @@
# SemanticKernel Activity Provider for Elsa Workflows 3.x
The project supports running [Microsoft Semantic Kernel](https://github.com/microsoft/semantic-kernel) Skills as workflows using [Elsa Workflows](https://v3.elsaworkflows.io). You can build the workflows as .NET code or in the visual designer.
To run the designer:
```bash
> cd WorkflowsApp
> cp .env_example .env
# Edit the .env file to choose your AI model, add your API Endpoint, and secrets.
> . ./.env
> dotnet build
> dotnet run
# Open browser to the URI in the console output
```
By Default you can use "admin" and "password" to login. Please review [Workflow Security](https://v3.elsaworkflows.io/docs/installation/aspnet-apps-workflow-server) for into on securing the app, using API tokens, and more.
To [invoke](https://v3.elsaworkflows.io/docs/guides/invoking-workflows) a workflow, first it must be "Published". If your workflow has a trigger activity, you can use that. When your workflow is ready, click the "Publish" button. You can also execute the workflow using the API. Then, find the Workflow Definition ID. From a command line, you can use "curl":
```bash
> curl --location 'https://localhost:5001/elsa/api/workflow-definitions/{workflow_definition_id}/execute' \
--header 'Content-Type: application/json' \
--header 'Authorization: ApiKey {api_key}' \
--data '{
}'
```
Once you have the app runing locally, you can login (admin/password - see the [Elsa Workflows](https://v3.elsaworkflows.io) for info about securing). Then you can click "new workflow" to begin building your workflow with semantic kernel skills.
1. Drag workflow Activity blocks into the designer, and examine the settings.
2. Connect the Activities to specify an order of operations.
3. You can use Workfflow Variables to pass state between activities.
1. Create a Workflow Variable, "MyVariable"
2. Click on the Activity that you want to use to populate the variable.
3. In the Settings box for the Activity, Click "Output"
4. Set the "Output" to the variable chosen.
5. Click the Activity that will use the variable. Click on "Settings".
6. Find the text box representing the variable that you want to populate, in this case usually "input".
7. Click the "..." widget above the text box, and select "javascript"
8. Set the value of the text box to
```javascript
`${getMyVariable()}`
```
9. Run the workflow.
## Run via codespaces
The easiest way to run the project is in Codespaces. Codespaces will start a qdrant instance for you.
1. Create a new codespace from the *code* button on the main branch.
2. Once the code space setup is finished, from the terminal:
```bash
> cd cli
cli> cp ../WorkflowsApp/.env_example .
# Edit the .env file to choose your AI model, add your API Endpoint, and secrets.
cli> bash .env
cli> dotnet build
cli> dotnet run --file util/ToDoListSamplePrompt.txt do it
```
You will find the output in the *output/* directory.

View File

@ -1,48 +0,0 @@
namespace Microsoft.SKDevTeam;
public static class DevLead
{
public static SemanticFunctionConfig Plan = new SemanticFunctionConfig
{
PromptTemplate = """
You are a Dev Lead for an application team, building the application described below.
Please break down the steps and modules required to develop the complete application, describe each step in detail.
Make prescriptive architecture, language, and frameowrk choices, do not provide a range of choices.
For each step or module then break down the steps or subtasks required to complete that step or module.
For each subtask write an LLM prompt that would be used to tell a model to write the coee that will accomplish that subtask. If the subtask involves taking action/running commands tell the model to write the script that will run those commands.
In each LLM prompt restrict the model from outputting other text that is not in the form of code or code comments.
Please output a JSON array data structure, in the precise schema shown below, with a list of steps and a description of each step, and the steps or subtasks that each requires, and the LLM prompts for each subtask.
Example:
{
"steps": [
{
"step": "1",
"description": "This is the first step",
"subtasks": [
{
"subtask": "Subtask 1",
"description": "This is the first subtask",
"prompt": "Write the code to do the first subtask"
},
{
"subtask": "Subtask 2",
"description": "This is the second subtask",
"prompt": "Write the code to do the second subtask"
}
]
}
]
}
Do not output any other text.
Input: {{$input}}
{{$wafContext}}
""",
Name = nameof(Plan),
SkillName = nameof(DevLead),
Description = "From a simple description of an application output a development plan for building the application.",
MaxTokens = 6500,
Temperature = 0.0,
TopP = 0.0,
PPenalty = 0.0,
FPenalty = 0.0
};
}

View File

@ -1,47 +0,0 @@
namespace Microsoft.SKDevTeam;
public static class Developer
{
public static SemanticFunctionConfig Implement = new SemanticFunctionConfig
{
PromptTemplate = """
You are a Developer for an application.
Please output the code required to accomplish the task assigned to you below and wrap it in a bash script that creates the files.
Do not use any IDE commands and do not build and run the code.
Make specific choices about implementation. Do not offer a range of options.
Use comments in the code to describe the intent. Do not include other text other than code and code comments.
Input: {{$input}}
{{$wafContext}}
""",
Name = nameof(Implement),
SkillName = nameof(Developer),
Description = "From a description of a coding task out put the code or scripts necessary to complete the task.",
MaxTokens = 6500,
Temperature = 0.0,
TopP = 0.0,
PPenalty = 0.0,
FPenalty = 0.0
};
public static SemanticFunctionConfig Improve = new SemanticFunctionConfig
{
PromptTemplate = """
You are a Developer for an application. Your job is to imrove the code that you are given in the input below.
Please output a new version of code that fixes any problems with this version.
If there is an error message in the input you should fix that error in the code.
Wrap the code output up in a bash script that creates the necessary files by overwriting any previous files.
Do not use any IDE commands and do not build and run the code.
Make specific choices about implementation. Do not offer a range of options.
Use comments in the code to describe the intent. Do not include other text other than code and code comments.
Input: {{$input}}
{{$wafContext}}
""",
Name = nameof(Improve),
SkillName = nameof(Developer),
Description = "From a description of a coding task out put the code or scripts necessary to complete the task.",
MaxTokens = 6500,
Temperature = 0.0,
TopP = 0.0,
PPenalty = 0.0,
FPenalty = 0.0
};
}

View File

@ -1,42 +0,0 @@
namespace Microsoft.SKDevTeam;
public static class PM
{
public static SemanticFunctionConfig BootstrapProject = new SemanticFunctionConfig
{
PromptTemplate = """
Please write a bash script with the commands that would be required to generate applications as described in the following input.
You may add comments to the script and the generated output but do not add any other text except the bash script.
You may include commands to build the applications but do not run them.
Do not include any git commands.
Input: {{$input}}
{{$wafContext}}
""",
Name = nameof(BootstrapProject),
SkillName = nameof(PM),
Description = "Bootstrap a new project",
MaxTokens = 6500,
Temperature = 0.0,
TopP = 0.0,
PPenalty = 0.0,
FPenalty = 0.0
};
public static SemanticFunctionConfig Readme = new SemanticFunctionConfig
{
PromptTemplate = """
You are a program manager on a software development team. You are working on an app described below.
Based on the input below, and any dialog or other context, please output a raw README.MD markdown file documenting the main features of the app and the architecture or code organization.
Do not describe how to create the application.
Write the README as if it were documenting the features and architecture of the application. You may include instructions for how to run the application.
Input: {{$input}}
{{$wafContext}}
""",
Name = nameof(Readme),
SkillName = nameof(PM),
Description = "From a simple description output a README.md file for a GitHub repository.",
MaxTokens = 6500,
Temperature = 0.0,
TopP = 0.0,
PPenalty = 0.0,
FPenalty = 0.0
};
}

View File

@ -1,23 +0,0 @@
namespace Microsoft.SKDevTeam;
public class SemanticFunctionConfig
{
public required string PromptTemplate { get; set; }
public required string Name { get; set; }
public required string SkillName { get; set; }
public required string Description { get; set; }
public int MaxTokens { get; set; }
public double Temperature { get; set; }
public double TopP { get; set; }
public double PPenalty { get; set; }
public double FPenalty { get; set; }
public static SemanticFunctionConfig ForSkillAndFunction(string skillName, string functionName) =>
(skillName, functionName) switch
{
(nameof(PM), nameof(PM.Readme)) => PM.Readme,
(nameof(DevLead), nameof(DevLead.Plan)) => DevLead.Plan,
(nameof(Developer), nameof(Developer.Implement)) => Developer.Implement,
(nameof(Developer), nameof(Developer.Improve)) => Developer.Improve,
_ => throw new ArgumentException($"Unable to find {skillName}.{functionName}")
};
}

View File

@ -1,29 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Elsa.EntityFrameworkCore" />
<PackageReference Include="Elsa.EntityFrameworkCore.Sqlite" />
<PackageReference Include="Elsa.Identity" />
<PackageReference Include="Elsa" />
<PackageReference Include="Elsa.Http" />
<PackageReference Include="Elsa.Workflows.Api" />
<PackageReference Include="Elsa.Workflows.Core" />
<PackageReference Include="Elsa.Workflows.Management" />
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" />
<PackageReference Include="Microsoft.Extensions.Logging.Debug" />
<PackageReference Include="Microsoft.Extensions.Hosting" />
<PackageReference Include="Microsoft.Extensions.Caching.Abstractions" />
<PackageReference Include="AspNetCore.Authentication.ApiKey" />
<PackageReference Include="Microsoft.Extensions.Http.Resilience" />
<PackageReference Include="Elsa.Workflows.Designer" />
<PackageReference Include="Microsoft.SemanticKernel" />
</ItemGroup>
</Project>

View File

@ -1,8 +0,0 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
}