Skip to content

Commit

Permalink
Merge pull request #69 from careywalker-msft/typescript_console_chat
Browse files Browse the repository at this point in the history
Implementation of a typescript console chat application based on the c# console chat app
  • Loading branch information
markwallace-microsoft authored Sep 18, 2023
2 parents 7e8baec + d1d2a7d commit 0f9ff1d
Show file tree
Hide file tree
Showing 11 changed files with 213 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ Alternatively, you can use the [Semantic Kernel Tools](https://marketplace.visua
- [C# Azure Functions](sk-csharp-azure-functions): The Hello World C# Azure Functions starter for the Semantic Kernel.
- [Python Hello World](sk-python-hello-world): The Hello World Python console application starter for the Semantic Kernel.
- [Python Azure Functions](sk-python-azure-functions): The Hello World Python Azure Functions starter for the Semantic Kernel.
- [Typescript Console Chat](sk-typescript-console-chat): A console application based chat starter for the Semantic Kernel.

## Contributing

Expand Down
6 changes: 6 additions & 0 deletions sk-starters.sln
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "sk-csharp-console-chat", "s
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "sk_csharp_apim_demo", "sk_csharp_apim_demo\sk_csharp_apim_demo.csproj", "{FC9DF14A-6CCB-42FA-BE38-C61F87C06094}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "sk-typescript-console-chat", "sk-typescript-console-chat\sk-typescript-console-chat.csproj", "{9FEE5A32-69C2-4DEF-9179-BBCD80AB8317}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -45,6 +47,10 @@ Global
{FC9DF14A-6CCB-42FA-BE38-C61F87C06094}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FC9DF14A-6CCB-42FA-BE38-C61F87C06094}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FC9DF14A-6CCB-42FA-BE38-C61F87C06094}.Release|Any CPU.Build.0 = Release|Any CPU
{9FEE5A32-69C2-4DEF-9179-BBCD80AB8317}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9FEE5A32-69C2-4DEF-9179-BBCD80AB8317}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9FEE5A32-69C2-4DEF-9179-BBCD80AB8317}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9FEE5A32-69C2-4DEF-9179-BBCD80AB8317}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
15 changes: 15 additions & 0 deletions sk-typescript-console-chat/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

{
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": "latest",
"sourceType": "module"
},
"plugins": [ "@typescript-eslint" ],
"root": true,
"rules": {
// Add rules here
}
}
5 changes: 5 additions & 0 deletions sk-typescript-console-chat/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
**/bin
**/obj
**/pkg
*.js
*.map
52 changes: 52 additions & 0 deletions sk-typescript-console-chat/consoleChat.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

import "./bin/Microsoft.SemanticKernel.Core.js";
import "./bin/Microsoft.SemanticKernel.Connectors.AI.OpenAI.js";
import dotnet from "node-api-dotnet";
import readline from "node:readline";
import { consoleColours } from "./consoleColours.js";

const SK = dotnet.Microsoft.SemanticKernel;

// The JS marshaller does not yet support extension methods.
const kernelBuilder = SK.OpenAIKernelBuilderExtensions.WithAzureChatCompletionService(
SK.Kernel.Builder,
process.env['OPENAI_DEPLOYMENT'] || '',
process.env['OPENAI_ENDPOINT'] || '',
process.env['OPENAI_KEY'] || '',
);

const kernel = kernelBuilder
.Build();

const r1 = readline.createInterface({
input: process.stdin,
output: process.stdout,
prompt: 'SK> Hello. Ask me a question or say goodbye to exit.'
});

let chatHistory: string[] = [];

