Skip to content

Commit

Permalink
HealCharacterTools has been created
Browse files Browse the repository at this point in the history
  • Loading branch information
KarmaKamikaze committed Oct 28, 2024
1 parent e44d857 commit a27edfd
Show file tree
Hide file tree
Showing 6 changed files with 83 additions and 3 deletions.
13 changes: 13 additions & 0 deletions ChatRPG/API/ReActLlmClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,19 @@ private List<AgentTool> CreateTools(Campaign campaign)
"only raw JSON as input. Use this tool only once per character at most.");
tools.Add(woundCharacterTool);

var healCharacterTool = new HealCharacterTool(_configuration, campaign, utils, "healcharactertool",
"This tool must be used when a character performs an action that could heal or restore them to " +
"health after being wounded. The tool is only appropriate if the healing can be done without any " +
"further actions. Example: A character is wounded by an enemy attack and the player decides to heal " +
"the character. Another example would be a scenario where a character consumes a beneficial item like " +
"a potion, a magical item, or spends time in an area that could provide healing " +
"benefits. Resting may provide modest healing effects depending on the duration of the rest. " +
"Input to this tool must be in the following RAW JSON format: {\"input\": \"The game " +
"summary appended with the player's input\", \"magnitude\": \"Describes how much health the character will " +
"regain based on the action. Can be one of the following values: {low, medium, high, extraordinary}}\". " +
"Do not use markdown, only raw JSON as input. Use this tool only once per character at most.");
tools.Add(healCharacterTool);

// Use battle when an attack can be mitigated or dodged by the involved participants.
// This tool is appropriate for combat, battle between multiple participants,
// or attacks that can be avoided and a to-hit roll would be needed in order to determine a hit.
Expand Down
59 changes: 59 additions & 0 deletions ChatRPG/API/Tools/HealCharacterTool.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
using System.Text.Json;
using ChatRPG.Data.Models;
using LangChain.Chains.StackableChains.Agents.Tools;

namespace ChatRPG.API.Tools;

public class HealCharacterTool(
IConfiguration configuration,
Campaign campaign,
ToolUtilities utilities,
string name,
string? description = null) : AgentTool(name, description)
{
private static readonly JsonSerializerOptions JsonOptions = new()
{
PropertyNameCaseInsensitive = true
};

private static readonly Dictionary<string, (int, int)> HealingRanges = new()
{
{ "low", (5, 10) },
{ "medium", (10, 20) },
{ "high", (15, 25) },
{ "extraordinary", (25, 80) }
};

public override async Task<string> ToolTask(string input, CancellationToken token = new CancellationToken())
{
try
{
var effectInput = JsonSerializer.Deserialize<HealInput>(input, JsonOptions) ??
throw new JsonException("Failed to deserialize");

var instruction = configuration.GetSection("SystemPrompts").GetValue<string>("HealCharacterInstruction")!;
var character = await utilities.FindCharacter(campaign, effectInput.Input!, instruction);

if (character is null)
{
return "Could not determine the character to heal. The character does not exist in the game. " +
"Consider creating the character before wounding it.";
}

// Determine damage
Random rand = new Random();
var (minHealing, maxHealing) = HealingRanges[effectInput.Magnitude!];
var healing = rand.Next(minHealing, maxHealing);

character.AdjustHealth(healing);

return $"The character {character.Name} is healed for {healing} health points. They now have {character.CurrentHealth} health points out of a total of {character.MaxHealth}.";

}
catch (Exception)
{
return "Could not determine the character to heal. Tool input format was invalid. " +
"Please provide a valid character name, description, and magnitude level in valid JSON without markdown.";
}
}
}
7 changes: 7 additions & 0 deletions ChatRPG/API/Tools/HealInput.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace ChatRPG.API.Tools;

public class HealInput
{
public string? Input { get; set; }
public string? Magnitude { get; set; }
}
2 changes: 1 addition & 1 deletion ChatRPG/API/Tools/WoundCharacterTool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public class WoundCharacterTool(
{
try
{
var effectInput = JsonSerializer.Deserialize<EffectInput>(input, JsonOptions) ??
var effectInput = JsonSerializer.Deserialize<WoundInput>(input, JsonOptions) ??
throw new JsonException("Failed to deserialize");

var instruction = configuration.GetSection("SystemPrompts").GetValue<string>("WoundCharacterInstruction")!;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
namespace ChatRPG.API.Tools;

public class EffectInput
public class WoundInput
{
public string? Input { get; set; }
public string? Severity { get; set; }
Expand Down
3 changes: 2 additions & 1 deletion ChatRPG/appsettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
"DoAction": "The player has input an action that they would like to perform. You must describe everything that happens as the player completes this action. You may have the player say and do anything as long as it is in character. Address the player only in the second person. Always respond in a narrative as the game master in an immersive way.",
"SayAction": "The player has input something that they want to say. You must describe how characters react and what they say. Address the player only in the second person. Always respond in a narrative as the game master in an immersive way.",
"FindCharacter": "You are an expert game master in a single-player RPG. You need to find a specific character in a list of characters from the game world based on the following instruction: {instruction}. Once you have determined the correct character, you must return only its name, description, and type which you received in the list, in valid JSON format. Format Instructions: Answer only in valid RAW JSON in the format { \"name\": \"The character's name\", \"description\": \"The character's description\", \"type\": \"The character's type\" }. If the character does not match anyone in the list based on the instructions, return an empty JSON object.",
"WoundCharacterInstruction": "Find the character that will be hurt or wounded resulting from unnoticed attacks or performing dangerous activities that will lead to injury"
"WoundCharacterInstruction": "Find the character that will be hurt or wounded resulting from unnoticed attacks or performing dangerous activities that will lead to injury",
"HealCharacterInstruction": "Find the character that will be healed by magical effects such as a healing spell, or through consuming a health potion, or by resting"
}
}

0 comments on commit a27edfd

Please sign in to comment.