Skip to content
Merged
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
22 changes: 15 additions & 7 deletions examples/HealthData/HealthSchema.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ public class ApproxDateTime
public DateTime? Timestamp { get; set; }
}

[Comment("Meds, pills, etc")]
public class Medication
{
public string Name { get; set; }
Expand All @@ -53,7 +54,7 @@ public class Medication
public ApproxQuantity Strength { get; set; }
}

[Comment("Disease, ailment, injury etc")]
[Comment("Disease, Ailment, Injury, Sickness")]
public class Condition
{
public string Name { get; set; }
Expand All @@ -69,23 +70,30 @@ public class Condition
public ApproxDateTime? EndDate { get; set; }
}

[Comment("Use for health data that match nothing else. E.g. immunization, blood prssure etc")]
public class OtherData
{
[JsonPropertyName("text")]
public string Text { get; set; }

public ApproxDateTime? When { get; set; }
}

public class HealthData
{
public Medication? Medication { get; set; }
public Condition? Condition { get; set; }
public Medication[]? Medication { get; set; }
public Condition[]? Condition { get; set; }
public OtherData[]? Other { get; set; }
}

public class HealthDataResponse
{
[Comment("Use this to ask questions, respond to user, notify user")]
public string Message { get; set; }
public string? Message { get; set; }

[Comment("Return this if JSON has ALL required information. Else ask questions")]
public HealthData? Data { get; set; }

[Comment("Use this for text that was not understood")]
public string[]? NotTranslated { get; set; }

[JsonIgnore]
public bool HasMessage => (!string.IsNullOrEmpty(Message));
}
10 changes: 6 additions & 4 deletions examples/HealthData/Program.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright (c) Microsoft. All rights reserved.

using Microsoft.TypeChat;
using Microsoft.TypeChat.Schema;
using Microsoft.TypeChat.Dialog;

