Skip to content

Commit 8dbceb9

Browse files
Merge pull request #159 from hchen2020/master
print functions in verbose.
2 parents 30dec8f + 7b45a27 commit 8dbceb9

File tree

22 files changed

+135
-81
lines changed

22 files changed

+135
-81
lines changed

src/Infrastructure/BotSharp.Abstraction/Agents/AgentHookBase.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using BotSharp.Abstraction.Agents.Settings;
2+
using BotSharp.Abstraction.Functions.Models;
23

34
namespace BotSharp.Abstraction.Agents;
45

@@ -34,7 +35,7 @@ public virtual bool OnInstructionLoaded(string template, Dictionary<string, obje
3435
return true;
3536
}
3637

37-
public virtual bool OnFunctionsLoaded(ref List<string> functions)
38+
public virtual bool OnFunctionsLoaded(ref List<FunctionDef> functions)
3839
{
3940
_agent.Functions = functions;
4041
return true;

src/Infrastructure/BotSharp.Abstraction/Agents/IAgentHook.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
using BotSharp.Abstraction.Functions.Models;
2+
13
namespace BotSharp.Abstraction.Agents;
24

35
public interface IAgentHook
@@ -15,7 +17,7 @@ public interface IAgentHook
1517

1618
bool OnInstructionLoaded(string template, Dictionary<string, object> dict);
1719

18-
bool OnFunctionsLoaded(ref List<string> functions);
20+
bool OnFunctionsLoaded(ref List<FunctionDef> functions);
1921

2022
bool OnSamplesLoaded(ref string samples);
2123

src/Infrastructure/BotSharp.Abstraction/Agents/Models/Agent.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using BotSharp.Abstraction.Functions.Models;
12
using BotSharp.Abstraction.Routing.Models;
23

34
namespace BotSharp.Abstraction.Agents.Models;
@@ -32,7 +33,7 @@ public class Agent
3233
/// Functions
3334
/// </summary>
3435
[JsonIgnore]
35-
public List<string> Functions { get; set; }
36+
public List<FunctionDef> Functions { get; set; } = new List<FunctionDef>();
3637

3738
/// <summary>
3839
/// Responses
@@ -102,9 +103,9 @@ public Agent SetTemplates(List<AgentTemplate> templates)
102103
return this;
103104
}
104105

105-
public Agent SetFunctions(List<string> functions)
106+
public Agent SetFunctions(List<FunctionDef> functions)
106107
{
107-
Functions = functions ?? new List<string>();
108+
Functions = functions ?? new List<FunctionDef>();
108109
return this;
109110
}
110111

src/Infrastructure/BotSharp.Abstraction/Functions/Models/FunctionDef.cs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
1-
using System.Text.Json;
2-
31
namespace BotSharp.Abstraction.Functions.Models;
42

