Skip to content

Commit 4a61d61

Browse files
authored
Merge branch 'SciSharp:master' into master
2 parents 65c2c0f + e0cfb18 commit 4a61d61

File tree

10 files changed

+122
-11
lines changed

10 files changed

+122
-11
lines changed

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,4 +63,13 @@ Task<bool> SendMessage(string agentId,
6363
bool IsConversationMode();
6464

6565
void SaveStates();
66+
67+
/// <summary>
68+
/// Get conversation keys for searching
69+
/// </summary>
70+
/// <param name="query">search query</param>
71+
/// <param name="convLimit">conversation limit</param>
72+
/// <param name="preLoad">if pre-loading, then keys are not filter by the search query</param>
73+
/// <returns></returns>
74+
Task<List<string>> GetConversationSearhKeys(string query, int convlimit = 100, int keyLimit = 10, bool preLoad = false);
6675
}

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,9 @@ List<Conversation> GetLastConversations()
146146
=> throw new NotImplementedException();
147147
List<string> GetIdleConversations(int batchSize, int messageLimit, int bufferHours, IEnumerable<string> excludeAgentIds)
148148
=> throw new NotImplementedException();
149-
IEnumerable<string> TruncateConversation(string conversationId, string messageId, bool cleanLog = false)
149+
List<string> TruncateConversation(string conversationId, string messageId, bool cleanLog = false)
150+
=> throw new NotImplementedException();
151+
List<string> GetConversationSearchKeys(int messageLimit = 2, int convlimit = 100)
150152
=> throw new NotImplementedException();
151153
#endregion
152154

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

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,4 +221,18 @@ public void SaveStates()
221221
{
222222
_state.Save();
223223
}
224+
225+
public async Task<List<string>> GetConversationSearhKeys(string query, int convlimit = 100, int keyLimit = 10, bool preLoad = false)
226+
{
227+
var keys = new List<string>();
228+
if (!preLoad && string.IsNullOrWhiteSpace(query))
229+
{
230+
return keys;
231+
}
232+
233+
var db = _services.GetRequiredService<IBotSharpRepository>();
234+
keys = db.GetConversationSearchKeys(convlimit: convlimit);
235+
keys = preLoad ? keys : keys.Where(x => x.Contains(query, StringComparison.OrdinalIgnoreCase)).ToList();
236+
return keys.OrderBy(x => x).Take(keyLimit).ToList();
237+
}
224238
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ public void UpdateConversationStates(string conversationId, List<StateKeyValue>
131131
public void UpdateConversationStatus(string conversationId, string status)
132132
=> throw new NotImplementedException();
133133

134-
public IEnumerable<string> TruncateConversation(string conversationId, string messageId, bool cleanLog = false)
134+
public List<string> TruncateConversation(string conversationId, string messageId, bool cleanLog = false)
135135
=> throw new NotImplementedException();
136136
#endregion
137137

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

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -547,7 +547,7 @@ public List<string> GetIdleConversations(int batchSize, int messageLimit, int bu
547547
}
548548

549549

550-
public IEnumerable<string> TruncateConversation(string conversationId, string messageId, bool cleanLog = false)
550+
public List<string> TruncateConversation(string conversationId, string messageId, bool cleanLog = false)
551551
{
552552
var deletedMessageIds = new List<string>();
553553
if (string.IsNullOrEmpty(conversationId) || string.IsNullOrEmpty(messageId))
@@ -603,6 +603,46 @@ public IEnumerable<string> TruncateConversation(string conversationId, string me
603603
}
604604

605605

606+
public List<string> GetConversationSearchKeys(int messageLimit = 2, int convlimit = 100)
607+
{
608+
var dir = Path.Combine(_dbSettings.FileRepository, _conversationSettings.DataDir);
609+
if (!Directory.Exists(dir)) return [];
610+
611+
var count = 0;
612+
var keys = new List<string>();
613+
614+
foreach (var d in Directory.GetDirectories(dir))
615+
{
616+
var convFile = Path.Combine(d, CONVERSATION_FILE);
617+
var stateFile = Path.Combine(d, STATE_FILE);
618+
if (!File.Exists(convFile) || !File.Exists(stateFile))
619+
{
620+
continue;
621+
}
622+
623+
var convJson = File.ReadAllText(convFile);
624+
var stateJson = File.ReadAllText(stateFile);
625+
var conv = JsonSerializer.Deserialize<Conversation>(convJson, _options);
626+
var states = JsonSerializer.Deserialize<List<StateKeyValue>>(stateJson, _options);
627+
if (conv == null || conv.DialogCount < messageLimit)
628+
{
629+
continue;
630+
}
631+
632+
var stateKeys = states?.Select(x => x.Key)?.Distinct()?.ToList() ?? [];
633+
keys.AddRange(stateKeys);
634+
count++;
635+
636+
if (count > convlimit)
637+
{
638+
break;
639+
}
640+
}
641+
642+
return keys.Distinct().ToList();
643+
}
644+
645+
606646
#region Private methods
607647
private string? FindConversationDirectory(string conversationId)
608648
{

src/Infrastructure/BotSharp.OpenAPI/Controllers/ConversationController.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -553,6 +553,16 @@ public async Task<bool> UnpinConversationFromDashboard([FromRoute] string agentI
553553
}
554554
#endregion
555555

556+
#region Search state keys
557+
[HttpGet("/conversation/state/keys")]
558+
public async Task<List<string>> GetConversationStateKeys([FromQuery] string query, [FromQuery] int keyLimit = 10, [FromQuery] bool preLoad = false)
559+
{
560+
var convService = _services.GetRequiredService<IConversationService>();
561+
var keys = await convService.GetConversationSearhKeys(query, keyLimit: keyLimit, preLoad: preLoad);
562+
return keys;
563+
}
564+
#endregion
565+
556566
#region Private methods
557567
private void SetStates(IConversationService conv, NewMessageModel input)
558568
{

src/Plugins/BotSharp.Plugin.MongoStorage/Collections/ConversationDialogDocument.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,6 @@ public class ConversationDialogDocument : MongoBase
44
{
55
public string ConversationId { get; set; }
66
public string AgentId { get; set; }
7+
public DateTime UpdatedTime { get; set; }
78
public List<DialogMongoElement> Dialogs { get; set; }
89
}

src/Plugins/BotSharp.Plugin.MongoStorage/Collections/ConversationStateDocument.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ public class ConversationStateDocument : MongoBase
44
{
55
public string ConversationId { get; set; }
66
public string AgentId { get; set; }
7+
public DateTime UpdatedTime { get; set; }
78
public List<StateMongoElement> States { get; set; } = new List<StateMongoElement>();
89
public List<BreakpointMongoElement> Breakpoints { get; set; } = new List<BreakpointMongoElement>();
910
}

src/Plugins/BotSharp.Plugin.MongoStorage/Repository/MongoRepository.Conversation.cs

Lines changed: 37 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,16 +30,18 @@ public void CreateNewConversation(Conversation conversation)
3030
Id = Guid.NewGuid().ToString(),
3131
ConversationId = convDoc.Id,
3232
AgentId = conversation.AgentId,
33-
Dialogs = new List<DialogMongoElement>()
33+
Dialogs = [],
34+
UpdatedTime = utcNow
3435
};
3536

3637
var stateDoc = new ConversationStateDocument
3738
{
3839
Id = Guid.NewGuid().ToString(),
3940
ConversationId = convDoc.Id,
4041
AgentId = conversation.AgentId,
41-
States = new List<StateMongoElement>(),
42-
Breakpoints = new List<BreakpointMongoElement>()
42+
States = [],
43+
Breakpoints = [],
44+
UpdatedTime = utcNow
4345
};
4446

4547
_dc.Conversations.InsertOne(convDoc);
@@ -97,7 +99,8 @@ public void AppendConversationDialogs(string conversationId, List<DialogElement>
9799
var filterConv = Builders<ConversationDocument>.Filter.Eq(x => x.Id, conversationId);
98100
var filterDialog = Builders<ConversationDialogDocument>.Filter.Eq(x => x.ConversationId, conversationId);
99101
var dialogElements = dialogs.Select(x => DialogMongoElement.ToMongoElement(x)).ToList();
100-
var updateDialog = Builders<ConversationDialogDocument>.Update.PushEach(x => x.Dialogs, dialogElements);
102+
var updateDialog = Builders<ConversationDialogDocument>.Update.PushEach(x => x.Dialogs, dialogElements)
103+
.Set(x => x.UpdatedTime, DateTime.UtcNow);
101104
var updateConv = Builders<ConversationDocument>.Update.Set(x => x.UpdatedTime, DateTime.UtcNow)
102105
.Inc(x => x.DialogCount, dialogs.Count);
103106

@@ -190,7 +193,8 @@ public bool UpdateConversationMessage(string conversationId, UpdateMessageReques
190193
found.SecondaryRichContent = request.Message.RichContent;
191194
}
192195

193-
var update = Builders<ConversationDialogDocument>.Update.Set(x => x.Dialogs, dialogs);
196+
var update = Builders<ConversationDialogDocument>.Update.Set(x => x.Dialogs, dialogs)
197+
.Set(x => x.UpdatedTime, DateTime.UtcNow);
194198
_dc.ConversationDialogs.UpdateOne(filter, update);
195199
return true;
196200
}
@@ -208,7 +212,8 @@ public void UpdateConversationBreakpoint(string conversationId, ConversationBrea
208212
Reason = breakpoint.Reason
209213
};
210214
var filterState = Builders<ConversationStateDocument>.Filter.Eq(x => x.ConversationId, conversationId);
211-
var updateState = Builders<ConversationStateDocument>.Update.Push(x => x.Breakpoints, newBreakpoint);
215+
var updateState = Builders<ConversationStateDocument>.Update.Push(x => x.Breakpoints, newBreakpoint)
216+
.Set(x => x.UpdatedTime, DateTime.UtcNow);
212217

213218
_dc.ConversationStates.UpdateOne(filterState, updateState);
214219
}
@@ -258,7 +263,8 @@ public void UpdateConversationStates(string conversationId, List<StateKeyValue>
258263

259264
var filterStates = Builders<ConversationStateDocument>.Filter.Eq(x => x.ConversationId, conversationId);
260265
var saveStates = states.Select(x => StateMongoElement.ToMongoElement(x)).ToList();
261-
var updateStates = Builders<ConversationStateDocument>.Update.Set(x => x.States, saveStates);
266+
var updateStates = Builders<ConversationStateDocument>.Update.Set(x => x.States, saveStates)
267+
.Set(x => x.UpdatedTime, DateTime.UtcNow);
262268

263269
_dc.ConversationStates.UpdateOne(filterStates, updateStates);
264270
}
@@ -500,7 +506,7 @@ public List<string> GetIdleConversations(int batchSize, int messageLimit, int bu
500506
return conversationIds.Take(batchSize).ToList();
501507
}
502508

503-
public IEnumerable<string> TruncateConversation(string conversationId, string messageId, bool cleanLog = false)
509+
public List<string> TruncateConversation(string conversationId, string messageId, bool cleanLog = false)
504510
{
505511
var deletedMessageIds = new List<string>();
506512
if (string.IsNullOrEmpty(conversationId) || string.IsNullOrEmpty(messageId))
@@ -566,11 +572,13 @@ public IEnumerable<string> TruncateConversation(string conversationId, string me
566572
}
567573

568574
// Update
575+
foundStates.UpdatedTime = DateTime.UtcNow;
569576
_dc.ConversationStates.ReplaceOne(stateFilter, foundStates);
570577
}
571578

572579
// Save dialogs
573580
foundDialog.Dialogs = truncatedDialogs;
581+
foundDialog.UpdatedTime = DateTime.UtcNow;
574582
_dc.ConversationDialogs.ReplaceOne(dialogFilter, foundDialog);
575583

576584
// Update conversation
@@ -603,6 +611,27 @@ public IEnumerable<string> TruncateConversation(string conversationId, string me
603611
return deletedMessageIds;
604612
}
605613

614+
615+
public List<string> GetConversationSearchKeys(int messageLimit = 2, int convlimit = 100)
616+
{
617+
var convFilter = Builders<ConversationDocument>.Filter.Gte(x => x.DialogCount, messageLimit);
618+
var conversations = _dc.Conversations.Find(convFilter)
619+
.SortByDescending(x => x.UpdatedTime)
620+
.Limit(convlimit)
621+
.ToList();
622+
623+
if (conversations.IsNullOrEmpty()) return [];
624+
625+
var convIds = conversations.Select(x => x.Id).ToList();
626+
var stateFilter = Builders<ConversationStateDocument>.Filter.In(x => x.ConversationId, convIds);
627+
628+
var states = _dc.ConversationStates.Find(stateFilter).ToList();
629+
var keys = states.SelectMany(x => x.States.Select(x => x.Key)).Distinct().ToList();
630+
return keys;
631+
}
632+
633+
634+
606635
private string ConvertSnakeCaseToPascalCase(string snakeCase)
607636
{
608637
string[] words = snakeCase.Split('_');

src/Plugins/BotSharp.Plugin.MongoStorage/Repository/MongoRepository.User.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,11 @@ public bool UpdateUser(User user, bool updateUserAgents = false)
429429
return true;
430430
}
431431

432+
public Dashboard? GetDashboard(string userId = null)
433+
{
434+
return null;
435+
}
436+
432437
public void AddDashboardConversation(string userId, string conversationId)
433438
{
434439
var user = _dc.Users.AsQueryable()

0 commit comments

Comments
 (0)