Skip to content

Commit db709b2

Browse files
authored
Merge branch 'SciSharp:master' into master
2 parents e334c74 + 887619d commit db709b2

File tree

29 files changed

+294
-139
lines changed

29 files changed

+294
-139
lines changed

Directory.Build.props

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
<PropertyGroup>
33
<TargetFramework>net8.0</TargetFramework>
44
<LangVersion>10.0</LangVersion>
5-
<BotSharpVersion>1.2.1</BotSharpVersion>
6-
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
5+
<BotSharpVersion>1.3.1</BotSharpVersion>
6+
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
77
<GenerateDocumentationFile>false</GenerateDocumentationFile>
88
</PropertyGroup>
99
</Project>

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ namespace BotSharp.Abstraction.Agents;
1010
public interface IAgentService
1111
{
1212
Task<Agent> CreateAgent(Agent agent);
13-
Task RefreshAgents();
13+
Task<string> RefreshAgents();
1414
Task<PagedItems<Agent>> GetAgents(AgentFilter filter);
1515

1616
/// <summary>
@@ -26,6 +26,8 @@ public interface IAgentService
2626

2727
bool RenderFunction(Agent agent, FunctionDef def);
2828

29+
FunctionParametersDef? RenderFunctionProperty(Agent agent, FunctionDef def);
30+
2931
/// <summary>
3032
/// Get agent detail without trigger any hook.
3133
/// </summary>
@@ -35,7 +37,7 @@ public interface IAgentService
3537

3638
Task<bool> DeleteAgent(string id);
3739
Task UpdateAgent(Agent agent, AgentField updateField);
38-
Task UpdateAgentFromFile(string id);
40+
Task<string> UpdateAgentFromFile(string id);
3941
string GetDataDir();
4042
string GetAgentDataDir(string agentId);
4143

src/Infrastructure/BotSharp.Abstraction/Conversations/IConversationStateService.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ namespace BotSharp.Abstraction.Conversations;
99
public interface IConversationStateService
1010
{
1111
string GetConversationId();
12-
Dictionary<string, string> Load(string conversationId);
12+
Dictionary<string, string> Load(string conversationId, bool isReadOnly = false);
1313
string GetState(string name, string defaultValue = "");
1414
bool ContainsState(string name);
1515
Dictionary<string, string> GetStates();

src/Infrastructure/BotSharp.Abstraction/Messaging/Enums/EditorTypeEnum.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ public static class EditorTypeEnum
1212
public const string DateTimePicker = "datetime-picker";
1313
public const string DateTimeRangePicker = "datetime-range-picker";
1414
public const string Email = "email";
15+
public const string File = "file";
1516

1617
/// <summary>
1718
/// Regex, set the expression in editor_attributes

src/Infrastructure/BotSharp.Abstraction/Messaging/Models/RichContent/ElementButton.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,7 @@ public class ElementButton
2020

2121
[JsonPropertyName("is_secondary")]
2222
public bool IsSecondary { get; set; }
23+
24+
[JsonPropertyName("post_action_disclaimer")]
25+
public string? PostActionDisclaimer { get; set; }
2326
}

src/Infrastructure/BotSharp.Abstraction/Messaging/Models/RichContent/Template/GenericTemplateMessage.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ public class GenericTemplateMessage<T> : IRichMessage, ITemplateMessage
1919
[JsonPropertyName("is_horizontal")]
2020
public bool IsHorizontal { get; set; }
2121

22+
[JsonPropertyName("is_popup")]
23+
public bool IsPopup { get; set; }
24+
2225
[JsonPropertyName("element_type")]
2326
public string ElementType => typeof(T).Name;
2427
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
namespace BotSharp.Abstraction.Repositories.Enums;
2+
3+
public static class RepositoryEnum
4+
{
5+
public const string FileRepository = nameof(FileRepository);
6+
public const string MongoRepository = nameof(MongoRepository);
7+
}

src/Infrastructure/BotSharp.Abstraction/Repositories/IBotSharpRepository.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ public interface IBotSharpRepository
3232
void BulkInsertAgents(List<Agent> agents);
3333
void BulkInsertUserAgents(List<UserAgent> userAgents);
3434
bool DeleteAgents();
35+
bool DeleteAgent(string agentId);
3536
List<string> GetAgentResponses(string agentId, string prefix, string intent);
3637
string GetAgentTemplate(string agentId, string templateName);
3738
#endregion
@@ -42,7 +43,7 @@ public interface IBotSharpRepository
4243
void InsertAgentTask(AgentTask task);
4344
void BulkInsertAgentTasks(List<AgentTask> tasks);
4445
void UpdateAgentTask(AgentTask task, AgentTaskField field);
45-
bool DeleteAgentTask(string agentId, string taskId);
46+
bool DeleteAgentTask(string agentId, List<string> taskIds);
4647
bool DeleteAgentTasks();
4748
#endregion
4849

Lines changed: 68 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,89 @@
1-
using BotSharp.Abstraction.Tasks.Models;
1+
using BotSharp.Abstraction.Repositories.Enums;
22
using System.IO;
33

44
namespace BotSharp.Core.Agents.Services;
55

66
public partial class AgentService
77
{
8-
public async Task RefreshAgents()
8+
public async Task<string> RefreshAgents()
99
{
10-
var isAgentDeleted = _db.DeleteAgents();
11-
var isTaskDeleted = _db.DeleteAgentTasks();
12-
if (!isAgentDeleted) return;
13-
10+
string refreshResult;
1411
var dbSettings = _services.GetRequiredService<BotSharpDatabaseSettings>();
12+
if (dbSettings.Default == RepositoryEnum.FileRepository)
13+
{
14+
refreshResult = $"Invalid database repository setting: {dbSettings.Default}";
15+
_logger.LogWarning(refreshResult);
16+
return refreshResult;
17+
}
18+
1519
var agentDir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory,
1620
dbSettings.FileRepository,
1721
_agentSettings.DataDir);
1822

23+
if (!Directory.Exists(agentDir))
24+
{
25+
refreshResult = $"Cannot find the directory: {agentDir}";
26+
return refreshResult;
27+
}
28+
1929
var user = _db.GetUserById(_user.Id);
20-
var agents = new List<Agent>();
21-
var userAgents = new List<UserAgent>();
22-
var agentTasks = new List<AgentTask>();
30+
var refreshedAgents = new List<string>();
2331

2432
foreach (var dir in Directory.GetDirectories(agentDir))
2533
{
26-
var agentJson = File.ReadAllText(Path.Combine(dir, "agent.json"));
27-
var agent = JsonSerializer.Deserialize<Agent>(agentJson, _options);
28-
if (agent == null) continue;
29-
30-
var functions = FetchFunctionsFromFile(dir);
31-
var instruction = FetchInstructionFromFile(dir);
32-
var responses = FetchResponsesFromFile(dir);
33-
var templates = FetchTemplatesFromFile(dir);
34-
var samples = FetchSamplesFromFile(dir);
35-
agent.SetInstruction(instruction)
36-
.SetTemplates(templates)
37-
.SetFunctions(functions)
38-
.SetResponses(responses)
39-
.SetSamples(samples);
40-
agents.Add(agent);
41-
42-
var userAgent = BuildUserAgent(agent.Id, user.Id);
43-
userAgents.Add(userAgent);
44-
45-
var tasks = FetchTasksFromFile(dir);
46-
agentTasks.AddRange(tasks);
34+
try
35+
{
36+
var agentJson = File.ReadAllText(Path.Combine(dir, "agent.json"));
37+
var agent = JsonSerializer.Deserialize<Agent>(agentJson, _options);
38+
39+
if (agent == null)
40+
{
41+
_logger.LogError($"Cannot find agent in file directory: {dir}");
42+
continue;
43+
}
44+
45+
var functions = FetchFunctionsFromFile(dir);
46+
var instruction = FetchInstructionFromFile(dir);
47+
var responses = FetchResponsesFromFile(dir);
48+
var templates = FetchTemplatesFromFile(dir);
49+
var samples = FetchSamplesFromFile(dir);
50+
agent.SetInstruction(instruction)
51+
.SetTemplates(templates)
52+
.SetFunctions(functions)
53+
.SetResponses(responses)
54+
.SetSamples(samples);
55+
56+
var userAgent = BuildUserAgent(agent.Id, user.Id);
57+
var tasks = FetchTasksFromFile(dir);
58+
59+
var isAgentDeleted = _db.DeleteAgent(agent.Id);
60+
if (isAgentDeleted)
61+
{
62+
await Task.Delay(100);
63+
_db.BulkInsertAgents(new List<Agent> { agent });
64+
_db.BulkInsertUserAgents(new List<UserAgent> { userAgent });
65+
_db.BulkInsertAgentTasks(tasks);
66+
refreshedAgents.Add(agent.Name);
67+
_logger.LogInformation($"Agent {agent.Name} has been migrated.");
68+
}
69+
}
70+
catch (Exception ex)
71+
{
72+
_logger.LogError($"Failed to migrate agent in file directory: {dir}\r\nError: {ex.Message}");
73+
}
4774
}
4875

49-
_db.BulkInsertAgents(agents);
50-
_db.BulkInsertUserAgents(userAgents);
51-
_db.BulkInsertAgentTasks(agentTasks);
76+
if (!refreshedAgents.IsNullOrEmpty())
77+
{
78+
Utilities.ClearCache();
79+
refreshResult = $"Agents are migrated!\r\n{string.Join("\r\n", refreshedAgents)}";
80+
}
81+
else
82+
{
83+
refreshResult = "No agent gets refreshed!";
84+
}
5285

53-
Utilities.ClearCache();
86+
_logger.LogInformation(refreshResult);
87+
return refreshResult;
5488
}
5589
}

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

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using BotSharp.Abstraction.Loggers;
22
using BotSharp.Abstraction.Templating;
3+
using Newtonsoft.Json.Linq;
34