r1.prompt();
console.log("");
r1.on('line', async (userInput: string) => {
if (userInput.toLowerCase() === 'goodbye') {
console.log('SK> Goodbye!');
process.exit(0);
} else {
chatHistory.push(userInput);
// The JS marshaller does not yet support extension methods.
const chatFunction = SK.InlineFunctionsDefinitionExtension
.CreateSemanticFunction(kernel, chatHistory.join(""));

const reply = await kernel.RunAsync("", [chatFunction]);

chatHistory.push(`${reply}`);
console.log(consoleColours.green, `Answer> ${reply}`);
console.log(consoleColours.white, `SK> Ask me another question or say goodbye to exit.`);
}
}).on('close', () => {
console.log(consoleColours.white, 'SK> Goodbye!');
process.exit(0);
});
7 changes: 7 additions & 0 deletions sk-typescript-console-chat/consoleColours.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

export const consoleColours = {
green: "\x1b[32m",
white: "\x1b[37m",
};
57 changes: 57 additions & 0 deletions sk-typescript-console-chat/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 13 additions & 0 deletions sk-typescript-console-chat/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"type": "module",
"scripts": {
"build": "tsc --build"
},
"dependencies": {
"node-api-dotnet": "^0.4.4",
"typescript": "^5.2.2"
},
"devDependencies": {
"@types/node": "^20.6.0"
}
}
23 changes: 23 additions & 0 deletions sk-typescript-console-chat/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@

## Example: Using .NET Semantic Kernel to call Azure OpenAI
The `consoleChat.js` script dynamically loads the [`Microsoft.SemanticKernel`](https://github.com/microsoft/semantic-kernel) .NET assembly and uses it
to call Azure OpenAI.

This application allows you to have a conversation with Azure OpenAI. It will ask you to enter your question
and return the response. You can continue the conversation by entering another question. When finished, type `goodbye`
to end the conversation.

To run this example, first set the following environment variables, as System variables, referencing your
[Azure OpenAI deployment](https://learn.microsoft.com/en-us/azure/cognitive-services/openai/quickstart):
- `OPENAI_ENDPOINT`
- `OPENAI_DEPLOYMENT`
- `OPENAI_KEY`

Then run the following commands in sequence:

| Command | Explanation
|----------------------------------|--------------------------------------------------
| `dotnet build` | Install [`SemanticKernel`](https://www.nuget.org/packages/Microsoft.SemanticKernel) nuget packages into the project and generate type definitions.
| `npm install` | Install [`node-api-dotnet`](https://www.npmjs.com/package/node-api-dotnet) npm package into the project.
| `npm run build` | Transpile the typescript to javascript.
| `node consoleChat.js` | Run consoleChat JS code that uses the above packages to call the Azure OpenAI service.
14 changes: 14 additions & 0 deletions sk-typescript-console-chat/sk-typescript-console-chat.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<OutDir>bin</OutDir>
<NodeApiAssemblyJSModuleType>esm</NodeApiAssemblyJSModuleType>
<GenerateNodeApiTypeDefinitionsForReferences>true</GenerateNodeApiTypeDefinitionsForReferences>
<RestorePackagesPath>$(MSBuildThisFileDirectory)/pkg</RestorePackagesPath>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.JavaScript.NodeApi.Generator" Version="0.4.4" />
<PackageReference Include="Microsoft.SemanticKernel" Version="0.24.230912.2-preview" />
</ItemGroup>
</Project>
20 changes: 20 additions & 0 deletions sk-typescript-console-chat/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"compilerOptions": {
/* Visit https://aka.ms/tsconfig to read more about this file */
/* Language and Environment */
"target": "es2017", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
/* Modules */
"module": "ESNext", /* Specify what module code is generated. */
"types": [ "node" ], /* Specify type package names to be included without being referenced in a source file. */
/* Emit */
"sourceMap": true, /* Create source map files for emitted JavaScript files. */
"esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */
"forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */
/* Type Checking */
"strict": true, /* Enable all strict type-checking options. */
/* Completeness */
"skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */
"skipLibCheck": true /* Skip type checking all .d.ts files. */
},
"exclude": ["./bin/*.d.ts"] // Don't typecheck the type files for the SemanticKernel assemblies because some of the types used are not supported by node-dotnet-api conversion. Specifically the c# record type.
}

0 comments on commit 0f9ff1d

Please sign in to comment.