Skip to content

Commit

Permalink
(a) Prompt OM refined (b) Interactive Agents (c) HealthData sample (#81)
Browse files Browse the repository at this point in the history
- Composable Prompt and Prompt Section builds
- Interactive Agents, Chat history. 
- Intent Router
- HealthData example now also does Conditions. 
- Config improvements
  • Loading branch information
umeshma committed Sep 8, 2023
1 parent e2b76db commit f5b9abb
Show file tree
Hide file tree
Showing 61 changed files with 860 additions and 272 deletions.
28 changes: 16 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# TypeChat.NET

TypeChat.NET is an experimental project that makes it easy to build natural language interfaces using strong Types.
TypeChat.NET is an **experimental project** that makes it easy to build natural language interfaces using strong Types.

TypeChat.NET applies the ideas of [TypeChat](https://github.com/microsoft/TypeChat) to .NET.

Expand All @@ -11,11 +11,12 @@ TypeChat.NET applies the ideas of [TypeChat](https://github.com/microsoft/TypeCh
);

TypeChat.NET consists of the following assemblies:
- TypeChat
- TypeChat.Schema: Classes for exporting .NET types as Typescript schema.
- TypeChat.Program: Classes to generate, validate and execute ***JSON programs***
- TypeChat.SemanticKernel: Integration with Microsoft Semantic Kernel.
- TypeChat.App: Classes and extensions used by Typechat examples; may be useful for all apps built using Typechat
* TypeChat: Translate user intent into strongly typed and validated objects
* TypeChat.Schema: Classes for exporting .NET types as Typescript schema.
* TypeChat.Program: Classes to synthesize, validate and execute ***JSON programs***
* TypeChat.SemanticKernel: Integration with Microsoft Semantic Kernel.
* TypeChat.Dialog: Classes for working with interactive Agents
* TypeChat.App: Classes and extensions used by Typechat examples; may also be useful for other apps built using Typechat

TypeChat.NET is in **active and rapid development** with very frequent updates and refactoring.
- **Goal**: learn how to strong typing programming with AI, particulary generative LLMs.
Expand Down Expand Up @@ -50,19 +51,22 @@ With auto-generation of Typescript schema:

// Translates user input into a typed responses classifying sentiment
var translator = new JsonTranslator<SentimentResponse>(
new CompletionService(Config.LoadOpenAI()),
new LanguageModel(Config.LoadOpenAI()),
new TypeValidator<SentimentResponse>()
);

The library provides:
- LLM bindings for TypeChat using the Semantic Kernel.
TypeChat.SemanticKernel also contains experimental support to dynamically synthesize and execute **programs** that call Semantic Kernel plugins.

The library contains classes for:
* LLM bindings for TypeChat using the Semantic Kernel. All TypeChat examples use the Semantic Kernel to call LLMs
* Program synthesis with Plugins: Automatically turns registered plugins into a PluginAPI that programs synthesized by the LLM can call. [Plugins Example](examples/Plugins/Program.cs)

# Getting Started
## Building
You will need Visual Studio 2022. VS Code is not tested.
- Load **typechat.sln** from the root directory of your .
- Restore packages
- Build
* Load **typechat.sln** from the root directory of your .
* Restore packages
* Build

## Examples

Expand Down
9 changes: 8 additions & 1 deletion TypeChat.sln
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Plugins", "examples\Plugins
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MultiSchema", "examples\MultiSchema\MultiSchema.csproj", "{9598D98A-3688-45E5-9C51-1C4F385BD693}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TypeChat.Dialog", "src\typechat.dialog\TypeChat.Dialog.csproj", "{DDE39125-BE33-41DC-B536-7185CD374797}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TypeChat.Dialog", "src\typechat.dialog\TypeChat.Dialog.csproj", "{DDE39125-BE33-41DC-B536-7185CD374797}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HealthData", "examples\HealthData\HealthData.csproj", "{F4B127FE-CAB9-483E-AA79-6A2F8665C5FC}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand Down Expand Up @@ -111,6 +113,10 @@ Global
{DDE39125-BE33-41DC-B536-7185CD374797}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DDE39125-BE33-41DC-B536-7185CD374797}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DDE39125-BE33-41DC-B536-7185CD374797}.Release|Any CPU.Build.0 = Release|Any CPU
{F4B127FE-CAB9-483E-AA79-6A2F8665C5FC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F4B127FE-CAB9-483E-AA79-6A2F8665C5FC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F4B127FE-CAB9-483E-AA79-6A2F8665C5FC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F4B127FE-CAB9-483E-AA79-6A2F8665C5FC}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -124,6 +130,7 @@ Global
{A6E4FA5A-116E-4770-8BD2-31185FA13632} = {179655A3-3581-45F4-BE46-1BF4FABA7F97}
{5F8B1030-2D87-4942-BCB3-271B4541BAF3} = {179655A3-3581-45F4-BE46-1BF4FABA7F97}
{9598D98A-3688-45E5-9C51-1C4F385BD693} = {179655A3-3581-45F4-BE46-1BF4FABA7F97}
{F4B127FE-CAB9-483E-AA79-6A2F8665C5FC} = {179655A3-3581-45F4-BE46-1BF4FABA7F97}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {8A9AF678-E669-4AF2-9644-7EBB970DAC41}
Expand Down
10 changes: 2 additions & 8 deletions examples/Calendar/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,19 +27,12 @@ public CalendarApp()