45
namespace BotSharp.Core.Agents.Services;
56

@@ -32,6 +33,64 @@ public bool RenderFunction(Agent agent, FunctionDef def)
3233
return true;
3334
}
3435

36+
public FunctionParametersDef? RenderFunctionProperty(Agent agent, FunctionDef def)
37+
{
38+
var parameterDef = def?.Parameters;
39+
var propertyDef = parameterDef?.Properties;
40+
if (propertyDef == null) return null;
41+
42+
var visibleExpress = "visibility_expression";
43+
var root = propertyDef.RootElement;
44+
var iterator = root.EnumerateObject();
45+
var visibleProps = new List<string>();
46+
while (iterator.MoveNext())
47+
{
48+
var prop = iterator.Current;
49+
var name = prop.Name;
50+
var node = prop.Value;
51+
var matched = true;
52+
if (node.TryGetProperty(visibleExpress, out var element))
53+
{
54+
var expression = element.GetString();
55+
var render = _services.GetRequiredService<ITemplateRender>();
56+
var result = render.Render(expression, new Dictionary<string, object>
57+
{
58+
{ "states", agent.TemplateDict }
59+
});
60+
matched = result == "visible";
61+
}
62+
63+
if (matched)
64+
{
65+
visibleProps.Add(name);
66+
}
67+
}
68+
69+
var rootObject = JObject.Parse(root.GetRawText());
70+
var clonedRoot = rootObject.DeepClone() as JObject;
71+
var required = parameterDef?.Required ?? new List<string>();
72+
foreach (var property in rootObject.Properties())
73+
{
74+
if (visibleProps.Contains(property.Name))
75+
{
76+
var value = clonedRoot.GetValue(property.Name) as JObject;
77+
if (value != null && value.ContainsKey(visibleExpress))
78+
{
79+
value.Remove(visibleExpress);
80+
}
81+
}
82+
else
83+
{
84+
clonedRoot.Remove(property.Name);
85+
required.Remove(property.Name);
86+
}
87+
}
88+
89+
parameterDef.Properties = JsonSerializer.Deserialize<JsonDocument>(clonedRoot.ToString());
90+
parameterDef.Required = required;
91+
return parameterDef; ;
92+
}
93+
3594
public string RenderedTemplate(Agent agent, string templateName)
3695
{
3796
// render liquid template

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

Lines changed: 40 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using BotSharp.Abstraction.Agents.Models;
22
using BotSharp.Abstraction.Functions.Models;
33
using BotSharp.Abstraction.Repositories;
4+
using BotSharp.Abstraction.Repositories.Enums;
45
using BotSharp.Abstraction.Routing.Models;
56
using System.IO;
67

@@ -39,21 +40,41 @@ public async Task UpdateAgent(Agent agent, AgentField updateField)
3940
await Task.CompletedTask;
4041
}
4142

