diff --git a/BotSharp.sln b/BotSharp.sln
index d4890be1..b176747f 100644
--- a/BotSharp.sln
+++ b/BotSharp.sln
@@ -127,6 +127,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BotSharp.Core.Rules", "src\
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BotSharp.Plugin.DeepSeekAI", "src\Plugins\BotSharp.Plugin.DeepSeekAI\BotSharp.Plugin.DeepSeekAI.csproj", "{AF329442-B48E-4B48-A18A-1C869D1BA6F5}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BotSharp.Core.Realtime", "src\Infrastructure\BotSharp.Core.Realtime\BotSharp.Core.Realtime.csproj", "{7ACD8C95-C66B-436A-80E7-541A57D8C3F4}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -519,6 +521,14 @@ Global
{AF329442-B48E-4B48-A18A-1C869D1BA6F5}.Release|Any CPU.Build.0 = Release|Any CPU
{AF329442-B48E-4B48-A18A-1C869D1BA6F5}.Release|x64.ActiveCfg = Release|Any CPU
{AF329442-B48E-4B48-A18A-1C869D1BA6F5}.Release|x64.Build.0 = Release|Any CPU
+ {7ACD8C95-C66B-436A-80E7-541A57D8C3F4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {7ACD8C95-C66B-436A-80E7-541A57D8C3F4}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {7ACD8C95-C66B-436A-80E7-541A57D8C3F4}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {7ACD8C95-C66B-436A-80E7-541A57D8C3F4}.Debug|x64.Build.0 = Debug|Any CPU
+ {7ACD8C95-C66B-436A-80E7-541A57D8C3F4}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {7ACD8C95-C66B-436A-80E7-541A57D8C3F4}.Release|Any CPU.Build.0 = Release|Any CPU
+ {7ACD8C95-C66B-436A-80E7-541A57D8C3F4}.Release|x64.ActiveCfg = Release|Any CPU
+ {7ACD8C95-C66B-436A-80E7-541A57D8C3F4}.Release|x64.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -580,6 +590,7 @@ Global
{F812BAAE-5A7D-4DF7-8E71-70696B51C61F} = {E29DC6C4-5E57-48C5-BCB0-6B8F84782749}
{AFD64412-4D6A-452E-82A2-79E5D8842E29} = {E29DC6C4-5E57-48C5-BCB0-6B8F84782749}
{AF329442-B48E-4B48-A18A-1C869D1BA6F5} = {D5293208-2BEF-42FC-A64C-5954F61720BA}
+ {7ACD8C95-C66B-436A-80E7-541A57D8C3F4} = {E29DC6C4-5E57-48C5-BCB0-6B8F84782749}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {A9969D89-C98B-40A5-A12B-FC87E55B3A19}
diff --git a/Directory.Build.props b/Directory.Build.props
index 6716a3c7..3cb973b5 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -2,7 +2,7 @@
net8.0
12.0
- 4.0.0
+ 4.1.0
true
false
diff --git a/Directory.Packages.props b/Directory.Packages.props
index a031cec3..aa76cf61 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -1,24 +1,26 @@
8.0.0
+ 2.3.0
+ true
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
+
-
-
-
+
+
@@ -27,14 +29,96 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
diff --git a/src/BotSharp.AppHost/BotSharp.AppHost.csproj b/src/BotSharp.AppHost/BotSharp.AppHost.csproj
index 2a2705db..68673f7d 100644
--- a/src/BotSharp.AppHost/BotSharp.AppHost.csproj
+++ b/src/BotSharp.AppHost/BotSharp.AppHost.csproj
@@ -10,8 +10,8 @@
-
-
+
+
diff --git a/src/BotSharp.ServiceDefaults/BotSharp.ServiceDefaults.csproj b/src/BotSharp.ServiceDefaults/BotSharp.ServiceDefaults.csproj
index 53f9559f..d19f2eea 100644
--- a/src/BotSharp.ServiceDefaults/BotSharp.ServiceDefaults.csproj
+++ b/src/BotSharp.ServiceDefaults/BotSharp.ServiceDefaults.csproj
@@ -9,17 +9,17 @@
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Infrastructure/BotSharp.Abstraction/Agents/IAgentService.cs b/src/Infrastructure/BotSharp.Abstraction/Agents/IAgentService.cs
index cf49da42..7c2466d9 100644
--- a/src/Infrastructure/BotSharp.Abstraction/Agents/IAgentService.cs
+++ b/src/Infrastructure/BotSharp.Abstraction/Agents/IAgentService.cs
@@ -12,7 +12,7 @@ public interface IAgentService
Task CreateAgent(Agent agent);
Task RefreshAgents();
Task> GetAgents(AgentFilter filter);
- Task> GetAgentOptions();
+ Task> GetAgentOptions(List? agentIds = null);
///
/// Load agent configurations and trigger hooks
diff --git a/src/Infrastructure/BotSharp.Abstraction/BotSharp.Abstraction.csproj b/src/Infrastructure/BotSharp.Abstraction/BotSharp.Abstraction.csproj
index f189d323..97e645d0 100644
--- a/src/Infrastructure/BotSharp.Abstraction/BotSharp.Abstraction.csproj
+++ b/src/Infrastructure/BotSharp.Abstraction/BotSharp.Abstraction.csproj
@@ -1,4 +1,4 @@
-
+
$(TargetFramework)
@@ -8,7 +8,6 @@
Icon.png
$(GeneratePackageOnBuild)
$(SolutionDir)packages
- true
diff --git a/src/Infrastructure/BotSharp.Abstraction/Browsing/Models/PageActionArgs.cs b/src/Infrastructure/BotSharp.Abstraction/Browsing/Models/PageActionArgs.cs
index fe575462..1abf7994 100644
--- a/src/Infrastructure/BotSharp.Abstraction/Browsing/Models/PageActionArgs.cs
+++ b/src/Infrastructure/BotSharp.Abstraction/Browsing/Models/PageActionArgs.cs
@@ -16,7 +16,10 @@ public class PageActionArgs
///
/// This value has to be set to true if you want to get the page XHR/ Fetch responses
///
- public bool OpenNewTab { get; set; } = false;
+ [JsonPropertyName("open_new_tab")]
+ public bool OpenNewTab { get; set; } = true;
+ [JsonPropertyName("open_blank_page")]
+ public bool OpenBlankPage { get; set; } = true;
public bool EnableResponseCallback { get; set; } = false;
@@ -47,4 +50,6 @@ public class PageActionArgs
public int WaitTime { get; set; }
public bool ReadInnerHTMLAsBody { get; set; } = false;
+ [JsonPropertyName("keep_browser_open")]
+ public bool KeepBrowserOpen { get; set; } = false;
}
diff --git a/src/Infrastructure/BotSharp.Abstraction/Browsing/Settings/WebBrowsingSettings.cs b/src/Infrastructure/BotSharp.Abstraction/Browsing/Settings/WebBrowsingSettings.cs
index 25149fe0..f876c449 100644
--- a/src/Infrastructure/BotSharp.Abstraction/Browsing/Settings/WebBrowsingSettings.cs
+++ b/src/Infrastructure/BotSharp.Abstraction/Browsing/Settings/WebBrowsingSettings.cs
@@ -3,4 +3,10 @@ namespace BotSharp.Abstraction.Browsing.Settings;
public class WebBrowsingSettings
{
public string Driver { get; set; } = "Playwright";
+ public bool Headless { get; set; }
+ // Default timeout in milliseconds
+ public float DefaultTimeout { get; set; } = 30000;
+ public bool IsEnableScreenshot { get; set; }
+ // Default wait time in seconds after page is opened
+ public int DefaultWaitTime { get; set; } = 5;
}
diff --git a/src/Infrastructure/BotSharp.Abstraction/Conversations/Enums/MessageTypeName.cs b/src/Infrastructure/BotSharp.Abstraction/Conversations/Enums/MessageTypeName.cs
index c13f26a8..e59622bb 100644
--- a/src/Infrastructure/BotSharp.Abstraction/Conversations/Enums/MessageTypeName.cs
+++ b/src/Infrastructure/BotSharp.Abstraction/Conversations/Enums/MessageTypeName.cs
@@ -6,4 +6,5 @@ public static class MessageTypeName
public const string Notification = "notification";
public const string FunctionCall = "function";
public const string Audio = "audio";
+ public const string Error = "error";
}
diff --git a/src/Infrastructure/BotSharp.Abstraction/Conversations/IConversationService.cs b/src/Infrastructure/BotSharp.Abstraction/Conversations/IConversationService.cs
index 6d84103e..15f7e89e 100644
--- a/src/Infrastructure/BotSharp.Abstraction/Conversations/IConversationService.cs
+++ b/src/Infrastructure/BotSharp.Abstraction/Conversations/IConversationService.cs
@@ -13,7 +13,7 @@ public interface IConversationService
Task> GetConversations(ConversationFilter filter);
Task UpdateConversationTitle(string id, string title);
Task UpdateConversationTitleAlias(string id, string titleAlias);
- Task UpdateConversationTags(string conversationId, List tags);
+ Task UpdateConversationTags(string conversationId, List toAddTags, List toDeleteTags);
Task UpdateConversationMessage(string conversationId, UpdateMessageRequest request);
Task> GetLastConversations();
Task> GetIdleConversations(int batchSize, int messageLimit, int bufferHours, IEnumerable excludeAgentIds);
@@ -27,20 +27,17 @@ public interface IConversationService
/// If not null, delete messages while input a new message; otherwise delete messages only
///
Task TruncateConversation(string conversationId, string messageId, string? newMessageId = null);
- Task> GetConversationContentLogs(string conversationId);
- Task> GetConversationStateLogs(string conversationId);
///
/// Send message to LLM
///
///
- ///
+ ///
+ ///
/// Received the response from AI Agent
- /// This delegate is useful when you want to report progress on UI
- /// This delegate is useful when you want to report progress on UI
///
Task SendMessage(string agentId,
- RoleDialogModel lastDalog,
+ RoleDialogModel lastDialog,
PostbackMessageModel? replyMessage,
Func onResponseReceived);
@@ -64,12 +61,7 @@ public interface IConversationService
void SaveStates();
- ///
- /// Get conversation keys for searching
- ///
- /// search query
- /// conversation limit
- /// if pre-loading, then keys are not filter by the search query
- ///
- Task> GetConversationStateSearhKeys(string query, int convLimit = 100, int keyLimit = 10, bool preload = false);
+ Task> GetConversationStateSearhKeys(ConversationStateKeysFilter filter);
+
+ Task MigrateLatestStates(int batchSize = 100, int errorLimit = 10);
}
diff --git a/src/Infrastructure/BotSharp.Abstraction/Conversations/Models/Conversation.cs b/src/Infrastructure/BotSharp.Abstraction/Conversations/Models/Conversation.cs
index 07258402..ac1efb04 100644
--- a/src/Infrastructure/BotSharp.Abstraction/Conversations/Models/Conversation.cs
+++ b/src/Infrastructure/BotSharp.Abstraction/Conversations/Models/Conversation.cs
@@ -58,17 +58,13 @@ public class DialogElement
[JsonPropertyName("payload")]
public string? Payload { get; set; }
- [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
- [JsonPropertyName("data")]
- public object? Data { get; set; }
-
public DialogElement()
{
}
public DialogElement(DialogMetaData meta, string content, string? richContent = null,
- string? secondaryContent = null, string? secondaryRichContent = null, string? payload = null, object? data = null)
+ string? secondaryContent = null, string? secondaryRichContent = null, string? payload = null)
{
MetaData = meta;
Content = content;
@@ -76,7 +72,6 @@ public class DialogElement
SecondaryContent = secondaryContent;
SecondaryRichContent = secondaryRichContent;
Payload = payload;
- Data = data;
}
public override string ToString()
diff --git a/src/Infrastructure/BotSharp.Abstraction/Conversations/Models/RoleDialogModel.cs b/src/Infrastructure/BotSharp.Abstraction/Conversations/Models/RoleDialogModel.cs
index 585112a2..6f96eec5 100644
--- a/src/Infrastructure/BotSharp.Abstraction/Conversations/Models/RoleDialogModel.cs
+++ b/src/Infrastructure/BotSharp.Abstraction/Conversations/Models/RoleDialogModel.cs
@@ -108,7 +108,8 @@ public class RoleDialogModel : ITrackableMessage
[JsonPropertyName("generated_images")]
public List GeneratedImages { get; set; } = new List();
-
+ [JsonIgnore(Condition = JsonIgnoreCondition.Always)]
+ public string RenderedInstruction { get; set; } = string.Empty;
private RoleDialogModel()
{
diff --git a/src/Infrastructure/BotSharp.Abstraction/Files/Utilities/FileUtility.cs b/src/Infrastructure/BotSharp.Abstraction/Files/Utilities/FileUtility.cs
index bf2644dd..db9ccb65 100644
--- a/src/Infrastructure/BotSharp.Abstraction/Files/Utilities/FileUtility.cs
+++ b/src/Infrastructure/BotSharp.Abstraction/Files/Utilities/FileUtility.cs
@@ -47,6 +47,17 @@ public static class FileUtility
return $"data:{contentType};base64,{base64}";
}
+ public static BinaryData BuildBinaryDataFromFile(IFormFile file)
+ {
+ using var stream = new MemoryStream();
+ file.CopyTo(stream);
+ stream.Position = 0;
+ var binary = BinaryData.FromStream(stream);
+ stream.Close();
+
+ return binary;
+ }
+
public static string GetFileContentType(string fileName)
{
string contentType;
diff --git a/src/Infrastructure/BotSharp.Abstraction/Infrastructures/Enums/StateConst.cs b/src/Infrastructure/BotSharp.Abstraction/Infrastructures/Enums/StateConst.cs
index 466893d3..9db7c440 100644
--- a/src/Infrastructure/BotSharp.Abstraction/Infrastructures/Enums/StateConst.cs
+++ b/src/Infrastructure/BotSharp.Abstraction/Infrastructures/Enums/StateConst.cs
@@ -8,8 +8,12 @@ public class StateConst
public const string NEXT_ACTION_REASON = "next_action_reason";
public const string USER_GOAL_AGENT = "user_goal_agent";
public const string AGENT_REDIRECTION_REASON = "agent_redirection_reason";
+ // lazy or eager
+ public const string ROUTING_MODE = "routing_mode";
+ public const string LAZY_ROUTING_AGENT_ID = "lazy_routing_agent_id";
public const string LANGUAGE = "language";
public const string SUB_CONVERSATION_ID = "sub_conversation_id";
+ public const string ORIGIN_CONVERSATION_ID = "origin_conversation_id";
}
diff --git a/src/Infrastructure/BotSharp.Abstraction/Instructs/IInstructHook.cs b/src/Infrastructure/BotSharp.Abstraction/Instructs/IInstructHook.cs
index 8eaee99b..c9fa1cd7 100644
--- a/src/Infrastructure/BotSharp.Abstraction/Instructs/IInstructHook.cs
+++ b/src/Infrastructure/BotSharp.Abstraction/Instructs/IInstructHook.cs
@@ -7,4 +7,5 @@ public interface IInstructHook
string SelfId { get; }
Task BeforeCompletion(Agent agent, RoleDialogModel message);
Task AfterCompletion(Agent agent, InstructResult result);
+ Task OnResponseGenerated(InstructResponseModel response);
}
diff --git a/src/Infrastructure/BotSharp.Abstraction/Instructs/InstructHookBase.cs b/src/Infrastructure/BotSharp.Abstraction/Instructs/InstructHookBase.cs
index b59e4640..f19cca5c 100644
--- a/src/Infrastructure/BotSharp.Abstraction/Instructs/InstructHookBase.cs
+++ b/src/Infrastructure/BotSharp.Abstraction/Instructs/InstructHookBase.cs
@@ -15,4 +15,9 @@ public class InstructHookBase : IInstructHook
{
return;
}
+
+ public virtual async Task OnResponseGenerated(InstructResponseModel response)
+ {
+ return;
+ }
}
diff --git a/src/Infrastructure/BotSharp.Abstraction/Instructs/Models/InstructResponseModel.cs b/src/Infrastructure/BotSharp.Abstraction/Instructs/Models/InstructResponseModel.cs
new file mode 100644
index 00000000..62752bf4
--- /dev/null
+++ b/src/Infrastructure/BotSharp.Abstraction/Instructs/Models/InstructResponseModel.cs
@@ -0,0 +1,12 @@
+namespace BotSharp.Abstraction.Instructs.Models;
+
+public class InstructResponseModel
+{
+ public string? AgentId { get; set; }
+ public string Provider { get; set; } = default!;
+ public string Model { get; set; } = default!;
+ public string? TemplateName { get; set; }
+ public string UserMessage { get; set; } = default!;
+ public string? SystemInstruction { get; set; }
+ public string CompletionText { get; set; } = default!;
+}
diff --git a/src/Infrastructure/BotSharp.Abstraction/Instructs/Settings/InstructionSettings.cs b/src/Infrastructure/BotSharp.Abstraction/Instructs/Settings/InstructionSettings.cs
new file mode 100644
index 00000000..d1f51348
--- /dev/null
+++ b/src/Infrastructure/BotSharp.Abstraction/Instructs/Settings/InstructionSettings.cs
@@ -0,0 +1,6 @@
+namespace BotSharp.Abstraction.Instructs.Settings;
+
+public class InstructionSettings
+{
+ public bool EnableLog { get; set; }
+}
diff --git a/src/Infrastructure/BotSharp.Abstraction/Knowledges/IKnowledgeService.cs b/src/Infrastructure/BotSharp.Abstraction/Knowledges/IKnowledgeService.cs
index 3fc90816..fb368b0b 100644
--- a/src/Infrastructure/BotSharp.Abstraction/Knowledges/IKnowledgeService.cs
+++ b/src/Infrastructure/BotSharp.Abstraction/Knowledges/IKnowledgeService.cs
@@ -60,6 +60,14 @@ public interface IKnowledgeService
Task GetKnowledgeDocumentBinaryData(string collectionName, Guid fileId);
#endregion
+ #region Snapshot
+ Task> GetVectorCollectionSnapshots(string collectionName);
+ Task CreateVectorCollectionSnapshot(string collectionName);
+ Task DownloadVectorCollectionSnapshot(string collectionName, string snapshotFileName);
+ Task RecoverVectorCollectionFromSnapshot(string collectionName, string snapshotFileName, BinaryData snapshotData);
+ Task DeleteVectorCollectionSnapshot(string collectionName, string snapshotName);
+ #endregion
+
#region Common
Task RefreshVectorKnowledgeConfigs(VectorCollectionConfigsModel configs);
#endregion
diff --git a/src/Infrastructure/BotSharp.Abstraction/Loggers/IContentGeneratingHook.cs b/src/Infrastructure/BotSharp.Abstraction/Loggers/IContentGeneratingHook.cs
index 9d0662db..c4f63450 100644
--- a/src/Infrastructure/BotSharp.Abstraction/Loggers/IContentGeneratingHook.cs
+++ b/src/Infrastructure/BotSharp.Abstraction/Loggers/IContentGeneratingHook.cs
@@ -1,3 +1,5 @@
+using BotSharp.Abstraction.Functions.Models;
+
namespace BotSharp.Abstraction.Loggers;
///
@@ -37,4 +39,13 @@ public interface IContentGeneratingHook
///
///
Task OnRenderingTemplate(Agent agent, string name, string content) => Task.CompletedTask;
+
+ ///
+ /// Realtime session updated
+ ///
+ ///
+ ///
+ ///
+ ///
+ Task OnSessionUpdated(Agent agent, string instruction, FunctionDef[] functions) => Task.CompletedTask;
}
diff --git a/src/Infrastructure/BotSharp.Abstraction/Loggers/Models/InstructionLogModel.cs b/src/Infrastructure/BotSharp.Abstraction/Loggers/Models/InstructionLogModel.cs
new file mode 100644
index 00000000..de843023
--- /dev/null
+++ b/src/Infrastructure/BotSharp.Abstraction/Loggers/Models/InstructionLogModel.cs
@@ -0,0 +1,53 @@
+using System.Text.Json;
+
+namespace BotSharp.Abstraction.Loggers.Models;
+
+public class InstructionLogModel
+{
+ [JsonPropertyName("id")]
+ public string Id { get; set; } = default!;
+
+ [JsonPropertyName("agent_id")]
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ public string? AgentId { get; set; }
+
+ [JsonPropertyName("agent_name")]
+ [JsonIgnore]
+ public string? AgentName { get; set; }
+
+ [JsonPropertyName("provider")]
+ public string Provider { get; set; } = default!;
+
+ [JsonPropertyName("model")]
+ public string Model { get; set; } = default!;
+
+ [JsonPropertyName("template_name")]
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ public string? TemplateName { get; set; }
+
+ [JsonPropertyName("user_message")]
+ public string UserMessage { get; set; } = string.Empty;
+
+ [JsonPropertyName("system_instruction")]
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ public string? SystemInstruction { get; set; }
+
+ [JsonPropertyName("completion_text")]
+ public string CompletionText { get; set; } = string.Empty;
+
+ [JsonPropertyName("user_id")]
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ public string? UserId { get; set; }
+
+ [JsonIgnore]
+ public string? UserName { get; set; }
+
+ [JsonIgnore]
+ public Dictionary States { get; set; } = [];
+
+ [JsonPropertyName("states")]
+ public Dictionary InnerStates { get; set; } = [];
+
+ [JsonPropertyName("created_time")]
+ public DateTime CreatedTime { get; set; } = DateTime.UtcNow;
+}
diff --git a/src/Infrastructure/BotSharp.Abstraction/Loggers/Services/ILoggerService.cs b/src/Infrastructure/BotSharp.Abstraction/Loggers/Services/ILoggerService.cs
new file mode 100644
index 00000000..564fcf37
--- /dev/null
+++ b/src/Infrastructure/BotSharp.Abstraction/Loggers/Services/ILoggerService.cs
@@ -0,0 +1,17 @@
+using BotSharp.Abstraction.Loggers.Models;
+using BotSharp.Abstraction.Repositories.Filters;
+
+namespace BotSharp.Abstraction.Loggers.Services;
+
+public interface ILoggerService
+{
+ #region Conversation
+ Task> GetConversationContentLogs(string conversationId, ConversationLogFilter filter);
+ Task> GetConversationStateLogs(string conversationId, ConversationLogFilter filter);
+ #endregion
+
+ #region Instruction
+ Task> GetInstructionLogs(InstructLogFilter filter);
+ Task> GetInstructionLogSearchKeys(InstructLogKeysFilter filter);
+ #endregion
+}
diff --git a/src/Infrastructure/BotSharp.Abstraction/MLTasks/IAudioCompletion.cs b/src/Infrastructure/BotSharp.Abstraction/MLTasks/IAudioCompletion.cs
index 54ed2d7d..85fc84f2 100644
--- a/src/Infrastructure/BotSharp.Abstraction/MLTasks/IAudioCompletion.cs
+++ b/src/Infrastructure/BotSharp.Abstraction/MLTasks/IAudioCompletion.cs
@@ -6,6 +6,8 @@ public interface IAudioCompletion
{
string Provider { get; }
+ string Model { get; }
+
Task GenerateTextFromAudioAsync(Stream audio, string audioFileName, string? text = null);
Task GenerateAudioFromTextAsync(string text);
diff --git a/src/Infrastructure/BotSharp.Abstraction/MLTasks/IChatCompletion.cs b/src/Infrastructure/BotSharp.Abstraction/MLTasks/IChatCompletion.cs
index 306e72e3..7cf52fe4 100644
--- a/src/Infrastructure/BotSharp.Abstraction/MLTasks/IChatCompletion.cs
+++ b/src/Infrastructure/BotSharp.Abstraction/MLTasks/IChatCompletion.cs
@@ -7,6 +7,8 @@ public interface IChatCompletion
///
string Provider { get; }
+ string Model { get; }
+
///
/// Set model name, one provider can consume different model or version(s)
///
diff --git a/src/Infrastructure/BotSharp.Abstraction/MLTasks/IImageCompletion.cs b/src/Infrastructure/BotSharp.Abstraction/MLTasks/IImageCompletion.cs
index 323fe643..2b74a337 100644
--- a/src/Infrastructure/BotSharp.Abstraction/MLTasks/IImageCompletion.cs
+++ b/src/Infrastructure/BotSharp.Abstraction/MLTasks/IImageCompletion.cs
@@ -9,6 +9,8 @@ public interface IImageCompletion
///
string Provider { get; }
+ string Model { get; }
+
///
/// Set model name, one provider can consume different model or version(s)
///
diff --git a/src/Infrastructure/BotSharp.Abstraction/MLTasks/IRealTimeCompletion.cs b/src/Infrastructure/BotSharp.Abstraction/MLTasks/IRealTimeCompletion.cs
index 8e1d11d5..68a96dfa 100644
--- a/src/Infrastructure/BotSharp.Abstraction/MLTasks/IRealTimeCompletion.cs
+++ b/src/Infrastructure/BotSharp.Abstraction/MLTasks/IRealTimeCompletion.cs
@@ -6,12 +6,11 @@ public interface IRealTimeCompletion
{
string Provider { get; }
string Model { get; }
-
void SetModelName(string model);
Task Connect(RealtimeHubConnection conn,
Action onModelReady,
- Action onModelAudioDeltaReceived,
+ Action onModelAudioDeltaReceived,
Action onModelAudioResponseDone,
Action onAudioTranscriptDone,
Action> onModelResponseDone,
@@ -24,9 +23,11 @@ public interface IRealTimeCompletion
Task Disconnect();
Task CreateSession(Agent agent, List conversations);
- Task UpdateInitialSession(RealtimeHubConnection conn);
+ Task UpdateSession(RealtimeHubConnection conn, bool interruptResponse = true);
Task InsertConversationItem(RoleDialogModel message);
+ Task RemoveConversationItem(string itemId);
Task TriggerModelInference(string? instructions = null);
+ Task CancelModelResponse();
Task> OnResponsedDone(RealtimeHubConnection conn, string response);
Task OnConversationItemCreated(RealtimeHubConnection conn, string response);
}
diff --git a/src/Infrastructure/BotSharp.Abstraction/MLTasks/ITextCompletion.cs b/src/Infrastructure/BotSharp.Abstraction/MLTasks/ITextCompletion.cs
index 63a15940..8fc549f7 100644
--- a/src/Infrastructure/BotSharp.Abstraction/MLTasks/ITextCompletion.cs
+++ b/src/Infrastructure/BotSharp.Abstraction/MLTasks/ITextCompletion.cs
@@ -6,6 +6,7 @@ public interface ITextCompletion
/// The LLM provider like Microsoft Azure, OpenAI, ClaudAI
///
string Provider { get; }
+ string Model { get; }
///
/// Set model name, one provider can consume different model or version(s)
diff --git a/src/Infrastructure/BotSharp.Abstraction/MLTasks/ITextEmbedding.cs b/src/Infrastructure/BotSharp.Abstraction/MLTasks/ITextEmbedding.cs
index 79b3aff8..a96dfec9 100644
--- a/src/Infrastructure/BotSharp.Abstraction/MLTasks/ITextEmbedding.cs
+++ b/src/Infrastructure/BotSharp.Abstraction/MLTasks/ITextEmbedding.cs
@@ -6,9 +6,14 @@ public interface ITextEmbedding
/// The Embedding provider like Microsoft Azure, OpenAI, ClaudAI
///
string Provider { get; }
+ string Model { get; }
+
+ void SetModelName(string model);
+
+
Task GetVectorAsync(string text);
Task> GetVectorsAsync(List texts);
- void SetModelName(string model);
+
void SetDimension(int dimension);
int GetDimension();
}
diff --git a/src/Infrastructure/BotSharp.Abstraction/Models/KeyValue.cs b/src/Infrastructure/BotSharp.Abstraction/Models/KeyValue.cs
index 81286489..3cb9c73f 100644
--- a/src/Infrastructure/BotSharp.Abstraction/Models/KeyValue.cs
+++ b/src/Infrastructure/BotSharp.Abstraction/Models/KeyValue.cs
@@ -3,10 +3,24 @@ namespace BotSharp.Abstraction.Models;
public class KeyValue
{
[JsonPropertyName("key")]
- public string Key { get; set; }
+ public string Key { get; set; } = string.Empty;
[JsonPropertyName("value")]
- public string Value { get; set; }
+ public string? Value { get; set; }
+
+ public override string ToString()
+ {
+ return $"Key: {Key}, Value: {Value}";
+ }
+}
+
+public class KeyValue
+{
+ [JsonPropertyName("key")]
+ public string Key { get; set; } = string.Empty;
+
+ [JsonPropertyName("value")]
+ public T? Value { get; set; }
public override string ToString()
{
diff --git a/src/Infrastructure/BotSharp.Abstraction/Options/BotSharpOptions.cs b/src/Infrastructure/BotSharp.Abstraction/Options/BotSharpOptions.cs
index 90168872..b8609422 100644
--- a/src/Infrastructure/BotSharp.Abstraction/Options/BotSharpOptions.cs
+++ b/src/Infrastructure/BotSharp.Abstraction/Options/BotSharpOptions.cs
@@ -4,7 +4,7 @@ namespace BotSharp.Abstraction.Options;
public class BotSharpOptions
{
- private readonly static JsonSerializerOptions defaultJsonOptions = new JsonSerializerOptions()
+ public readonly static JsonSerializerOptions defaultJsonOptions = new JsonSerializerOptions()
{
PropertyNameCaseInsensitive = true,
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
diff --git a/src/Infrastructure/BotSharp.Abstraction/Plugins/Models/PluginMenuDef.cs b/src/Infrastructure/BotSharp.Abstraction/Plugins/Models/PluginMenuDef.cs
index c387d1ca..f347fb84 100644
--- a/src/Infrastructure/BotSharp.Abstraction/Plugins/Models/PluginMenuDef.cs
+++ b/src/Infrastructure/BotSharp.Abstraction/Plugins/Models/PluginMenuDef.cs
@@ -13,6 +13,9 @@ public class PluginMenuDef(string label, string? link = null, string? icon = nul
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public string? Link { get; set; } = link;
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ public EmbeddingData? EmbeddingInfo { get; set; }
+
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public bool? IsHeader { get; set; }
@@ -30,3 +33,35 @@ public class PluginMenuDef(string label, string? link = null, string? icon = nul
return $"{Label} {Link} {Weight}";
}
}
+
+public class EmbeddingData
+{
+ ///
+ /// Embedding source, e.g., tableau
+ ///
+ public string Source { get; set; } = default!;
+
+ ///
+ /// Embedding url
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ public string? Url { get; set; }
+
+ ///
+ /// Html tag
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ public string? HtmlTag { get; set; }
+
+ ///
+ /// Javascript script src
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ public string? ScriptSrc { get; set; }
+
+ ///
+ /// Javascript script type, e.g., module
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ public string? ScriptType { get; set; }
+}
diff --git a/src/Infrastructure/BotSharp.Abstraction/Realtime/IRealtimeHook.cs b/src/Infrastructure/BotSharp.Abstraction/Realtime/IRealtimeHook.cs
new file mode 100644
index 00000000..2ad8f1df
--- /dev/null
+++ b/src/Infrastructure/BotSharp.Abstraction/Realtime/IRealtimeHook.cs
@@ -0,0 +1,6 @@
+namespace BotSharp.Abstraction.Realtime;
+
+public interface IRealtimeHook
+{
+ string[] OnModelTranscriptPrompt(Agent agent);
+}
diff --git a/src/Infrastructure/BotSharp.Abstraction/Realtime/IRealtimeHub.cs b/src/Infrastructure/BotSharp.Abstraction/Realtime/IRealtimeHub.cs
index 67d0f18c..23ecb654 100644
--- a/src/Infrastructure/BotSharp.Abstraction/Realtime/IRealtimeHub.cs
+++ b/src/Infrastructure/BotSharp.Abstraction/Realtime/IRealtimeHub.cs
@@ -1,3 +1,4 @@
+using BotSharp.Abstraction.MLTasks;
using BotSharp.Abstraction.Realtime.Models;
using System.Net.WebSockets;
@@ -8,5 +9,11 @@ namespace BotSharp.Abstraction.Realtime;
///
public interface IRealtimeHub
{
- Task Listen(WebSocket userWebSocket, Func onUserMessageReceived);
+ RealtimeHubConnection HubConn { get; }
+ RealtimeHubConnection SetHubConnection(string conversationId);
+
+ IRealTimeCompletion Completer { get; }
+ IRealTimeCompletion SetCompleter(string provider);
+
+ Task Listen(WebSocket userWebSocket, Action onUserMessageReceived);
}
diff --git a/src/Infrastructure/BotSharp.Abstraction/Realtime/Models/ModelTurnDetection.cs b/src/Infrastructure/BotSharp.Abstraction/Realtime/Models/ModelTurnDetection.cs
new file mode 100644
index 00000000..a65a8985
--- /dev/null
+++ b/src/Infrastructure/BotSharp.Abstraction/Realtime/Models/ModelTurnDetection.cs
@@ -0,0 +1,10 @@
+namespace BotSharp.Abstraction.Realtime.Models;
+
+public class ModelTurnDetection
+{
+ public int PrefixPadding { get; set; } = 300;
+
+ public int SilenceDuration { get; set; } = 800;
+
+ public float Threshold { get; set; } = 0.8f;
+}
diff --git a/src/Infrastructure/BotSharp.Abstraction/Realtime/Models/RealtimeHubConnection.cs b/src/Infrastructure/BotSharp.Abstraction/Realtime/Models/RealtimeHubConnection.cs
index 60fec1dc..9fa3ee3b 100644
--- a/src/Infrastructure/BotSharp.Abstraction/Realtime/Models/RealtimeHubConnection.cs
+++ b/src/Infrastructure/BotSharp.Abstraction/Realtime/Models/RealtimeHubConnection.cs
@@ -1,14 +1,34 @@
+using System.Collections.Concurrent;
+
namespace BotSharp.Abstraction.Realtime.Models;
public class RealtimeHubConnection
{
public string Event { get; set; } = null!;
public string StreamId { get; set; } = null!;
- public string EntryAgentId { get; set; } = null!;
+ public string? LastAssistantItemId { get; set; } = null!;
+ public long LatestMediaTimestamp { get; set; }
+ public long? ResponseStartTimestamp { get; set; }
+ public string KeypadInputBuffer { get; set; } = string.Empty;
+ public ConcurrentQueue MarkQueue { get; set; } = new();
+ public string CurrentAgentId { get; set; } = null!;
public string ConversationId { get; set; } = null!;
public string Data { get; set; } = string.Empty;
public string Model { get; set; } = null!;
public Func OnModelMessageReceived { get; set; } = null!;
public Func