namespace HealthData;
Expand All @@ -13,14 +14,15 @@ public HealthDataAgent()
{
_agent = new Agent<HealthDataResponse>(new LanguageModel(Config.LoadOpenAI()));
_agent.Translator.MaxRepairAttempts = 2;
_agent.Translator.ConstraintsValidator = new ConstraintsValidator<HealthDataResponse>();
_agent.ResponseToMessage = (r) => (r.HasMessage) ?
Message.FromAssistant(r.Message) :
null;

PromptSection preamble = "Ask the user pertinent questions to get all DATA required for a valid JSON object.\n";
preamble += "Also ask about optional data, but stop asking if the user does have the answer OR does not know";
_agent.Preamble.Append(preamble);
_agent.Preamble.Append("DO fix spelling mistakes, including phonetic misspellings of medications and conditions.");
PromptSection section = "Ask the user pertinent questions to get all DATA required and optional for a valid JSON object.\n";
section += "But stop asking if the user does have the answer OR does not know";
_agent.Preamble.Add(section);
_agent.Preamble.Append("Fix spelling mistakes, including phonetic misspellings.");
_agent.Preamble.Append(PromptLibrary.Now());
// Uncomment to observe prompts
//base.SubscribeAllEvents(_agent.Translator);
Expand Down
9 changes: 6 additions & 3 deletions examples/HealthData/Readme.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
# HealthData
Demonstrates a ***strongly typed*** chat. Work with an Agent to interactively enter health data.
# Health Data Agent
This example requires GPT-4.

Demonstrates how to use **Agents (Chat) with history** to ***interactively*** fill forms.
Demonstrates a ***strongly typed*** Chat. Here, you work with an Agent to interactively enter medications or conditions.

Demonstrates **form filling** scenario: how to use **Agents (Chat) with history** to ***interactively*** acquire information need for one or more Types from the user.

# Usage

Example prompts can be found in [`input.txt`](input.txt).


Expand Down
1 change: 0 additions & 1 deletion src/typechat.dialog/Agent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ public Agent(JsonTranslator<T> translator, IMessageStream? history = null)
public Prompt Preamble => _preamble;
public TranslationSettings RequestSettings { get; set; }
public IMessageStream InteractionHistory => _history;

/// <summary>
/// Transform raw responses into messages for the message history
/// </summary>
Expand Down
21 changes: 14 additions & 7 deletions src/typechat/JsonTranslator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,15 @@ public IConstraintsValidator<T>? ConstraintsValidator
/// <summary>
/// Prompts used during translation
/// </summary>
public IJsonTranslatorPrompts Prompts => _prompts;
public IJsonTranslatorPrompts Prompts
{
get => _prompts;
set
{
value ??= JsonTranslatorPrompts.Default;
_prompts = value;
}
}

/// <summary>
/// Translation settings
Expand Down Expand Up @@ -202,11 +210,6 @@ public async Task<T> TranslateAsync(
string responseText = await GetResponseAsync(prompt, requestSettings, cancelToken).ConfigureAwait(false);

JsonResponse jsonResponse = JsonResponse.Parse(responseText);
if (!jsonResponse.HasJson)
{
TypeChatException.ThrowNoJson(request, jsonResponse);
}

Result<T> validationResult;
if (jsonResponse.HasCompleteJson)
{
Expand All @@ -216,11 +219,15 @@ public async Task<T> TranslateAsync(
return validationResult;
}
}
else
else if (jsonResponse.HasJson)
{
// Partial json
validationResult = Result<T>.Error(TypeChatException.IncompleteJson(jsonResponse));
}
else
{
validationResult = Result<T>.Error(TypeChatException.NoJson(jsonResponse));
}

// Attempt to repair the Json that was returned
++repairAttempts;
Expand Down
21 changes: 9 additions & 12 deletions src/typechat/JsonTranslatorPrompts.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,14 @@ namespace Microsoft.TypeChat;

/// <summary>
/// The standard prompts used by JsonTranslator
/// You can customize prompts you give to the translator as per your scenario
/// To do so, you can implement IJsonTranslatorPrompts OR just inherit from this class and override
/// </summary>
public class JsonTranslatorPrompts : IJsonTranslatorPrompts
{
internal static readonly JsonTranslatorPrompts Default = new JsonTranslatorPrompts();

public virtual Prompt CreateRequestPrompt(TypeSchema schema, Prompt request, IList<IPromptSection> preamble = null)
{
return RequestPrompt(schema, request, preamble);
}

public virtual string CreateRepairPrompt(TypeSchema schema, string json, string validationError)
{
return RepairPrompt(validationError);
}

public static Prompt RequestPrompt(TypeSchema typeSchema, Prompt request, IList<IPromptSection>? context = null)
public virtual Prompt CreateRequestPrompt(TypeSchema typeSchema, Prompt request, IList<IPromptSection> context = null)
{
if (request == null)
{
Expand All @@ -33,6 +25,11 @@ public static Prompt RequestPrompt(TypeSchema typeSchema, Prompt request, IList<
return prompt;
}

public virtual string CreateRepairPrompt(TypeSchema schema, string json, string validationError)
{
return RepairPrompt(validationError);
}

/// <summary>
/// Add the given user request and any context to the prompt we are sending to the model
/// </summary>
Expand Down Expand Up @@ -74,7 +71,7 @@ public static PromptSection IntroSection(string typeName, string schema)
return introSection;
}

static PromptSection RequestSection(string request)
public static PromptSection RequestSection(string request)
{
PromptSection requestSection = new PromptSection();
requestSection += "The following is a user request:\n";
Expand Down
5 changes: 5 additions & 0 deletions src/typechat/SchemaText.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,11 @@ public SchemaText(string text, string lang)
[JsonPropertyName("text")]
public string Text => _text;

public override string ToString()
{
return _text;
}

public static implicit operator string(SchemaText schema)
{
return schema._text;
Expand Down
9 changes: 7 additions & 2 deletions src/typechat/TypeChatException.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ public class TypeChatException : Exception
{
static class ErrorMessages
{
public const string NoJsonReturned = "No JSON object returned";
public const string IncompleteJson = "Json Parse Error. Json Object is incomplete";
public const string NoJsonReturned = "The response is not Json";
public const string IncompleteJson = "Json Object is incomplete";
}

/// <summary>
Expand Down Expand Up @@ -82,6 +82,11 @@ internal static void ThrowJsonValidation(string request, JsonResponse response,
);
}

internal static string NoJson(JsonResponse response)
{
return $"{TypeChatException.ErrorMessages.NoJsonReturned}:\n{response.ResponseText}";
}

internal static string IncompleteJson(JsonResponse response)
{
return $"{TypeChatException.ErrorMessages.IncompleteJson}:\n{response.Json}";
Expand Down