Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,4 @@ public class BuiltInAgentId
/// Translates user-defined natural language rules into programmatic code
/// </summary>
public const string RuleEncoder = "6acfb93c-3412-402e-9ba5-c5d3cd8f0161";

/// <summary>
/// Schedule job
/// </summary>
public const string Crontab = "c2o139da-a62a-4355-8605-fdf0ffaca58e";
}
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,15 @@
</PropertyGroup>

<ItemGroup>
<None Remove="data\agents\c2o139da-a62a-4355-8605-fdf0ffaca58e\agent.json" />
<None Remove="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\functions\util-crontab-schedule_task.json" />
<None Remove="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\templates\util-crontab-schedule_task.fn.liquid" />
</ItemGroup>

<ItemGroup>
<Content Include="data\agents\c2o139da-a62a-4355-8605-fdf0ffaca58e\agent.json">
<Content Include="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\functions\util-crontab-schedule_task.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\templates\util-crontab-schedule_task.fn.liquid">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
Expand Down
8 changes: 3 additions & 5 deletions src/Infrastructure/BotSharp.Core.Crontab/CrontabPlugin.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

/// <summary>
Expand All @@ -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<IAgentUtilityHook, CrontabUtilityHook>();
services.AddScoped<ICrontabService, CrontabService>();
services.AddHostedService<CrontabWatcher>();
}
Expand Down
6 changes: 6 additions & 0 deletions src/Infrastructure/BotSharp.Core.Crontab/Enum/UtilityName.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace BotSharp.Core.Crontab.Enum;

public class UtilityName
{
public const string ScheduleTask = "crontab.schedule-task";
}
Original file line number Diff line number Diff line change
@@ -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<bool> Execute(RoleDialogModel message)
{
var args = JsonSerializer.Deserialize<ScheduleTaskArgs>(message.FunctionArgs);

var routing = _services.GetRequiredService<IRoutingContext>();
var user = _services.GetRequiredService<IUserIdentity>();
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;
}
}
Original file line number Diff line number Diff line change
@@ -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<AgentUtility> utilities)
{
var items = new List<AgentUtility>
{
new AgentUtility
{
Name = UtilityName.ScheduleTask,
Functions = [new(SCHEDULE_TASK_FN)],
Templates = [new($"{SCHEDULE_TASK_FN}.fn")]
}
};

utilities.AddRange(items);
}
}
Original file line number Diff line number Diff line change
@@ -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}]";
}
}
Original file line number Diff line number Diff line change
@@ -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!;
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -56,22 +58,38 @@ public CrontabService(IServiceProvider services, ILogger<CrontabService> logger)

public async Task<List<CrontabItem>> GetCrontable()
{
var convService = _services.GetRequiredService<IConversationService>();
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<ICrontabHook>(_services, async hook =>
_logger.LogDebug($"ScheduledTimeArrived {item}");

var hooks = _services.GetServices<ICrontabHook>();
foreach(var hook in hooks)
{
await hook.OnCronTriggered(item);
}
/*await HookEmitter.Emit<ICrontabHook>(_services, async hook =>
await hook.OnCronTriggered(item)
);
);*/
await Task.Delay(1000 * 10);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
Expand Down
6 changes: 6 additions & 0 deletions src/Infrastructure/BotSharp.Core.Crontab/Using.cs
Original file line number Diff line number Diff line change
@@ -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;
Original file line number Diff line number Diff line change
@@ -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" ]
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Call schedule_task if user needs to set up a scheduled task with appropriate programming script and language type.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public static HookEmittedResult Emit<T>(IServiceProvider services, Action<T> 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)
Expand Down Expand Up @@ -43,7 +43,7 @@ public static async Task<HookEmittedResult> Emit<T>(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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

<ItemGroup>
<FrameworkReference Include="Microsoft.AspNetCore.App" />
<ProjectReference Include="..\..\Infrastructure\BotSharp.Core.Crontab\BotSharp.Core.Crontab.csproj" />
<ProjectReference Include="..\..\Infrastructure\BotSharp.OpenAPI\BotSharp.OpenAPI.csproj" />
</ItemGroup>
</Project>
2 changes: 2 additions & 0 deletions src/Plugins/BotSharp.Plugin.ChatHub/ChatHubPlugin.cs
Original file line number Diff line number Diff line change
@@ -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;

Expand All @@ -23,5 +24,6 @@ public void RegisterDI(IServiceCollection services, IConfiguration config)
services.AddScoped<IConversationHook, WelcomeHook>();
services.AddScoped<IRoutingHook, StreamingLogHook>();
services.AddScoped<IContentGeneratingHook, StreamingLogHook>();
services.AddScoped<ICrontabHook, ChatHubCrontabHook>();
}
}
Loading