Skip to content
Open
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
7 changes: 7 additions & 0 deletions dotnet/SK-dotnet.sln
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "JavaSkillRunner", "..\sampl
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DotnetReferenceSkill", "..\samples\dotnet\DotnetReferenceSkill\DotnetReferenceSkill.csproj", "{D49FC00D-3102-43B6-8120-093EF2FACA03}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GrpcSkillRunner", "..\samples\dotnet\GrpcSkillRunner\GrpcSkillRunner.csproj", "{A2A10C59-4EE4-46C7-8BF7-00317AA1E5AD}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -148,6 +150,10 @@ Global
{D49FC00D-3102-43B6-8120-093EF2FACA03}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D49FC00D-3102-43B6-8120-093EF2FACA03}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D49FC00D-3102-43B6-8120-093EF2FACA03}.Release|Any CPU.Build.0 = Release|Any CPU
{A2A10C59-4EE4-46C7-8BF7-00317AA1E5AD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A2A10C59-4EE4-46C7-8BF7-00317AA1E5AD}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A2A10C59-4EE4-46C7-8BF7-00317AA1E5AD}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A2A10C59-4EE4-46C7-8BF7-00317AA1E5AD}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -174,6 +180,7 @@ Global
{8FBB03E4-7402-40D3-8A8A-BA1F327F6BF8} = {0E881C20-29A5-454D-97D0-9FEC762BBEFF}
{5EB48620-02BE-4143-ABF8-F415D413EFE7} = {0E881C20-29A5-454D-97D0-9FEC762BBEFF}
{D49FC00D-3102-43B6-8120-093EF2FACA03} = {0E881C20-29A5-454D-97D0-9FEC762BBEFF}
{A2A10C59-4EE4-46C7-8BF7-00317AA1E5AD} = {0E881C20-29A5-454D-97D0-9FEC762BBEFF}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {FBDC56A3-86AD-4323-AA0F-201E59123B83}
Expand Down
19 changes: 19 additions & 0 deletions samples/dotnet/GrpcSkillRunner/GrpcSkillRunner.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net7.0</TargetFramework>
</PropertyGroup>

<ItemGroup>
<Protobuf Include="Protos\activity.proto" GrpcServices="Client" />

<PackageReference Include="Google.Protobuf" Version="3.22.1" />
<PackageReference Include="Grpc.Net.Client" Version="2.52.0" />
<PackageReference Include="Grpc.Tools" Version="2.53.0" PrivateAssets="All" />

<ProjectReference Include="..\..\..\dotnet\src\SemanticKernel\SemanticKernel.csproj" />
<ProjectReference Include="..\DotnetReferenceSkill\DotnetReferenceSkill.csproj" />
</ItemGroup>

</Project>
81 changes: 81 additions & 0 deletions samples/dotnet/GrpcSkillRunner/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
// Copyright (c) Microsoft. All rights reserved.

using System;
using System.Collections.Generic;
using System.Text.Json;
using Grpc.Net.Client;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.KernelExtensions;
using Microsoft.SemanticKernel.Orchestration;
using ReferenceSkill;

const string RANDOM_ACTIVITY_PROMPT = "Find me an activity to do, return only a single activity. I like to {{$INPUT}}. Be creative!";
const string DEGREES_OF_SEPARATION_PROMPT = "How many degrees of separation are there between {{$ITEM1}} and {{$ITEM2}}? Bonus points for Kevin Bacon reference.";
const string THING_I_LIKE_TO_DO = "surf";

//configure your Azure OpenAI backend
var key = "";
var endpoint = "";
var model = "";

//configure gRPC server address
const string DEFAULT_GRPC_SERVER_ADDRESS = "http://localhost:50051";

var sk = Kernel.Builder.Configure(c => c.AddAzureOpenAICompletionBackend(model, model, endpoint, key)).Build();

#region Semantic Function Loading

sk.CreateSemanticFunction(RANDOM_ACTIVITY_PROMPT,
skillName: "RandomActivityLLMSkill",
functionName: "GetRandomActivity",
description: "Finds a random activity based on the interest input",
maxTokens: 256,
temperature: 0.1,
topP: 0.5);

sk.CreateSemanticFunction(DEGREES_OF_SEPARATION_PROMPT,
skillName: "DegreesOfSeparation",
functionName: "FindDegrees",
description: "Returns the degrees of separation between two concepts.",
maxTokens: 256,
temperature: 0.2,
topP: 0.5);

#endregion

//TODO: load your python skill here
//currently loading a skill that will pull a random activity from an API.
//We will compare the activity to the one from the LLM and return true if they match, false if not
// var randomActivitySkill = new RandomActivitySkill();
// sk.ImportSkill(randomActivitySkill, nameof(RandomActivitySkill));

var llmResult = string.Empty;
var apiResult = string.Empty;

//ask the LLM for a random activity
var llmRandomActivityResult = await sk.RunAsync(THING_I_LIKE_TO_DO, sk.Skills.GetSemanticFunction("RandomActivityLLMSkill", "GetRandomActivity"));
llmResult = llmRandomActivityResult.Result;
Console.WriteLine("LLM suggested: " + llmResult);

//ask the skill to find us a random activity via gRPC
var serverAddress = Environment.GetEnvironmentVariable("GRPC_SERVER_ADDRESS") ?? DEFAULT_GRPC_SERVER_ADDRESS;
using var channel = GrpcChannel.ForAddress(serverAddress);

// Create client for random activity skill
var randomActivityClient = new RandomActivitySkill.RandomActivitySkillClient(channel);

