planner get remaining task.

This commit is contained in:
Haiping Chen 2024-02-01 12:32:16 -06:00
parent 2e5e12e309
commit a3c6a6b93c
12 changed files with 103 additions and 17 deletions

View file

@ -0,0 +1,9 @@
namespace BotSharp.Abstraction.Routing.Models;
public class DecomposedStep
{
public string Description { get; set; }
[JsonPropertyName("total_remaining_steps")]
public int TotalRemainingSteps { get; set; }
}

View file

@ -1,4 +1,5 @@
using BotSharp.Abstraction.Functions.Models;
using BotSharp.Abstraction.Routing.Models;
namespace BotSharp.Abstraction.Routing.Planning;
@ -11,4 +12,8 @@ public interface IPlaner
Task<FunctionCallFromLlm> GetNextInstruction(Agent router, string messageId);
Task<bool> AgentExecuting(Agent router, FunctionCallFromLlm inst, RoleDialogModel message);
Task<bool> AgentExecuted(Agent router, FunctionCallFromLlm inst, RoleDialogModel message);
bool HideDialogContext => false;
Task<DecomposedStep> GetDecomposedStepAsync(Agent router, string messageId, List<RoleDialogModel> dialogs)
=> throw new NotImplementedException("");
int MaxLoopCount => 5;
}

View file

@ -53,6 +53,7 @@
<None Remove="data\agents\01fcc3e5-9af7-49e6-ad7a-a760bd12dc4a\templates\.welcome.liquid" />
<None Remove="data\agents\01fcc3e5-9af7-49e6-ad7a-a760bd12dc4a\templates\planner_prompt.hf.liquid" />
<None Remove="data\agents\01fcc3e5-9af7-49e6-ad7a-a760bd12dc4a\templates\planner_prompt.naive.liquid" />
<None Remove="data\agents\01fcc3e5-9af7-49e6-ad7a-a760bd12dc4a\templates\planner_prompt.sequential.get_remaining_task.liquid" />
<None Remove="data\agents\01fcc3e5-9af7-49e6-ad7a-a760bd12dc4a\templates\planner_prompt.sequential.liquid" />
<None Remove="data\agents\01fcc3e5-9af7-49e6-ad7a-a760bd12dc4a\templates\response_with_function.liquid" />
<None Remove="data\agents\dfd9b46d-d00c-40af-8a75-3fbdc2b89869\agent.json" />
@ -75,6 +76,9 @@
<Content Include="data\agents\01fcc3e5-9af7-49e6-ad7a-a760bd12dc4a\instruction.liquid">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="data\agents\01fcc3e5-9af7-49e6-ad7a-a760bd12dc4a\templates\planner_prompt.sequential.get_remaining_task.liquid">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="data\agents\01fcc3e5-9af7-49e6-ad7a-a760bd12dc4a\templates\planner_prompt.sequential.liquid">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>

View file

@ -42,7 +42,7 @@ public class HFPlanner : IPlaner
{
new RoleDialogModel(AgentRole.User, next)
{
FunctionName = nameof(NaivePlanner),
FunctionName = nameof(HFPlanner),
MessageId = messageId
}
};

View file