53
public class FunctionDef
64
{
75
public string Name { get; set; }
86
public string Description { get; set; }
9-
public JsonDocument Parameters { get; set; }
7+
public FunctionParametersDef Parameters { get; set; } = new FunctionParametersDef();
108

119
public override string ToString()
1210
{
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
using System.Text.Json;
2+
3+
namespace BotSharp.Abstraction.Functions.Models;
4+
5+
public class FunctionParametersDef
6+
{
7+
[JsonPropertyName("type")]
8+
public string Type { get; set; } = "object";
9+
10+
/// <summary>
11+
/// ParameterPropertyDef
12+
/// {
13+
/// "field_name": {}
14+
/// }
15+
/// </summary>
16+
[JsonPropertyName("properties")]
17+
public JsonDocument Properties { get; set; } = JsonSerializer.Deserialize<JsonDocument>("{}");
18+
19+
[JsonPropertyName("required")]
20+
public List<string> Required { get; set; } = new List<string>();
21+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
namespace BotSharp.Abstraction.Functions.Models;
2+
3+
public class ParameterPropertyDef
4+
{
5+
public string Type { get; set; } = "string";
6+
public string Description { get; set; }
7+
}

src/Infrastructure/BotSharp.Abstraction/Routing/IRoutingHandler.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@
33

44
namespace BotSharp.Abstraction.Routing;
55

6+
/// <summary>
7+
/// The routing handler will be injected to Router's FUNCTIONS section of the system prompt
8+
/// So the handler will be invoked by LLM autonomously.
9+
/// </summary>
610
public interface IRoutingHandler
711
{
812
string Name { get; }

src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.CreateAgent.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using BotSharp.Abstraction.Agents.Models;
2+
using BotSharp.Abstraction.Functions.Models;
23
using BotSharp.Abstraction.Repositories;
34
using System.IO;
45

@@ -114,14 +115,13 @@ private List<AgentTemplate> FetchTemplatesFromFile(string fileDir)
114115
return templates;
115116
}
116117

117-
private List<string> FetchFunctionsFromFile(string fileDir)
118+
private List<FunctionDef> FetchFunctionsFromFile(string fileDir)
118119
{
119120
var file = Path.Combine(fileDir, "functions.json");
120-
if (!File.Exists(file)) return new List<string>();
121+
if (!File.Exists(file)) return new List<FunctionDef>();
121122

122123
var functionsJson = File.ReadAllText(file);
123-
var functionDefs = JsonSerializer.Deserialize<List<Abstraction.Functions.Models.FunctionDef>>(functionsJson, _options);
124-
var functions = functionDefs.Select(x => JsonSerializer.Serialize(x, _options)).ToList();
124+
var functions = JsonSerializer.Deserialize<List<FunctionDef>>(functionsJson, _options);
125125
return functions;
126126
}
127127

src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.LoadAgent.cs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
using BotSharp.Abstraction.Agents.Models;
2-
using BotSharp.Abstraction.Routing;
3-
using BotSharp.Abstraction.Routing.Settings;
42
using BotSharp.Abstraction.Templating;
53

64
namespace BotSharp.Core.Agents.Services;
@@ -34,7 +32,7 @@ public async Task<Agent> LoadAgent(string id)
3432
hook.OnInstructionLoaded(agent.Instruction, templateDict);
3533
}
3634

37-
if (!agent.Functions.IsNullOrEmpty())
35+
if (agent.Functions != null)
3836
{
3937
var functions = agent.Functions;
4038
hook.OnFunctionsLoaded(ref functions);

src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.UpdateAgent.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using BotSharp.Abstraction.Agents.Models;
2+
using BotSharp.Abstraction.Functions.Models;
23
using BotSharp.Abstraction.Repositories;
34
using BotSharp.Abstraction.Routing.Models;
45
using System.IO;
@@ -22,7 +23,7 @@ public async Task UpdateAgent(Agent agent, AgentField updateField)
2223
record.Profiles = agent.Profiles ?? new List<string>();
2324
record.RoutingRules = agent.RoutingRules ?? new List<RoutingRule>();
2425
record.Instruction = agent.Instruction ?? string.Empty;
25-
record.Functions = agent.Functions ?? new List<string>();
26+
record.Functions = agent.Functions ?? new List<FunctionDef>();
2627
record.Templates = agent.Templates ?? new List<AgentTemplate>();
2728
record.Responses = agent.Responses ?? new List<AgentResponse>();
2829

src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ public AgentService(IServiceProvider services,
2727
{
2828
PropertyNameCaseInsensitive = true,
2929
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
30-
WriteIndented = true
30+
WriteIndented = true,
31+
AllowTrailingCommas = true
3132
};
3233
}
3334

src/Infrastructure/BotSharp.Core/BotSharpServiceCollectionExtensions.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
using BotSharp.Core.Instructs;
1010
using BotSharp.Abstraction.Instructs;
1111
using BotSharp.Abstraction.Routing;
12-
using System.Reflection;
12+
using BotSharp.Core.Routing.Hooks;
1313

1414
namespace BotSharp.Core;
1515

@@ -63,6 +63,8 @@ public static IServiceCollection AddBotSharp(this IServiceCollection services, I
6363
services.AddScoped<IInstructService, InstructService>();
6464
services.AddScoped<ITokenStatistics, TokenStatistics>();
6565

66+
services.AddScoped<IAgentHook, RoutingAgentHook>();
67+
6668
return services;
6769
}
6870

src/Infrastructure/BotSharp.Core/Conversations/Services/TokenStatistics.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ public void AddToken(TokenStatsModel stats)
5151

5252
public void PrintStatistics()
5353
{
54-
var stats = $"Token Usage: {_promptTokenCount} prompt + {_completionTokenCount} completion = {Total} total tokens. One-Way cost: ${Cost:C4}, accumulated cost: ${AccumulatedCost:C4}. Model: {_model}";
54+
var stats = $"Token Usage: {_promptTokenCount} prompt + {_completionTokenCount} completion = {Total} total tokens. One-Way cost: {Cost:C4}, accumulated cost: {AccumulatedCost:C4}. [{_model}]";
5555
#if DEBUG
5656
Console.WriteLine(stats, Color.DarkGray);
5757
#else

src/Infrastructure/BotSharp.Core/Repository/FileRepository.cs

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -372,7 +372,7 @@ private void UpdateAgentInstruction(string agentId, string instruction)
372372
File.WriteAllText(instructionFile, instruction);
373373
}
374374

375-
private void UpdateAgentFunctions(string agentId, List<string> inputFunctions)
375+
private void UpdateAgentFunctions(string agentId, List<FunctionDef> inputFunctions)
376376
{
377377
if (inputFunctions.IsNullOrEmpty()) return;
378378

@@ -385,8 +385,7 @@ private void UpdateAgentFunctions(string agentId, List<string> inputFunctions)
385385
var functions = new List<string>();
386386
foreach (var function in inputFunctions)
387387
{
388-
var functionDef = JsonSerializer.Deserialize<FunctionDef>(function, _options);
389-
functions.Add(JsonSerializer.Serialize(functionDef, _options));
388+
functions.Add(JsonSerializer.Serialize(function, _options));
390389
}
391390

392391
var functionText = JsonSerializer.Serialize(functions, _options);
@@ -730,14 +729,13 @@ private string FetchInstruction(string fileDir)
730729
return instruction;
731730
}
732731

733-
private List<string> FetchFunctions(string fileDir)
732+
private List<FunctionDef> FetchFunctions(string fileDir)
734733
{
735734
var file = Path.Combine(fileDir, "functions.json");
736-
if (!File.Exists(file)) return new List<string>();
735+
if (!File.Exists(file)) return new List<FunctionDef>();
737736

738737
var functionsJson = File.ReadAllText(file);
739-
var functionDefs = JsonSerializer.Deserialize<List<FunctionDef>>(functionsJson, _options);
740-
var functions = functionDefs.Select(x => JsonSerializer.Serialize(x, _options)).ToList();
738+
var functions = JsonSerializer.Deserialize<List<FunctionDef>>(functionsJson, _options);
741739
return functions;
742740
}
743741

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
using BotSharp.Abstraction.Functions.Models;
2+
3+
namespace BotSharp.Core.Routing.Hooks;
4+
5+
public class RoutingAgentHook : AgentHookBase
6+
{
7+
public RoutingAgentHook(IServiceProvider services, AgentSettings settings)
8+
: base(services, settings)
9+
{
10+
}
11+
12+
public override bool OnFunctionsLoaded(ref List<FunctionDef> functions)
13+
{
14+
functions.Add(new FunctionDef
15+
{
16+
Name = "fallback_to_router",
17+
Description = "If the user's request is beyond your capabilities, you can call this function for help."
18+
});
19+
return base.OnFunctionsLoaded(ref functions);
20+
}
21+
}

src/Infrastructure/BotSharp.Core/Routing/RoutingService.InvokeAgent.cs

Lines changed: 31 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -18,51 +18,48 @@ public async Task<RoleDialogModel> InvokeAgent(string agentId)
1818
var agent = await agentService.LoadAgent(agentId);
1919

2020
var chatCompletion = CompletionProvider.GetChatCompletion(_services);
21+
RoleDialogModel response = chatCompletion.GetChatCompletions(agent, Dialogs);
2122

22-
RoleDialogModel response = null;
23-
await chatCompletion.GetChatCompletionsAsync(agent, Dialogs,
24-
async msg =>
25-
{
26-
response = msg;
27-
}, async fn =>
28-
{
29-
// execute function
30-
// Save states
31-
SaveStateByArgs(JsonSerializer.Deserialize<JsonDocument>(fn.FunctionArgs));
23+
if (response.Role == AgentRole.Function)
24+
{
25+
var fn = response;
26+
// execute function
27+
// Save states
28+
SaveStateByArgs(JsonSerializer.Deserialize<JsonDocument>(fn.FunctionArgs));
3229

33-
var conversationService = _services.GetRequiredService<IConversationService>();
34-
// Call functions
35-
await conversationService.CallFunctions(fn);
30+
var conversationService = _services.GetRequiredService<IConversationService>();
31+
// Call functions
32+
await conversationService.CallFunctions(fn);
3633

37-
if (string.IsNullOrEmpty(fn.Content))
38-
{
39-
fn.Content = fn.ExecutionResult;
40-
}
34+
if (string.IsNullOrEmpty(fn.Content))
35+
{
36+
fn.Content = fn.ExecutionResult;
37+
}
4138

42-
Dialogs.Add(fn);
39+
Dialogs.Add(fn);
4340

44-
if (!fn.StopCompletion)
41+
if (!fn.StopCompletion)
42+
{
43+
// Find response template
44+
var templateService = _services.GetRequiredService<IResponseTemplateService>();
45+
var quickResponse = await templateService.RenderFunctionResponse(agent.Id, fn);
46+
if (!string.IsNullOrEmpty(quickResponse))
4547
{
46-
// Find response template
47-
var templateService = _services.GetRequiredService<IResponseTemplateService>();
48-
var quickResponse = await templateService.RenderFunctionResponse(agent.Id, fn);
49-
if (!string.IsNullOrEmpty(quickResponse))
50-
{
51-
response = new RoleDialogModel(AgentRole.Assistant, quickResponse)
52-
{
53-
CurrentAgentId = agent.Id
54-
};
55-
}
56-
else
48+
response = new RoleDialogModel(AgentRole.Assistant, quickResponse)
5749
{
58-
response = await InvokeAgent(fn.CurrentAgentId);
59-
}
50+
CurrentAgentId = agent.Id
51+
};
6052
}
6153
else
6254
{
63-
response = fn;
55+
response = await InvokeAgent(fn.CurrentAgentId);
6456
}
65-
});
57+
}
58+
else
59+
{
60+
response = fn;
61+
}
62+
}
6663

6764
return response;
6865
}

src/Infrastructure/BotSharp.OpenAPI/ViewModels/Agents/AgentCreationModel.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using BotSharp.Abstraction.Agents.Models;
2+
using BotSharp.Abstraction.Functions.Models;
23
using BotSharp.Abstraction.Routing.Models;
34

45
namespace BotSharp.OpenAPI.ViewModels.Agents;
@@ -9,7 +10,7 @@ public class AgentCreationModel
910
public string Description { get; set; }
1011
public string Instruction { get; set; }
1112
public List<AgentTemplate> Templates { get; set; }
12-
public List<string> Functions { get; set; }
13+
public List<FunctionDef> Functions { get; set; }
1314
public List<AgentResponse> Responses { get; set; }
1415
public bool IsPublic { get; set; }
1516
public bool AllowRouting { get; set; }

src/Infrastructure/BotSharp.OpenAPI/ViewModels/Agents/AgentUpdateModel.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using BotSharp.Abstraction.Agents.Models;
2+
using BotSharp.Abstraction.Functions.Models;
23
using BotSharp.Abstraction.Routing.Models;
34

45
namespace BotSharp.OpenAPI.ViewModels.Agents;
@@ -26,7 +27,7 @@ public class AgentUpdateModel
2627
/// <summary>
2728
/// Functions
2829
/// </summary>
29-
public List<string>? Functions { get; set; }
30+
public List<FunctionDef>? Functions { get; set; }
3031

3132
/// <summary>
3233
/// Routes
@@ -61,7 +62,7 @@ public Agent ToAgent()
6162
.ToList() ?? new List<RoutingRule>(),
6263
Instruction = Instruction ?? string.Empty,
6364
Templates = Templates ?? new List<AgentTemplate>(),
64-
Functions = Functions ?? new List<string>(),
65+
Functions = Functions ?? new List<FunctionDef>(),
6566
Responses = Responses ?? new List<AgentResponse>()
6667
};
6768

src/Infrastructure/BotSharp.OpenAPI/ViewModels/Agents/AgentViewModel.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using BotSharp.Abstraction.Agents.Models;
2+
using BotSharp.Abstraction.Functions.Models;
23
using BotSharp.Abstraction.Routing.Models;
34

45
namespace BotSharp.OpenAPI.ViewModels.Agents;
@@ -10,7 +11,7 @@ public class AgentViewModel
1011
public string Description { get; set; }
1112
public string Instruction { get; set; }
1213
public List<AgentTemplate> Templates { get; set; }
13-
public List<string> Functions { get; set; }
14+
public List<FunctionDef> Functions { get; set; }
1415
public List<AgentResponse> Responses { get; set; }
1516
public bool IsPublic { get; set; }
1617
public bool AllowRouting { get; set; }

0 commit comments

Comments
 (0)