public override async Task ProcessRequestAsync(string input, CancellationToken cancelToken)
{
DateTime now = DateTime.Now;
string request = $"{input}\n{Now()}";
string request = $"{input}\n{PromptLibrary.Now()}";
CalendarActions actions = await _translator.TranslateAsync(request, cancelToken);
Console.WriteLine(Json.Stringify(actions));
PrintUnknown(actions);
}

string Now()
{
DateTime now = DateTime.Now;
return $"##Use precise date and times RELATIVE TO CURRENT DATE: {now.ToLongDateString()} CURRENT TIME: {now.ToLongTimeString()}" +
"Also turn ranges like next week and next month into precise dates";
}
bool PrintUnknown(CalendarActions calendarActions)
{
int countUnknown = 0;
Expand Down Expand Up @@ -70,6 +63,7 @@ public static async Task<int> Main(string[] args)
catch (Exception ex)
{
WriteError(ex);
Console.ReadLine();
return -1;
}

Expand Down
2 changes: 1 addition & 1 deletion examples/CoffeeShop/CoffeeShopSchema.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public abstract partial class CartItem
{
}

[Comment("Use this type for things that match nothing else or requests you could nnot translate")]
[Comment("Use this type for Cart Items that match nothing else")]
public partial class UnknownItem : CartItem
{
[Comment("The text that wasn't understood")]
Expand Down
5 changes: 4 additions & 1 deletion examples/CoffeeShop/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ public override async Task ProcessRequestAsync(string input, CancellationToken c
{
Cart cart = await _translator.TranslateAsync(input);

Console.WriteLine("##YOUR ORDER");
string json = Json.Stringify(cart);
Console.WriteLine(json);

Expand All @@ -46,6 +47,7 @@ bool PrintAnyUnknown(Cart cart)
cart.GetUnknown(sb);
if (sb.Length > 0)
{
Console.WriteLine();
Console.WriteLine("I didn't understand the following:");
Console.WriteLine(sb.ToString());
return true;
Expand All @@ -60,13 +62,14 @@ public static async Task<int> Main(string[] args)
{
CoffeeShopApp app = new CoffeeShopApp();
// Un-comment to print auto-generated schema at start:
//Console.WriteLine(app.Schema.Schema.Text);
// Console.WriteLine(app.Schema.Schema.Text);

await app.RunAsync("☕> ", args.GetOrNull(0));
}
catch (Exception ex)
{
WriteError(ex);
Console.ReadLine();
return -1;
}

Expand Down
2 changes: 1 addition & 1 deletion examples/CoffeeShop2/CoffeeShopSchema.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public abstract partial class CartItem
{
}

[Comment("Use this type for products with names that match NO listed PRODUCT NAME")]
[Comment("Use this type for Cart Items that match nothing else")]
public partial class UnknownItem : CartItem
{
[Comment("The text that wasn't understood")]
Expand Down
4 changes: 4 additions & 0 deletions examples/CoffeeShop2/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ public override async Task ProcessRequestAsync(string input, CancellationToken c
{
Cart cart = await _translator.TranslateAsync(input, cancelToken);

Console.WriteLine("##YOUR ORDER");
string json = Json.Stringify(cart);
Console.WriteLine(json);

Expand All @@ -55,6 +56,7 @@ bool PrintAnyUnknown(Cart cart)
cart.GetUnknown(sb);
if (sb.Length > 0)
{
Console.WriteLine();
Console.WriteLine("I didn't understand the following:");
Console.WriteLine(sb.ToString());
return true;
Expand All @@ -75,6 +77,8 @@ public static async Task<int> Main(string[] args)
catch (Exception ex)
{
WriteError(ex);
Console.ReadLine();
return -1;
}

return 0;
Expand Down
36 changes: 36 additions & 0 deletions examples/HealthData/HealthData.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net7.0</TargetFramework>
<RollForward>LatestMajor</RollForward>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>annotations</Nullable>
</PropertyGroup>

<ItemGroup>
<Content Include="..\appSettings.json" Link="appSettings.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>

<ItemGroup Condition="Exists('..\appSettings.Development.json')">
<Content Include="..\appSettings.Development.json" Link="appSettings.Development.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\src\typechat.app\TypeChat.App.csproj" />
<ProjectReference Include="..\..\src\typechat.dialog\TypeChat.Dialog.csproj" />
<ProjectReference Include="..\..\src\typechat.sk\TypeChat.SemanticKernel.csproj" />
<ProjectReference Include="..\..\src\typechat\TypeChat.csproj" />
</ItemGroup>

<ItemGroup>
<None Update="input.txt">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>

</Project>
80 changes: 80 additions & 0 deletions examples/HealthData/HealthSchema.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
// Copyright (c) Microsoft. All rights reserved.

using System;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.ComponentModel.DataAnnotations;
using Microsoft.TypeChat.Schema;
using Microsoft.TypeChat.Dialog;

namespace HealthData;

public class Quantity
{
[Comment("Exact number")]
public double Value { get; set; }
[Comment("UNITS include mg, kg, cm, pounds, liter, ml, tablet, pill, cup, per-day, per-week..ETC")]
public string Units { get; set; }
}

public class ApproxQuantity
{
[JsonRequired]
[Comment("Use if no precise quantity")]
public string DisplayText { get; set; }

[Comment("Optional: only if precise quantities are available")]
public Quantity? Quantity { get; set; }
}

public class ApproxDateTime
{
[JsonRequired]
[Comment("Use if no precise date")]
public string DisplayText { get; set; }

[Comment("If precise timestamp can be set")]
public DateTime? Timestamp { get; set; }
}

public class Medication
{
public string Name { get; set; }

[Comment("E.g. 2 tablets, 1 cup")]
[Required]
public ApproxQuantity Dose { get; set; }

[Comment("E.g. twice a day, ")]
[Required]
public ApproxQuantity Frequency { get; set; }

[Comment("E.g. 50 mg")]
[Required]
public ApproxQuantity Strength { get; set; }
}

[Comment("Disease, ailment, injury etc")]
public class Condition
{
public string Name { get; set; }

[JsonVocab("active | recurrence | relapse | inactive | remission | resolved | unknown")]
public string Status { get; set; }

[Required]
public ApproxDateTime StartDate { get; set; }

[Required]
[Comment("If the disease ended")]
public ApproxDateTime? EndDate { get; set; }
}

public class HealthData
{
public Medication? Medication { get; set; }
public Condition? Condition { get; set; }
}

public class HealthDataResponse : AgentResponse<HealthData> { }
Loading

0 comments on commit f5b9abb

Please sign in to comment.