Skip to content

Commit f2c3123

Browse files
authored
Merge pull request #320 from hchen2020/master
Auto restore function name in InvokeFunction.
2 parents 6e89dc6 + 18721a6 commit f2c3123

File tree

19 files changed

+491
-6
lines changed

19 files changed

+491
-6
lines changed

src/Infrastructure/BotSharp.Abstraction/Knowledges/IKnowledgeHook.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,9 @@ namespace BotSharp.Abstraction.Knowledges;
44

55
public interface IKnowledgeHook
66
{
7-
Task<List<KnowledgeChunk>> CollectChunkedKnowledge();
7+
Task<List<KnowledgeChunk>> CollectChunkedKnowledge()
8+
=> Task.FromResult(new List<KnowledgeChunk>());
9+
10+
Task<List<string>> GetRelevantKnowledges()
11+
=> Task.FromResult(new List<string>());
812
}

src/Infrastructure/BotSharp.Core/BotSharp.Core.csproj

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,9 @@
5555
<None Remove="data\agents\01fcc3e5-9af7-49e6-ad7a-a760bd12dc4a\templates\planner_prompt.naive.liquid" />
5656
<None Remove="data\agents\01fcc3e5-9af7-49e6-ad7a-a760bd12dc4a\templates\planner_prompt.sequential.get_remaining_task.liquid" />
5757
<None Remove="data\agents\01fcc3e5-9af7-49e6-ad7a-a760bd12dc4a\templates\planner_prompt.sequential.liquid" />
58+
<None Remove="data\agents\01fcc3e5-9af7-49e6-ad7a-a760bd12dc4a\templates\planner_prompt.two_stage.1st.plan.liquid" />
59+
<None Remove="data\agents\01fcc3e5-9af7-49e6-ad7a-a760bd12dc4a\templates\planner_prompt.two_stage.2nd.plan.liquid" />
60+
<None Remove="data\agents\01fcc3e5-9af7-49e6-ad7a-a760bd12dc4a\templates\planner_prompt.two_stage.2nd.task.liquid" />
5861
<None Remove="data\agents\01fcc3e5-9af7-49e6-ad7a-a760bd12dc4a\templates\response_with_function.liquid" />
5962
<None Remove="data\agents\dfd9b46d-d00c-40af-8a75-3fbdc2b89869\agent.json" />
6063
<None Remove="data\agents\dfd9b46d-d00c-40af-8a75-3fbdc2b89869\instruction.liquid" />
@@ -76,6 +79,15 @@
7679
<Content Include="data\agents\01fcc3e5-9af7-49e6-ad7a-a760bd12dc4a\instruction.liquid">
7780
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
7881
</Content>
82+
<Content Include="data\agents\01fcc3e5-9af7-49e6-ad7a-a760bd12dc4a\templates\planner_prompt.two_stage.1st.plan.liquid">
83+
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
84+
</Content>
85+
<Content Include="data\agents\01fcc3e5-9af7-49e6-ad7a-a760bd12dc4a\templates\planner_prompt.two_stage.2nd.plan.liquid">
86+
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
87+
</Content>
88+
<Content Include="data\agents\01fcc3e5-9af7-49e6-ad7a-a760bd12dc4a\templates\planner_prompt.two_stage.2nd.task.liquid">
89+
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
90+
</Content>
7991
<Content Include="data\agents\01fcc3e5-9af7-49e6-ad7a-a760bd12dc4a\templates\planner_prompt.sequential.get_remaining_task.liquid">
8092
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
8193
</Content>
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
using System.Text.Json.Serialization;
2+
3+
namespace BotSharp.Core.Routing.Planning;
4+
5+
public class FirstStagePlan
6+
{
7+
[JsonPropertyName("task_detail")]
8+
public string Task { get; set; } = "";
9+
10+
[JsonPropertyName("reason")]
11+
public string Reason { get; set; } = "";
12+
13+
[JsonPropertyName("step")]
14+
public int Step { get; set; } = -1;
15+
16+
[JsonPropertyName("contain_multiple_steps")]
17+
public bool ContainMultipleSteps { get; set; } = false;
18+
19+
[JsonPropertyName("related_tables")]
20+
public string[] Tables { get; set; } = new string[0];
21+
22+
[JsonPropertyName("input_args")]
23+
public JsonDocument[] Parameters { get; set; } = new JsonDocument[0];
24+
25+
[JsonPropertyName("output_results")]
26+
public string[] Results { get; set; } = new string[0];
27+
28+
public override string ToString()
29+
{
30+
return $"STEP {Step}: {Task}";
31+
}
32+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
using System.Text.Json.Serialization;
2+
3+
public class FirstStagePlanParameter
4+
{
5+
[JsonPropertyName("input_args")]
6+
public JsonDocument[] Parameters { get; set; } = new JsonDocument[0];
7+
8+
[JsonPropertyName("output_results")]
9+
public string[] Results { get; set; } = new string[0];
10+
11+
public override string ToString()
12+
{
13+
return $"INPUTS:\r\n{JsonSerializer.Serialize(Parameters)}\r\n\r\nOUTPUTS:\r\n{JsonSerializer.Serialize(Results)}";
14+
}
15+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
using System.Text.Json.Serialization;
2+
3+
namespace BotSharp.Core.Routing.Planning;
4+
5+
public class SecondStagePlan
6+
{
7+
[JsonPropertyName("related_tables")]
8+
public string[] Tables { get; set; } = new string[0];
9+
10+
[JsonPropertyName("description")]
11+
public string Description { get; set; } = "";
12+
13+
[JsonPropertyName("tool_name")]
14+
public string Tool { get; set; } = "";
15+
16+
[JsonPropertyName("input_args")]
17+
public JsonDocument[] Parameters { get; set; } = new JsonDocument[0];
18+
19+
[JsonPropertyName("output_results")]
20+
public string[] Results { get; set; } = new string[0];
21+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
public class SecondStagePlanParameter : FirstStagePlanParameter
2+
{
3+
4+
}
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
using BotSharp.Abstraction.Agents.Models;
2+
using BotSharp.Abstraction.MLTasks;
3+
using BotSharp.Abstraction.Templating;
4+
5+
namespace BotSharp.Core.Routing.Planning;
6+
7+
public partial class TwoStagePlanner
8+
{
9+
private async Task<FirstStagePlan[]> GetFirstStagePlanAsync(Agent router, string messageId, List<RoleDialogModel> dialogs)
10+
{
11+
var firstStagePlanPrompt = await GetFirstStagePlanPrompt(router);
12+
13+
var plan = new FirstStagePlan[0];
14+
15+
var llmProviderService = _services.GetRequiredService<ILlmProviderService>();
16+
var model = llmProviderService.GetProviderModel("azure-openai", "gpt-4");
17+
18+
// chat completion
19+
var completion = CompletionProvider.GetChatCompletion(_services,
20+
provider: "azure-openai",
21+
model: model.Name);
22+
23+
string text = string.Empty;
24+
25+
try
26+
{
27+
var response = await completion.GetChatCompletions(new Agent
28+
{
29+
Id = router.Id,
30+
Name = nameof(TwoStagePlanner),
31+
Instruction = firstStagePlanPrompt
32+
}, dialogs);
33+
34+
text = response.Content;
35+
plan = response.Content.JsonArrayContent<FirstStagePlan>();
36+
}
37+
catch (Exception ex)
38+
{
39+
_logger.LogError($"{ex.Message}: {text}");
40+
}
41+
42+
return plan;
43+
}
44+
45+
private async Task<string> GetFirstStagePlanPrompt(Agent router)
46+
{
47+
var template = router.Templates.First(x => x.Name == "planner_prompt.two_stage.1st.plan").Content;
48+
var responseFormat = JsonSerializer.Serialize(new FirstStagePlan
49+
{
50+
Parameters = new JsonDocument[]{ JsonDocument.Parse("{}") },
51+
Results = new string[] { "" }
52+
});
53+
54+
var relevantKnowledges = new List<string>();
55+
var hooks = _services.GetServices<IKnowledgeHook>();
56+
foreach (var hook in hooks)
57+
{
58+
var k = await hook.GetRelevantKnowledges();
59+
relevantKnowledges.AddRange(k);
60+
}
61+
62+
var render = _services.GetRequiredService<ITemplateRender>();
63+
return render.Render(template, new Dictionary<string, object>
64+
{
65+
{ "response_format", responseFormat },
66+
{ "relevant_knowledges", relevantKnowledges.ToArray() }
67+
});
68+
}
69+
70+
private string GetFirstStageNextPrompt(Agent router)
71+
{
72+
var template = router.Templates.First(x => x.Name == "planner_prompt.first_stage.next").Content;
73+
var responseFormat = JsonSerializer.Serialize(new FirstStagePlan
74+
{
75+
});
76+
var render = _services.GetRequiredService<ITemplateRender>();
77+
return render.Render(template, new Dictionary<string, object>
78+
{
79+
{ "response_format", responseFormat },
80+
});
81+
}
82+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
namespace BotSharp.Core.Routing.Planning;
2+
3+
public partial class TwoStagePlanner
4+
{
5+
public string GetContext()
6+
{
7+
var content = "";
8+
foreach (var c in _executionContext)
9+
{
10+
content += $"* {c}\r\n";
11+
}
12+
return content;
13+
}
14+
}
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
using BotSharp.Abstraction.Agents.Models;
2+
using BotSharp.Abstraction.MLTasks;
3+
using BotSharp.Abstraction.Templating;
4+
5+
namespace BotSharp.Core.Routing.Planning;
6+
7+
public partial class TwoStagePlanner
8+
{
9+
private async Task<SecondStagePlan[]> GetSecondStagePlanAsync(Agent router, string messageId, FirstStagePlan plan1st, List<RoleDialogModel> dialogs)
10+
{
11+
var secondStagePrompt = GetSecondStagePlanPrompt(router, plan1st);
12+
var firstStageSystemPrompt = await GetFirstStagePlanPrompt(router);
13+
14+
var plan = new SecondStagePlan[0];
15+
16+
var llmProviderService = _services.GetRequiredService<ILlmProviderService>();
17+
var model = llmProviderService.GetProviderModel("azure-openai", "gpt-4");
18+
19+
// chat completion
20+
var completion = CompletionProvider.GetChatCompletion(_services,
21+
provider: "azure-openai",
22+
model: model.Name);
23+
24+
string text = string.Empty;
25+
26+
var conversations = dialogs.Where(x => x.Role != AgentRole.Function).ToList();
27+
conversations.Add(new RoleDialogModel(AgentRole.User, secondStagePrompt)
28+
{
29+
CurrentAgentId = router.Id,
30+
MessageId = messageId,
31+
});
32+
33+
try
34+
{
35+
var response = await completion.GetChatCompletions(new Agent
36+
{
37+
Id = router.Id,
38+
Name = nameof(TwoStagePlanner),
39+
Instruction = firstStageSystemPrompt
40+
}, conversations);
41+
42+
text = response.Content;
43+
plan = response.Content.JsonArrayContent<SecondStagePlan>();
44+
}
45+
catch (Exception ex)
46+
{
47+
_logger.LogError($"{ex.Message}: {text}");
48+
}
49+
50+
return plan;
51+
}
52+
53+
private string GetSecondStageTaskPrompt(Agent router, SecondStagePlan plan)
54+
{
55+
var template = router.Templates.First(x => x.Name == "planner_prompt.two_stage.2nd.task").Content;
56+
var render = _services.GetRequiredService<ITemplateRender>();
57+
return render.Render(template, new Dictionary<string, object>
58+
{
59+
{ "task_description", plan.Description },
60+
{ "related_tables", plan.Tables },
61+
{ "input_arguments", JsonSerializer.Serialize(plan.Parameters) },
62+
{ "output_results", JsonSerializer.Serialize(plan.Results) },
63+
});
64+
}
65+
66+
private string GetSecondStagePlanPrompt(Agent router, FirstStagePlan plan)
67+
{
68+
var template = router.Templates.First(x => x.Name == "planner_prompt.two_stage.2nd.plan").Content;
69+
var responseFormat = JsonSerializer.Serialize(new SecondStagePlan
70+
{
71+
Tool = "tool name if task solution provided",
72+
Parameters = new JsonDocument[] { JsonDocument.Parse("{}") },
73+
Results = new string[] { "" }
74+
});
75+
var context = GetContext();
76+
var render = _services.GetRequiredService<ITemplateRender>();
77+
return render.Render(template, new Dictionary<string, object>
78+
{
79+
{ "task_description", plan.Task },
80+
{ "response_format", responseFormat }
81+
});
82+
}
83+
}

0 commit comments

Comments
 (0)