42-
public async Task UpdateAgentFromFile(string id)
43+
public async Task<string> UpdateAgentFromFile(string id)
4344
{
44-
var agent = _db.GetAgent(id);
45-
46-
if (agent == null) return;
47-
45+
string updateResult;
4846
var dbSettings = _services.GetRequiredService<BotSharpDatabaseSettings>();
4947
var agentSettings = _services.GetRequiredService<AgentSettings>();
48+
49+
if (dbSettings.Default == RepositoryEnum.FileRepository)
50+
{
51+
updateResult = $"Invalid database repository setting: {dbSettings.Default}";
52+
_logger.LogWarning(updateResult);
53+
return updateResult;
54+
}
55+
56+
var agent = _db.GetAgent(id);
57+
if (agent == null)
58+
{
59+
updateResult = $"Cannot find agent ${id}";
60+
_logger.LogError(updateResult);
61+
return updateResult;
62+
}
63+
5064
var filePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory,
5165
dbSettings.FileRepository,
5266
agentSettings.DataDir);
5367

5468
var clonedAgent = Agent.Clone(agent);
5569
var foundAgent = FetchAgentFileById(agent.Id, filePath);
56-
if (foundAgent != null)
70+
if (foundAgent == null)
71+
{
72+
updateResult = $"Cannot find agent {agent.Name} in file directory: {filePath}";
73+
_logger.LogError(updateResult);
74+
return updateResult;
75+
}
76+
77+
try
5778
{
5879
clonedAgent.SetId(foundAgent.Id)
5980
.SetName(foundAgent.Name)
@@ -71,15 +92,24 @@ public async Task UpdateAgentFromFile(string id)
7192
.SetLlmConfig(foundAgent.LlmConfig);
7293

7394
_db.UpdateAgent(clonedAgent, AgentField.All);
74-
7595
Utilities.ClearCache();
76-
}
7796

78-
await Task.CompletedTask;
97+
updateResult = $"Agent {agent.Name} has been migrated!";
98+
_logger.LogInformation(updateResult);
99+
return updateResult;
100+
}
101+
catch (Exception ex)
102+
{
103+
updateResult = $"Failed to migrate agent {agent.Name} in file directory {filePath}.\r\nError: {ex.Message}";
104+
_logger.LogError(updateResult);
105+
return updateResult;
106+
}
79107
}
80108

81-
private Agent FetchAgentFileById(string agentId, string filePath)
109+
private Agent? FetchAgentFileById(string agentId, string filePath)
82110
{
111+
if (!Directory.Exists(filePath)) return null;
112+
83113
foreach (var dir in Directory.GetDirectories(filePath))
84114
{
85115
var agentJson = File.ReadAllText(Path.Combine(dir, "agent.json"));

0 commit comments

Comments
 (0)