// Call gRPC service to get random activity
var randomActivityResponse = await randomActivityClient.GetRandomActivityAsync(new GetRandomActivityRequest { Input = THING_I_LIKE_TO_DO });
apiResult = JsonSerializer.Deserialize<Dictionary<string, object>>(randomActivityResponse.Activity)["activity"].ToString();
Console.WriteLine($"Random Activity: {apiResult}");

Console.WriteLine("Press any key to exit...");
Console.ReadKey();

//lastly, for fun, find out how many degrees of separation exist between these concepts :)
var contextVariables = new ContextVariables();
contextVariables.Set("Item1", llmResult);
contextVariables.Set("Item2", apiResult);

var llmDegreesOfSeparationResult = await sk.RunAsync(contextVariables, sk.Skills.GetSemanticFunction("DegreesOfSeparation", "FindDegrees"));
Console.WriteLine("Degrees of separation: " + llmDegreesOfSeparationResult.Result);
30 changes: 30 additions & 0 deletions samples/dotnet/GrpcSkillRunner/Protos/activity.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
syntax = "proto3";

package reference_skill;

// GetRandomActivityRequest is a message that contains input for the GetRandomActivity RPC method.
message GetRandomActivityRequest {
string input = 1; // Input is a hobby that is use to generate a random activity.
}

// GetRandomActivityResponse is a message that contains the activity returned by the GetRandomActivity RPC method.
message GetRandomActivityResponse {
string activity = 1; // Activity is a description of the random activity.
}

// RandomActivitySkill is a service that provides methods related to random activities.
service RandomActivitySkill {
// GetRandomActivity is an RPC method that retrieves a random activity from an API.
rpc GetRandomActivity (GetRandomActivityRequest) returns (GetRandomActivityResponse);
}

// Activity is a message that represents an activity with its various properties.
message Activity {
string activity = 1; // A description of the activity.
string type = 2; // The type or category of the activity.
int32 participants = 3; // The number of participants required for the activity.
double price = 4; // The cost associated with the activity, from 0 (free) to 1 (most expensive).
string link = 5; // A URL providing more information about the activity.
string key = 6; // A unique identifier for the activity.
float accessibility = 7; // The accessibility of the activity, from 0 (most accessible) to 1 (least accessible).
}
38 changes: 38 additions & 0 deletions samples/java/JavaReferenceSkill/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/

### IntelliJ IDEA ###
.idea/modules.xml
.idea/jarRepositories.xml
.idea/compiler.xml
.idea/libraries/
*.iws
*.iml
*.ipr

### Eclipse ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache

### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/

### VS Code ###
.vscode/

### Mac OS ###
.DS_Store
23 changes: 23 additions & 0 deletions samples/java/JavaReferenceSkill/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Java Reference Skill gRPC Server
This is a reference implementation of a gRPC server for the Java Reference Skill. It is intended to be used as a starting point for developers who want to create their own gRPC server for the Java Reference Skill.

## Prerequisites
* Java 17
* Maven

## Build
To build the project, run the following command:
```
mvn clean package
```
To generate the gRPC classes, run the following command:
```
mvn protobuf:compile
```

## Run
To run the project, run the following command:
```
java -jar ./target/JavaReferenceSkill-1.0-SNAPSHOT-jar-with-dependencies.jar
```

109 changes: 109 additions & 0 deletions samples/java/JavaReferenceSkill/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>com.microsoft.semantickernel.skills.random</groupId>
<artifactId>JavaReferenceSkill</artifactId>
<version>1.0-SNAPSHOT</version>

<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<grpc.version>1.54.0</grpc.version>
<javax.annotation-api.version>1.2</javax.annotation-api.version>
<os-maven-plugin.version>1.7.1</os-maven-plugin.version>
<protobuf-maven-plugin.version>0.6.1</protobuf-maven-plugin.version>
<protoc.version>3.22.2</protoc.version>
<mockito-core.version>5.2.0</mockito-core.version>
</properties>

<dependencies>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-protobuf</artifactId>
<version>${grpc.version}</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-stub</artifactId>
<version>${grpc.version}</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-testing</artifactId>
<version>${grpc.version}</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-netty-shaded</artifactId>
<version>${grpc.version}</version>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>${mockito-core.version}</version>
</dependency>
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>${javax.annotation-api.version}</version>
</dependency>
</dependencies>

<build>
<extensions>
<extension>
<groupId>kr.motd.maven</groupId>
<artifactId>os-maven-plugin</artifactId>
<version>${os-maven-plugin.version}</version>
</extension>
</extensions>
<plugins>
<plugin>
<groupId>org.xolstice.maven.plugins</groupId>
<artifactId>protobuf-maven-plugin</artifactId>
<version>${protobuf-maven-plugin.version}</version>
<configuration>
<protocArtifact>com.google.protobuf:protoc:${protoc.version}:exe:${os.detected.classifier}</protocArtifact>
<pluginId>grpc-java</pluginId>
<pluginArtifact>io.grpc:protoc-gen-grpc-java:${grpc.version}:exe:${os.detected.classifier}</pluginArtifact>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>compile-custom</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>com.microsoft.semantickernel.skills.random.Main</mainClass>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>

</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.microsoft.semantickernel.skills.random;

import io.grpc.Server;
import io.grpc.ServerBuilder;

import java.util.logging.Logger;

public class Main {

private static final int PORT = 50051;

public static void main(String[] args) {
Logger logger = java.util.logging.Logger.getLogger(Main.class.getName());

Server server = ServerBuilder.forPort(PORT)
.addService(new RandomActivitySkill()).build();

System.out.println("Starting server...");
try {
server.start();
System.out.println("gRPC Server for random activity started on port " + PORT);
server.awaitTermination();
} catch (Exception e) {
logger.severe("Error with request: " + e.getMessage());
throw new RuntimeException(e);
}
}
}
Loading