@ -4,6 +4,7 @@ using BotSharp.Abstraction.Routing;
using BotSharp.Abstraction.Routing.Models;
using BotSharp.Abstraction.Routing.Planning;
using BotSharp.Abstraction.Templating;
using System.Drawing;
namespace BotSharp.Core.Routing.Planning;
@ -12,6 +13,9 @@ public class SequentialPlanner : IPlaner
private readonly IServiceProvider _services;
private readonly ILogger _logger;
public bool HideDialogContext => true;
public int MaxLoopCount => 10;
public SequentialPlanner(IServiceProvider services, ILogger<NaivePlanner> logger)
{
_services = services;
@ -48,7 +52,7 @@ public class SequentialPlanner : IPlaner
{
new RoleDialogModel(AgentRole.User, next)
{
FunctionName = nameof(NaivePlanner),
FunctionName = nameof(SequentialPlanner),
MessageId = messageId
}
};
@ -110,4 +114,55 @@ public class SequentialPlanner : IPlaner
{
});
}
public async Task<DecomposedStep> GetDecomposedStepAsync(Agent router, string messageId, List<RoleDialogModel> dialogs)
{
var systemPrompt = GetDecomposeTaskPrompt(router);
var inst = new DecomposedStep();
// chat completion
var completion = CompletionProvider.GetChatCompletion(_services,
model: "llm-gpt4");
int retryCount = 0;
while (retryCount < 2)
{
string text = string.Empty;
try
{
var response = await completion.GetChatCompletions(new Agent
{
Id = router.Id,
Name = nameof(SequentialPlanner),
Instruction = systemPrompt
}, dialogs);
text = response.Content;
Console.WriteLine(text, Color.Red);
inst = response.Content.JsonContent<DecomposedStep>();
break;
}
catch (Exception ex)
{
_logger.LogError($"{ex.Message}: {text}");
}
finally
{
retryCount++;
}
}
return inst;
}
private string GetDecomposeTaskPrompt(Agent router)
{
var template = router.Templates.First(x => x.Name == "planner_prompt.sequential.get_remaining_task").Content;
var render = _services.GetRequiredService<ITemplateRender>();
return render.Render(template, new Dictionary<string, object>
{
});
}
}

View file

@ -80,7 +80,7 @@ public partial class RoutingService : IRoutingService
context.Push(_router.Id);
int loopCount = 0;
while (loopCount < 5 && !context.IsEmpty)
while (loopCount < planner.MaxLoopCount && !context.IsEmpty)
{
loopCount++;
@ -101,7 +101,25 @@ public partial class RoutingService : IRoutingService
await planner.AgentExecuting(_router, inst, message);
// Handle instruction by Executor
response = await executor.Execute(this, inst, message, dialogs);
if (planner.HideDialogContext)
{
/*var args = JsonSerializer.Serialize(inst.Arguments);
if (args.Length > 3)
{
inst.Question += $"\r\nargs: {args}";
}*/
var step = await planner.GetDecomposedStepAsync(_router, message.MessageId, dialogs);
var maskDialogs = new List<RoleDialogModel>
{
new RoleDialogModel(AgentRole.User, step.Description)
};
response = await executor.Execute(this, inst, message, maskDialogs);
dialogs.AddRange(maskDialogs.Skip(1));
}
else
{
response = await executor.Execute(this, inst, message, dialogs);
}
await planner.AgentExecuted(_router, inst, response);
}

View file

@ -0,0 +1,5 @@
Use will give you a task list with steps, which is going to be executed.
If a specific step has been exectued, you will get something indicates the result.
If there is no any result provided, it means all the steps have not been executed yet.
You need to figure out which steps have not been completed.
Tell me what is the first remaining step from user steps that have not been completed based on the context. Output in JSON { "description": "", "total_remaining_steps": 0}

View file

@ -1,2 +1,2 @@
In order to sequentially execute user needs,
In order to sequentially execute user tasks,
What is the next step based on the CONVERSATION?

View file

@ -58,10 +58,6 @@ public partial class PlaywrightWebDriver
try
{
await element.FillAsync(context.InputText);
if (context.PressEnter)
{
await element.PressAsync("Enter");
}
}
catch (Exception ex)
{

View file

@ -13,9 +13,6 @@ public class BrowsingContextIn
[JsonPropertyName("input_text")]
public string? InputText { get; set; }
[JsonPropertyName("press_enter")]
public bool PressEnter { get; set; }
[JsonPropertyName("update_value")]
public string? UpdateValue { get; set; }

View file

@ -5,9 +5,10 @@
"type": "task",
"createdDateTime": "2024-01-02T00:00:00Z",
"updatedDateTime": "2024-01-02T00:00:00Z",
"disabled": false,
"isPublic": true,
"profiles": [ "web-driver" ],
"llmConfig": {
"max_recursion_depth": 10
"max_recursion_depth": 1
}
}

View file

@ -78,10 +78,6 @@
"input_text": {
"type": "string",
"description": "non-sensitive text user provided."
},
"press_enter": {
"type": "boolean",
"description": "whether to press ENTER"
}
},
"required": [ "element_name", "input_text" ]