diff --git a/src/Infrastructure/BotSharp.Abstraction/Agents/Enums/BuiltInAgentId.cs b/src/Infrastructure/BotSharp.Abstraction/Agents/Enums/BuiltInAgentId.cs
index 7f22c8f29..f2f64b6bf 100644
--- a/src/Infrastructure/BotSharp.Abstraction/Agents/Enums/BuiltInAgentId.cs
+++ b/src/Infrastructure/BotSharp.Abstraction/Agents/Enums/BuiltInAgentId.cs
@@ -56,9 +56,4 @@ public class BuiltInAgentId
/// Translates user-defined natural language rules into programmatic code
///
public const string RuleEncoder = "6acfb93c-3412-402e-9ba5-c5d3cd8f0161";
-
- ///
- /// Schedule job
- ///
- public const string Crontab = "c2o139da-a62a-4355-8605-fdf0ffaca58e";
}
diff --git a/src/Infrastructure/BotSharp.Abstraction/Conversations/Models/RoleDialogModel.cs b/src/Infrastructure/BotSharp.Abstraction/Conversations/Models/RoleDialogModel.cs
index 679527a35..5a67216d4 100644
--- a/src/Infrastructure/BotSharp.Abstraction/Conversations/Models/RoleDialogModel.cs
+++ b/src/Infrastructure/BotSharp.Abstraction/Conversations/Models/RoleDialogModel.cs
@@ -2,9 +2,11 @@
using BotSharp.Abstraction.Functions.Models;
using BotSharp.Abstraction.Messaging;
using BotSharp.Abstraction.Messaging.Models.RichContent;
+using System.Diagnostics;
namespace BotSharp.Abstraction.Conversations.Models;
+[DebuggerStepThrough]
public class RoleDialogModel : ITrackableMessage
{
///
diff --git a/src/Infrastructure/BotSharp.Core.Crontab/BotSharp.Core.Crontab.csproj b/src/Infrastructure/BotSharp.Core.Crontab/BotSharp.Core.Crontab.csproj
index f1c70ad73..0740b6fa3 100644
--- a/src/Infrastructure/BotSharp.Core.Crontab/BotSharp.Core.Crontab.csproj
+++ b/src/Infrastructure/BotSharp.Core.Crontab/BotSharp.Core.Crontab.csproj
@@ -7,11 +7,15 @@
-
+
+
-
+
+ PreserveNewest
+
+
PreserveNewest
diff --git a/src/Infrastructure/BotSharp.Core.Crontab/CrontabPlugin.cs b/src/Infrastructure/BotSharp.Core.Crontab/CrontabPlugin.cs
index a449cbbb2..26f5cfad6 100644
--- a/src/Infrastructure/BotSharp.Core.Crontab/CrontabPlugin.cs
+++ b/src/Infrastructure/BotSharp.Core.Crontab/CrontabPlugin.cs
@@ -14,6 +14,8 @@ You may obtain a copy of the License at
limitations under the License.
******************************************************************************/
+using BotSharp.Core.Crontab.Hooks;
+
namespace BotSharp.Core.Crontab;
///
@@ -27,13 +29,9 @@ public class CrontabPlugin : IBotSharpPlugin
public string Description => "Crontab plugin is a time-based job scheduler in agent framework. The cron system is used to trigger AI Agent to do specific task periodically.";
public string IconUrl => "https://icon-library.com/images/stop-watch-icon/stop-watch-icon-10.jpg";
- public string[] AgentIds =
- [
- BuiltInAgentId.Crontab
- ];
-
public void RegisterDI(IServiceCollection services, IConfiguration config)
{
+ services.AddScoped();
services.AddScoped();
services.AddHostedService();
}
diff --git a/src/Infrastructure/BotSharp.Core.Crontab/Enum/UtilityName.cs b/src/Infrastructure/BotSharp.Core.Crontab/Enum/UtilityName.cs
new file mode 100644
index 000000000..eba15bd99
--- /dev/null
+++ b/src/Infrastructure/BotSharp.Core.Crontab/Enum/UtilityName.cs
@@ -0,0 +1,6 @@
+namespace BotSharp.Core.Crontab.Enum;
+
+public class UtilityName
+{
+ public const string ScheduleTask = "crontab.schedule-task";
+}
diff --git a/src/Infrastructure/BotSharp.Core.Crontab/Functions/ScheduleTaskFn.cs b/src/Infrastructure/BotSharp.Core.Crontab/Functions/ScheduleTaskFn.cs
new file mode 100644
index 000000000..70d3b4106
--- /dev/null
+++ b/src/Infrastructure/BotSharp.Core.Crontab/Functions/ScheduleTaskFn.cs
@@ -0,0 +1,37 @@
+using BotSharp.Abstraction.Routing;
+using BotSharp.Abstraction.Users;
+using BotSharp.Core.Crontab.Hooks;
+
+namespace BotSharp.Core.Crontab.Functions;
+
+public class ScheduleTaskFn : IFunctionCallback
+{
+ public string Name => $"{CrontabUtilityHook.PREFIX}schedule_task";
+ private readonly IServiceProvider _services;
+
+ public ScheduleTaskFn(IServiceProvider services)
+ {
+ _services = services;
+ }
+
+ public async Task Execute(RoleDialogModel message)
+ {
+ var args = JsonSerializer.Deserialize(message.FunctionArgs);
+
+ var routing = _services.GetRequiredService();
+ var user = _services.GetRequiredService();
+ var crontabItem = new CrontabItem
+ {
+ Topic = args.Topic,
+ Description = args.Description,
+ Cron = args.Cron,
+ Script = args.Script,
+ Language = args.Language,
+ UserId = user.Id,
+ AgentId = routing.EntryAgentId,
+ ConversationId = routing.ConversationId
+ };
+
+ return true;
+ }
+}
diff --git a/src/Infrastructure/BotSharp.Core.Crontab/Hooks/CrontabUtilityHook.cs b/src/Infrastructure/BotSharp.Core.Crontab/Hooks/CrontabUtilityHook.cs
new file mode 100644
index 000000000..ed150861a
--- /dev/null
+++ b/src/Infrastructure/BotSharp.Core.Crontab/Hooks/CrontabUtilityHook.cs
@@ -0,0 +1,25 @@
+using BotSharp.Abstraction.Agents.Models;
+using BotSharp.Core.Crontab.Enum;
+
+namespace BotSharp.Core.Crontab.Hooks;
+
+public class CrontabUtilityHook : IAgentUtilityHook
+{
+ public const string PREFIX = "util-crontab-";
+ private const string SCHEDULE_TASK_FN = $"{PREFIX}schedule_task";
+
+ public void AddUtilities(List utilities)
+ {
+ var items = new List
+ {
+ new AgentUtility
+ {
+ Name = UtilityName.ScheduleTask,
+ Functions = [new(SCHEDULE_TASK_FN)],
+ Templates = [new($"{SCHEDULE_TASK_FN}.fn")]
+ }
+ };
+
+ utilities.AddRange(items);
+ }
+}
diff --git a/src/Infrastructure/BotSharp.Core.Crontab/Models/CrontabItem.cs b/src/Infrastructure/BotSharp.Core.Crontab/Models/CrontabItem.cs
index 50cafd026..c3fab2e8c 100644
--- a/src/Infrastructure/BotSharp.Core.Crontab/Models/CrontabItem.cs
+++ b/src/Infrastructure/BotSharp.Core.Crontab/Models/CrontabItem.cs
@@ -1,14 +1,14 @@
namespace BotSharp.Core.Crontab.Models;
-public class CrontabItem
+public class CrontabItem : ScheduleTaskArgs
{
public string UserId { get; set; } = null!;
public string AgentId { get; set; } = null!;
- public string Topic { get; set; } = null!;
- public string Cron { get; set; } = null!;
+ public string ConversationId { get; set; } = null!;
+ public string ExecutionResult { get; set; } = null!;
public override string ToString()
{
- return $"AgentId: {AgentId}, UserId: {UserId}, Topic: {Topic}";
+ return $"{Topic}: {Description} [AgentId: {AgentId}, UserId: {UserId}]";
}
}
diff --git a/src/Infrastructure/BotSharp.Core.Crontab/Models/ScheduleTaskArgs.cs b/src/Infrastructure/BotSharp.Core.Crontab/Models/ScheduleTaskArgs.cs
new file mode 100644
index 000000000..af1bb23f0
--- /dev/null
+++ b/src/Infrastructure/BotSharp.Core.Crontab/Models/ScheduleTaskArgs.cs
@@ -0,0 +1,21 @@
+using System.Text.Json.Serialization;
+
+namespace BotSharp.Core.Crontab.Models;
+
+public class ScheduleTaskArgs
+{
+ [JsonPropertyName("cron_expression")]
+ public string Cron { get; set; } = null!;
+
+ [JsonPropertyName("topic")]
+ public string Topic { get; set; } = null!;
+
+ [JsonPropertyName("description")]
+ public string Description { get; set; } = null!;
+
+ [JsonPropertyName("script")]
+ public string Script { get; set; } = null!;
+
+ [JsonPropertyName("language")]
+ public string Language { get; set; } = null!;
+}
diff --git a/src/Infrastructure/BotSharp.Core.Crontab/Services/CrontabService.cs b/src/Infrastructure/BotSharp.Core.Crontab/Services/CrontabService.cs
index a8b5f6dd6..d09f9260d 100644
--- a/src/Infrastructure/BotSharp.Core.Crontab/Services/CrontabService.cs
+++ b/src/Infrastructure/BotSharp.Core.Crontab/Services/CrontabService.cs
@@ -15,6 +15,8 @@ limitations under the License.
******************************************************************************/
using BotSharp.Abstraction.Agents.Enums;
+using BotSharp.Abstraction.Conversations;
+using BotSharp.Abstraction.Routing;
using BotSharp.Core.Crontab.Models;
using BotSharp.Core.Infrastructures;
@@ -56,22 +58,38 @@ public CrontabService(IServiceProvider services, ILogger logger)
public async Task> GetCrontable()
{
+ var convService = _services.GetRequiredService();
+ var conv = await convService.GetConversation("73a9ee27-d597-4739-958f-3bd79760ac8e");
+ if (conv == null || !conv.States.ContainsKey("cron_expression"))
+ {
+ return [];
+ }
+
return
[
new CrontabItem
{
- Cron = "*/30 * * * * *",
- AgentId = BuiltInAgentId.AIAssistant,
+ Topic = conv.States["topic"],
+ Cron = conv.States["cron_expression"],
+ Description = conv.States["description"],
+ Script = conv.States["script"],
+ Language = conv.States["language"]
}
];
}
public async Task ScheduledTimeArrived(CrontabItem item)
{
- _logger.LogInformation("ScheduledTimeArrived");
- await HookEmitter.Emit(_services, async hook =>
+ _logger.LogDebug($"ScheduledTimeArrived {item}");
+
+ var hooks = _services.GetServices();
+ foreach(var hook in hooks)
+ {
+ await hook.OnCronTriggered(item);
+ }
+ /*await HookEmitter.Emit(_services, async hook =>
await hook.OnCronTriggered(item)
- );
+ );*/
await Task.Delay(1000 * 10);
}
}
diff --git a/src/Infrastructure/BotSharp.Core.Crontab/Services/CrontabWatcher.cs b/src/Infrastructure/BotSharp.Core.Crontab/Services/CrontabWatcher.cs
index 0abd050f8..f29bd0690 100644
--- a/src/Infrastructure/BotSharp.Core.Crontab/Services/CrontabWatcher.cs
+++ b/src/Infrastructure/BotSharp.Core.Crontab/Services/CrontabWatcher.cs
@@ -62,7 +62,7 @@ private async Task RunCronChecker(IServiceProvider services)
if (matches)
{
- _logger.LogInformation($"The current time matches the cron expression {item}");
+ _logger.LogDebug($"The current time matches the cron expression {item}");
cron.ScheduledTimeArrived(item);
}
}
diff --git a/src/Infrastructure/BotSharp.Core.Crontab/Using.cs b/src/Infrastructure/BotSharp.Core.Crontab/Using.cs
index 0da87fb26..425632384 100644
--- a/src/Infrastructure/BotSharp.Core.Crontab/Using.cs
+++ b/src/Infrastructure/BotSharp.Core.Crontab/Using.cs
@@ -1,7 +1,13 @@
+global using System.Text.Json;
+
global using Microsoft.Extensions.Configuration;
global using Microsoft.Extensions.DependencyInjection;
global using BotSharp.Abstraction.Agents.Enums;
+global using BotSharp.Abstraction.Agents;
global using BotSharp.Abstraction.Plugins;
+global using BotSharp.Abstraction.Conversations.Models;
+global using BotSharp.Abstraction.Functions;
global using BotSharp.Core.Crontab.Services;
global using BotSharp.Core.Crontab.Abstraction;
+global using BotSharp.Core.Crontab.Models;
diff --git a/src/Infrastructure/BotSharp.Core.Crontab/data/agents/6745151e-6d46-4a02-8de4-1c4f21c7da95/functions/util-crontab-schedule_task.json b/src/Infrastructure/BotSharp.Core.Crontab/data/agents/6745151e-6d46-4a02-8de4-1c4f21c7da95/functions/util-crontab-schedule_task.json
new file mode 100644
index 000000000..4f866ce19
--- /dev/null
+++ b/src/Infrastructure/BotSharp.Core.Crontab/data/agents/6745151e-6d46-4a02-8de4-1c4f21c7da95/functions/util-crontab-schedule_task.json
@@ -0,0 +1,31 @@
+{
+ "name": "util-crontab-schedule_task",
+ "description": "Set up a scheduled task",
+ "parameters": {
+ "type": "object",
+ "properties": {
+ "cron_expression": {
+ "type": "string",
+ "description": "cron expression include seconds"
+ },
+ "topic": {
+ "type": "string",
+ "description": "task topic in 1-3 keywords related to business entities"
+ },
+ "description": {
+ "type": "string",
+ "description": "task description without cron infromation, should include all key business entities"
+ },
+ "script": {
+ "type": "string",
+ "description": "task related script, commands or provided function with parameters"
+ },
+ "language": {
+ "type": "string",
+ "enum": ["sql", "function"],
+ "description": "script programming language"
+ }
+ },
+ "required": [ "cron_expression", "topic", "description", "script", "language" ]
+ }
+}
\ No newline at end of file
diff --git a/src/Infrastructure/BotSharp.Core.Crontab/data/agents/6745151e-6d46-4a02-8de4-1c4f21c7da95/templates/util-crontab-schedule_task.fn.liquid b/src/Infrastructure/BotSharp.Core.Crontab/data/agents/6745151e-6d46-4a02-8de4-1c4f21c7da95/templates/util-crontab-schedule_task.fn.liquid
new file mode 100644
index 000000000..0c1325464
--- /dev/null
+++ b/src/Infrastructure/BotSharp.Core.Crontab/data/agents/6745151e-6d46-4a02-8de4-1c4f21c7da95/templates/util-crontab-schedule_task.fn.liquid
@@ -0,0 +1 @@
+Call schedule_task if user needs to set up a scheduled task with appropriate programming script and language type.
\ No newline at end of file
diff --git a/src/Infrastructure/BotSharp.Core.Crontab/data/agents/c2o139da-a62a-4355-8605-fdf0ffaca58e/agent.json b/src/Infrastructure/BotSharp.Core.Crontab/data/agents/c2o139da-a62a-4355-8605-fdf0ffaca58e/agent.json
deleted file mode 100644
index b17e1e6db..000000000
--- a/src/Infrastructure/BotSharp.Core.Crontab/data/agents/c2o139da-a62a-4355-8605-fdf0ffaca58e/agent.json
+++ /dev/null
@@ -1,24 +0,0 @@
-{
- "id": "c2o139da-a62a-4355-8605-fdf0ffaca58e",
- "name": "Crontab",
- "description": "Convert the user-specified schedule into a Cron expression, accurate to the second level.",
- "iconUrl": "https://icon-library.com/images/stop-watch-icon/stop-watch-icon-10.jpg",
- "type": "task",
- "createdDateTime": "2024-12-03T00:00:00Z",
- "updatedDateTime": "2024-12-03T00:00:00Z",
- "disabled": false,
- "isPublic": true,
- "profiles": [ "cron" ],
- "llmConfig": {
- "provider": "openai",
- "model": "gpt-4o-mini"
- },
- "routingRules": [
- {
- "field": "cron_expression",
- "required": true,
- "field_type": "string",
- "description": "A Cron expression, accurate to the second level."
- }
- ]
-}
\ No newline at end of file
diff --git a/src/Infrastructure/BotSharp.Core/Infrastructures/HookEmitter.cs b/src/Infrastructure/BotSharp.Core/Infrastructures/HookEmitter.cs
index 943386e1a..454ed8409 100644
--- a/src/Infrastructure/BotSharp.Core/Infrastructures/HookEmitter.cs
+++ b/src/Infrastructure/BotSharp.Core/Infrastructures/HookEmitter.cs
@@ -15,7 +15,7 @@ public static HookEmittedResult Emit(IServiceProvider services, Action act
{
try
{
- logger.LogInformation($"Emit hook action on {action.Method.Name}({hook.GetType().Name})");
+ logger.LogDebug($"Emit hook action on {action.Method.Name}({hook.GetType().Name})");
action(hook);
if (option.OnlyOnce)
@@ -43,7 +43,7 @@ public static async Task Emit(IServiceProvider services, F
{
try
{
- logger.LogInformation($"Emit hook action on {action.Method.Name}({hook.GetType().Name})");
+ logger.LogDebug($"Emit hook action on {action.Method.Name}({hook.GetType().Name})");
await action(hook);
if (option.OnlyOnce)
diff --git a/src/Infrastructure/BotSharp.Core/data/agents/01fcc3e5-9af7-49e6-ad7a-a760bd12dc4a/agent.json b/src/Infrastructure/BotSharp.Core/data/agents/01fcc3e5-9af7-49e6-ad7a-a760bd12dc4a/agent.json
index 992e04f32..0a82ae0a2 100644
--- a/src/Infrastructure/BotSharp.Core/data/agents/01fcc3e5-9af7-49e6-ad7a-a760bd12dc4a/agent.json
+++ b/src/Infrastructure/BotSharp.Core/data/agents/01fcc3e5-9af7-49e6-ad7a-a760bd12dc4a/agent.json
@@ -8,7 +8,7 @@
"iconUrl": "https://cdn.iconscout.com/icon/premium/png-256-thumb/route-1613278-1368497.png",
"disabled": false,
"isPublic": true,
- "profiles": [ "tool" ],
+ "profiles": [ "planning", "fallback", "human" ],
"routingRules": [
{
"type": "reasoner",
diff --git a/src/Plugins/BotSharp.Plugin.ChatHub/BotSharp.Plugin.ChatHub.csproj b/src/Plugins/BotSharp.Plugin.ChatHub/BotSharp.Plugin.ChatHub.csproj
index 4f076a9e3..4268cf383 100644
--- a/src/Plugins/BotSharp.Plugin.ChatHub/BotSharp.Plugin.ChatHub.csproj
+++ b/src/Plugins/BotSharp.Plugin.ChatHub/BotSharp.Plugin.ChatHub.csproj
@@ -19,6 +19,7 @@
+
diff --git a/src/Plugins/BotSharp.Plugin.ChatHub/ChatHubPlugin.cs b/src/Plugins/BotSharp.Plugin.ChatHub/ChatHubPlugin.cs
index 5bd9a8ced..1eaad66de 100644
--- a/src/Plugins/BotSharp.Plugin.ChatHub/ChatHubPlugin.cs
+++ b/src/Plugins/BotSharp.Plugin.ChatHub/ChatHubPlugin.cs
@@ -1,5 +1,6 @@
using BotSharp.Abstraction.Loggers;
using BotSharp.Abstraction.Routing;
+using BotSharp.Core.Crontab.Abstraction;
using BotSharp.Plugin.ChatHub.Hooks;
using Microsoft.Extensions.Configuration;
@@ -23,5 +24,6 @@ public void RegisterDI(IServiceCollection services, IConfiguration config)
services.AddScoped();
services.AddScoped();
services.AddScoped();
+ services.AddScoped();
}
}
diff --git a/src/Plugins/BotSharp.Plugin.ChatHub/Hooks/ChatHubCrontabHook.cs b/src/Plugins/BotSharp.Plugin.ChatHub/Hooks/ChatHubCrontabHook.cs
new file mode 100644
index 000000000..4b475e735
--- /dev/null
+++ b/src/Plugins/BotSharp.Plugin.ChatHub/Hooks/ChatHubCrontabHook.cs
@@ -0,0 +1,46 @@
+using BotSharp.Core.Crontab.Abstraction;
+using BotSharp.Core.Crontab.Models;
+using Microsoft.AspNetCore.SignalR;
+
+namespace BotSharp.Plugin.ChatHub.Hooks;
+
+public class ChatHubCrontabHook : ICrontabHook
+{
+ private readonly IServiceProvider _services;
+ private readonly IHubContext _chatHub;
+ private readonly IUserIdentity _user;
+ private readonly IConversationStorage _storage;
+ private readonly BotSharpOptions _options;
+
+ public ChatHubCrontabHook(IServiceProvider services,
+ IHubContext chatHub,
+ IUserIdentity user,
+ IConversationStorage storage,
+ BotSharpOptions options)
+ {
+ _services = services;
+ _chatHub = chatHub;
+ _user = user;
+ _storage = storage;
+ _options = options;
+ }
+
+ public async Task OnCronTriggered(CrontabItem item)
+ {
+ var json = JsonSerializer.Serialize(new ChatResponseModel()
+ {
+ ConversationId = item.ConversationId,
+ MessageId = Guid.NewGuid().ToString(),
+ Text = item.ExecutionResult,
+ Function = "",
+ Sender = new UserViewModel()
+ {
+ FirstName = "Crontab",
+ LastName = "AI",
+ Role = AgentRole.Assistant
+ }
+ }, _options.JsonSerializerOptions);
+
+ await _chatHub.Clients.User(item.UserId).SendAsync("OnNotificationGenerated", json);
+ }
+}
diff --git a/src/Plugins/BotSharp.Plugin.Planner/data/agents/282a7128-69a1-44b0-878c-a9159b88f3b9/agent.json b/src/Plugins/BotSharp.Plugin.Planner/data/agents/282a7128-69a1-44b0-878c-a9159b88f3b9/agent.json
index 91ee618c0..1f91bacad 100644
--- a/src/Plugins/BotSharp.Plugin.Planner/data/agents/282a7128-69a1-44b0-878c-a9159b88f3b9/agent.json
+++ b/src/Plugins/BotSharp.Plugin.Planner/data/agents/282a7128-69a1-44b0-878c-a9159b88f3b9/agent.json
@@ -1,7 +1,7 @@
{
"id": "282a7128-69a1-44b0-878c-a9159b88f3b9",
"name": "Planner",
- "description": "Plan feasible implementation steps for complex user task request",
+ "description": "Plan feasible implementation steps for complex user task request, including generating sql query",
"type": "task",
"createdDateTime": "2023-08-27T10:39:00Z",
"updatedDateTime": "2023-08-27T14:39:00Z",
diff --git a/src/Plugins/BotSharp.Plugin.Planner/data/agents/282a7128-69a1-44b0-878c-a9159b88f3b9/instructions/instruction.liquid b/src/Plugins/BotSharp.Plugin.Planner/data/agents/282a7128-69a1-44b0-878c-a9159b88f3b9/instructions/instruction.liquid
index 89bcd49bb..00da3cd67 100644
--- a/src/Plugins/BotSharp.Plugin.Planner/data/agents/282a7128-69a1-44b0-878c-a9159b88f3b9/instructions/instruction.liquid
+++ b/src/Plugins/BotSharp.Plugin.Planner/data/agents/282a7128-69a1-44b0-878c-a9159b88f3b9/instructions/instruction.liquid
@@ -15,6 +15,7 @@ Don't run the planning process repeatedly if you have already got the result of
Function verify_dictionary_term CAN'T generate INSERT SQL Statement.
The table name must come from the relevant knowledge. has_found_relevant_knowledge must be true.
Do not introduce your actions or intentions in any way.
+Only extract the Data related request, ignore the other request, such as schedule job, make phone call etc.
{% if global_knowledges != empty -%}
=====
diff --git a/src/Plugins/BotSharp.Plugin.SqlDriver/BotSharp.Plugin.SqlDriver.csproj b/src/Plugins/BotSharp.Plugin.SqlDriver/BotSharp.Plugin.SqlDriver.csproj
index 84ecc1ee5..dbd3228dc 100644
--- a/src/Plugins/BotSharp.Plugin.SqlDriver/BotSharp.Plugin.SqlDriver.csproj
+++ b/src/Plugins/BotSharp.Plugin.SqlDriver/BotSharp.Plugin.SqlDriver.csproj
@@ -107,6 +107,7 @@
+
diff --git a/src/Plugins/BotSharp.Plugin.SqlDriver/Hooks/SqlDriverCrontabHook.cs b/src/Plugins/BotSharp.Plugin.SqlDriver/Hooks/SqlDriverCrontabHook.cs
new file mode 100644
index 000000000..64629fcbf
--- /dev/null
+++ b/src/Plugins/BotSharp.Plugin.SqlDriver/Hooks/SqlDriverCrontabHook.cs
@@ -0,0 +1,47 @@
+using BotSharp.Core.Crontab.Abstraction;
+using BotSharp.Core.Crontab.Models;
+using Microsoft.EntityFrameworkCore.Query;
+
+namespace BotSharp.Plugin.SqlDriver.Hooks;
+
+public class SqlDriverCrontabHook : ICrontabHook
+{
+ private readonly IServiceProvider _services;
+ private readonly ILogger _logger;
+ public SqlDriverCrontabHook(IServiceProvider services, ILogger logger)
+ {
+ _services = services;
+ _logger = logger;
+ }
+
+ public async Task OnCronTriggered(CrontabItem item)
+ {
+ if (item.Language != "sql")
+ {
+ return;
+ }
+
+ _logger.LogWarning($"Crontab item triggered: {item.Topic}. Run {item.Language}: {item.Script}");
+
+ var conv = _services.GetRequiredService();
+ conv.SetConversationId("73a9ee27-d597-4739-958f-3bd79760ac8e", []);
+
+ var message = new RoleDialogModel(AgentRole.User, $"Run the query")
+ {
+ FunctionName = "sql_select",
+ FunctionArgs = JsonSerializer.Serialize(new SqlStatement
+ {
+ Statement = item.Script,
+ Reason = item.Description
+ })
+ };
+ var routing = _services.GetRequiredService();
+ routing.Context.Push("ec46f15b-8790-400f-a37f-1e7995b7d6e2");
+ await routing.InvokeFunction("sql_select", message);
+
+ item.ConversationId = conv.ConversationId;
+ item.AgentId = BuiltInAgentId.SqlDriver;
+ item.UserId = "41021346";
+ item.ExecutionResult = message.Content;
+ }
+}
diff --git a/src/Plugins/BotSharp.Plugin.SqlDriver/SqlDriverPlugin.cs b/src/Plugins/BotSharp.Plugin.SqlDriver/SqlDriverPlugin.cs
index cf4579d5b..d6fe125b8 100644
--- a/src/Plugins/BotSharp.Plugin.SqlDriver/SqlDriverPlugin.cs
+++ b/src/Plugins/BotSharp.Plugin.SqlDriver/SqlDriverPlugin.cs
@@ -1,4 +1,5 @@
using BotSharp.Abstraction.Planning;
+using BotSharp.Core.Crontab.Abstraction;
namespace BotSharp.Plugin.SqlDriver;
@@ -29,5 +30,6 @@ public void RegisterDI(IServiceCollection services, IConfiguration config)
services.AddScoped();
services.AddScoped();
services.AddScoped();
+ services.AddScoped();
}
}
diff --git a/src/Plugins/BotSharp.Plugin.SqlDriver/data/agents/beda4c12-e1ec-4b4b-b328-3df4a6687c4f/agent.json b/src/Plugins/BotSharp.Plugin.SqlDriver/data/agents/beda4c12-e1ec-4b4b-b328-3df4a6687c4f/agent.json
index 1ec4bfce9..00d1e0b37 100644
--- a/src/Plugins/BotSharp.Plugin.SqlDriver/data/agents/beda4c12-e1ec-4b4b-b328-3df4a6687c4f/agent.json
+++ b/src/Plugins/BotSharp.Plugin.SqlDriver/data/agents/beda4c12-e1ec-4b4b-b328-3df4a6687c4f/agent.json
@@ -1,7 +1,7 @@
{
"id": "beda4c12-e1ec-4b4b-b328-3df4a6687c4f",
"name": "SQL Driver",
- "description": "Transfer to this Agent is allowed only when executable SQL statements are provided in the context.",
+ "description": "Transfer to this Agent only when executable SQL statements are explicitly provided in the context.",
"iconUrl": "https://cdn-icons-png.flaticon.com/512/3161/3161158.png",
"type": "task",
"createdDateTime": "2023-11-15T13:49:00Z",
@@ -11,14 +11,14 @@
"profiles": [ "database" ],
"llmConfig": {
"provider": "openai",
- "model": "gpt-4o"
+ "model": "gpt-4o-2024-11-20"
},
"routingRules": [
{
"field": "sql_statement",
"required": true,
"field_type": "string",
- "description": "SQL statement provided in the context"
+ "description": "SQL statement explicitly provided in the context."
}
]
}
\ No newline at end of file
diff --git a/src/Plugins/BotSharp.Plugin.SqlDriver/data/agents/beda4c12-e1ec-4b4b-b328-3df4a6687c4f/functions/sql_select.json b/src/Plugins/BotSharp.Plugin.SqlDriver/data/agents/beda4c12-e1ec-4b4b-b328-3df4a6687c4f/functions/sql_select.json
index bd5b88ce8..f2aa4c36f 100644
--- a/src/Plugins/BotSharp.Plugin.SqlDriver/data/agents/beda4c12-e1ec-4b4b-b328-3df4a6687c4f/functions/sql_select.json
+++ b/src/Plugins/BotSharp.Plugin.SqlDriver/data/agents/beda4c12-e1ec-4b4b-b328-3df4a6687c4f/functions/sql_select.json
@@ -1,12 +1,12 @@
{
"name": "sql_select",
- "description": "Execute the reporting related query in the database and get the result",
+ "description": "Execute the provided query in the database and get the result.",
"parameters": {
"type": "object",
"properties": {
"sql_statement": {
"type": "string",
- "description": "SQL statement with SELECT"
+ "description": "SQL statement with SELECT provided in context."
},
"reason": {
"type": "string",