This commit is contained in:
Jicheng Lu 2025-10-09 16:25:26 -05:00
parent a75c0a097f
commit 53d85ec54c
31 changed files with 308 additions and 141 deletions

View file

@ -147,6 +147,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BotSharp.Plugin.ChartHandle
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BotSharp.Plugin.ExcelHandler", "src\Plugins\BotSharp.Plugin.ExcelHandler\BotSharp.Plugin.ExcelHandler.csproj", "{FC63C875-E880-D8BB-B8B5-978AB7B62983}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BotSharp.Plugin.ImageHandler", "src\Plugins\BotSharp.Plugin.ImageHandler\BotSharp.Plugin.ImageHandler.csproj", "{242F2D93-FCCE-4982-8075-F3052ECCA92C}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -619,6 +621,14 @@ Global
{FC63C875-E880-D8BB-B8B5-978AB7B62983}.Release|Any CPU.Build.0 = Release|Any CPU
{FC63C875-E880-D8BB-B8B5-978AB7B62983}.Release|x64.ActiveCfg = Release|Any CPU
{FC63C875-E880-D8BB-B8B5-978AB7B62983}.Release|x64.Build.0 = Release|Any CPU
{242F2D93-FCCE-4982-8075-F3052ECCA92C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{242F2D93-FCCE-4982-8075-F3052ECCA92C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{242F2D93-FCCE-4982-8075-F3052ECCA92C}.Debug|x64.ActiveCfg = Debug|Any CPU
{242F2D93-FCCE-4982-8075-F3052ECCA92C}.Debug|x64.Build.0 = Debug|Any CPU
{242F2D93-FCCE-4982-8075-F3052ECCA92C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{242F2D93-FCCE-4982-8075-F3052ECCA92C}.Release|Any CPU.Build.0 = Release|Any CPU
{242F2D93-FCCE-4982-8075-F3052ECCA92C}.Release|x64.ActiveCfg = Release|Any CPU
{242F2D93-FCCE-4982-8075-F3052ECCA92C}.Release|x64.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -690,6 +700,7 @@ Global
{B067B126-88CD-4282-BEEF-7369B64423EF} = {32FAFFFE-A4CB-4FEE-BF7C-84518BBC6DCC}
{0428DEAA-E4FE-4259-A6D8-6EDD1A9D0702} = {51AFE054-AE99-497D-A593-69BAEFB5106F}
{FC63C875-E880-D8BB-B8B5-978AB7B62983} = {51AFE054-AE99-497D-A593-69BAEFB5106F}
{242F2D93-FCCE-4982-8075-F3052ECCA92C} = {51AFE054-AE99-497D-A593-69BAEFB5106F}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {A9969D89-C98B-40A5-A12B-FC87E55B3A19}

View file

@ -137,8 +137,8 @@ public partial class FileInstructService
var foundAgent = await agentService.GetAgent(agentId);
var agent = new Agent
{
Id = foundAgent?.Id ?? BuiltInAgentId.UtilityAssistant,
Name = foundAgent?.Name ?? "Utility Assistant",
Id = foundAgent?.Id ?? BuiltInAgentId.FileAssistant,
Name = foundAgent?.Name ?? "File Assistant",
Instruction = prompt,
LlmConfig = new AgentLlmConfig
{

View file

@ -11,42 +11,18 @@
</PropertyGroup>
<ItemGroup>
<None Remove="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\functions\util-file-generate_image.json" />
<None Remove="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\templates\util-file-generate_image.fn.liquid" />
<None Remove="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\functions\util-file-read_image.json" />
<None Remove="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\templates\util-file-read_image.fn.liquid" />
<None Remove="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\functions\util-file-read_pdf.json" />
<None Remove="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\templates\util-file-read_pdf.fn.liquid" />
<None Remove="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\functions\util-file-edit_image.json" />
<None Remove="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\templates\util-file-edit_image.fn.liquid" />
<None Remove="data\agents\f1e09a73-9efe-46ce-ba02-b3aaf96d97e0\templates\select-chat-file_instruction.liquid" />
</ItemGroup>
<ItemGroup>
<Content Include="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\functions\util-file-generate_image.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\templates\util-file-generate_image.fn.liquid">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\functions\util-file-read_image.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\templates\util-file-read_image.fn.liquid">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\functions\util-file-read_pdf.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\templates\util-file-read_pdf.fn.liquid">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\functions\util-file-edit_image.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\templates\util-file-edit_image.fn.liquid">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="data\agents\f1e09a73-9efe-46ce-ba02-b3aaf96d97e0\templates\select-chat-file_instruction.liquid">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>

View file

@ -2,8 +2,5 @@ namespace BotSharp.Plugin.FileHandler.Enums;
public class UtilityName
{
public const string ImageGenerator = "image-generator";
public const string ImageReader = "image-reader";
public const string ImageEditor = "image-editor";
public const string PdfReader = "pdf-reader";
}

View file

@ -1,4 +1,3 @@
using BotSharp.Plugin.FileHandler.Converters;
using BotSharp.Plugin.FileHandler.Hooks;
using Microsoft.Extensions.Configuration;
@ -21,7 +20,6 @@ public class FileHandlerPlugin : IBotSharpPlugin
});
services.AddScoped<IAgentUtilityHook, FileHandlerUtilityHook>();
services.AddScoped<IImageConverter, FileHandlerImageConverter>();
}
}

View file

@ -2,51 +2,12 @@ namespace BotSharp.Plugin.FileHandler.Hooks;
public class FileHandlerUtilityHook : IAgentUtilityHook
{
private const string READ_IMAGE_FN = "util-file-read_image";
private const string READ_PDF_FN = "util-file-read_pdf";
private const string GENERATE_IMAGE_FN = "util-file-generate_image";
private const string EDIT_IMAGE_FN = "util-file-edit_image";
public void AddUtilities(List<AgentUtility> utilities)
{
var items = new List<AgentUtility>
{
new AgentUtility
{
Category = "file",
Name = UtilityName.ImageGenerator,
Items = [
new UtilityItem
{
FunctionName = GENERATE_IMAGE_FN,
TemplateName = $"{GENERATE_IMAGE_FN}.fn"
}
]
},
new AgentUtility
{
Category = "file",
Name = UtilityName.ImageReader,
Items = [
new UtilityItem
{
FunctionName = READ_IMAGE_FN,
TemplateName = $"{READ_IMAGE_FN}.fn"
}
]
},
new AgentUtility
{
Category = "file",
Name = UtilityName.ImageEditor,
Items = [
new UtilityItem
{
FunctionName = EDIT_IMAGE_FN,
TemplateName = $"{EDIT_IMAGE_FN}.fn"
}
]
},
new AgentUtility
{
Category = "file",

View file

@ -4,34 +4,9 @@ namespace BotSharp.Plugin.FileHandler.Settings;
public class FileHandlerSettings
{
public ImageSettings? Image { get; set; }
public PdfSettings? Pdf { get; set; }
}
#region Image
public class ImageSettings
{
public ImageReadSettings? Reading { get; set; }
public ImageGenerationSettings? Generation { get; set; }
public ImageEditSettings? Edit { get; set; }
}
public class ImageReadSettings : LlmBase
{
public string? ImageDetailLevel { get; set; }
}
public class ImageGenerationSettings : LlmBase
{
}
public class ImageEditSettings : LlmBase
{
public SettingBase? ImageConverter { get; set; }
}
#endregion
#region Pdf
public class PdfSettings
{

View file

@ -1 +0,0 @@
Please call util-file-edit_image if user wants to edit, change or modify an image in the conversation.

View file

@ -1,2 +0,0 @@
** Please call util-file-generate_image if user wants you to provide or generate an image or picture.
** Please do not call util-file-generate_image, if user does not generate image explicitly or wants to change or edit the existing image.

View file

@ -1,2 +0,0 @@
Please call function util-file-read_image if user wants to describe an image or images.
You can also call function util-file-read_image to access the image or images that user uploaded.

View file

@ -0,0 +1,42 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>$(TargetFramework)</TargetFramework>
<Nullable>enable</Nullable>
<LangVersion>$(LangVersion)</LangVersion>
<VersionPrefix>$(BotSharpVersion)</VersionPrefix>
<GeneratePackageOnBuild>$(GeneratePackageOnBuild)</GeneratePackageOnBuild>
<GenerateDocumentationFile>$(GenerateDocumentationFile)</GenerateDocumentationFile>
<OutputPath>$(SolutionDir)packages</OutputPath>
</PropertyGroup>
<ItemGroup>
<Content Include="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\functions\util-image-generate_image.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\templates\util-image-generate_image.fn.liquid">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\functions\util-image-read_image.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\templates\util-image-read_image.fn.liquid">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\functions\util-image-edit_image.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\templates\util-image-edit_image.fn.liquid">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<PackageReference Include="SixLabors.ImageSharp" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Infrastructure\BotSharp.Core\BotSharp.Core.csproj" />
</ItemGroup>
</Project>

View file

@ -3,22 +3,22 @@ using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Formats.Png;
using System.IO;
namespace BotSharp.Plugin.FileHandler.Converters;
namespace BotSharp.Plugin.ImageHandler.Converters;
public class FileHandlerImageConverter : IImageConverter
public class ImageHandlerImageConverter : IImageConverter
{
private readonly IServiceProvider _services;
private readonly ILogger<FileHandlerImageConverter> _logger;
private readonly ILogger<ImageHandlerImageConverter> _logger;
public FileHandlerImageConverter(
public ImageHandlerImageConverter(
IServiceProvider services,
ILogger<FileHandlerImageConverter> logger)
ILogger<ImageHandlerImageConverter> logger)
{
_services = services;
_logger = logger;
}
public string Provider => "file-handler";
public string Provider => "image-handler";
public async Task<BinaryData> ConvertImage(BinaryData binary, ImageConvertOptions? options = null)
{

View file

@ -0,0 +1,8 @@
namespace BotSharp.Plugin.ImageHandler.Enums;
public class UtilityName
{
public const string ImageGenerator = "image-generator";
public const string ImageReader = "image-reader";
public const string ImageEditor = "image-editor";
}

View file

@ -1,15 +1,15 @@
using BotSharp.Abstraction.Conversations.Settings;
namespace BotSharp.Plugin.FileHandler.Functions;
namespace BotSharp.Plugin.ImageHandler.Functions;
public class EditImageFn : IFunctionCallback
{
public string Name => "util-file-edit_image";
public string Name => "util-image-edit_image";
public string Indication => "Editing image";
private readonly IServiceProvider _services;
private readonly ILogger<EditImageFn> _logger;
private readonly FileHandlerSettings _settings;
private readonly ImageHandlerSettings _settings;
private Agent _agent;
private string _conversationId;
@ -18,7 +18,7 @@ public class EditImageFn : IFunctionCallback
public EditImageFn(
IServiceProvider services,
ILogger<EditImageFn> logger,
FileHandlerSettings settings)
ImageHandlerSettings settings)
{
_services = services;
_logger = logger;
@ -91,8 +91,8 @@ public class EditImageFn : IFunctionCallback
var dialog = RoleDialogModel.From(message, AgentRole.User, text);
var agent = new Agent
{
Id = _agent?.Id ?? BuiltInAgentId.UtilityAssistant,
Name = _agent?.Name ?? "Utility Assistant"
Id = _agent?.Id ?? BuiltInAgentId.FileAssistant,
Name = _agent?.Name ?? "File Assistant"
};
var fileStorage = _services.GetRequiredService<IFileStorageService>();
@ -132,8 +132,8 @@ public class EditImageFn : IFunctionCallback
var llmConfig = _agent.LlmConfig;
var agent = new Agent
{
Id = _agent?.Id ?? BuiltInAgentId.UtilityAssistant,
Name = _agent?.Name ?? "Utility Assistant",
Id = _agent?.Id ?? BuiltInAgentId.FileAssistant,
Name = _agent?.Name ?? "File Assistant",
LlmConfig = new AgentLlmConfig
{
Provider = llmConfig?.Provider ?? "openai",
@ -159,8 +159,8 @@ public class EditImageFn : IFunctionCallback
return (provider, model);
}
provider = _settings?.Image?.Edit?.LlmProvider;
model = _settings?.Image?.Edit?.LlmModel;
provider = _settings?.Edit?.LlmProvider;
model = _settings?.Edit?.LlmModel;
if (!string.IsNullOrEmpty(provider) && !string.IsNullOrEmpty(model))
{
@ -196,7 +196,7 @@ public class EditImageFn : IFunctionCallback
private async Task<BinaryData> ConvertImageToPngWithRgba(BinaryData binaryFile)
{
var provider = _settings?.Image?.Edit?.ImageConverter?.Provider;
var provider = _settings?.Edit?.ImageConverter?.Provider;
var converter = _services.GetServices<IImageConverter>().FirstOrDefault(x => x.Provider == provider);
if (converter == null)
{

View file

@ -1,13 +1,13 @@
namespace BotSharp.Plugin.FileHandler.Functions;
namespace BotSharp.Plugin.ImageHandler.Functions;
public class GenerateImageFn : IFunctionCallback
{
public string Name => "util-file-generate_image";
public string Name => "util-image-generate_image";
public string Indication => "Generating image";
private readonly IServiceProvider _services;
private readonly ILogger<GenerateImageFn> _logger;
private readonly FileHandlerSettings _settings;
private readonly ImageHandlerSettings _settings;
private Agent _agent;
private string _conversationId;
@ -16,7 +16,7 @@ public class GenerateImageFn : IFunctionCallback
public GenerateImageFn(
IServiceProvider services,
ILogger<GenerateImageFn> logger,
FileHandlerSettings settings)
ImageHandlerSettings settings)
{
_services = services;
_logger = logger;
@ -59,8 +59,8 @@ public class GenerateImageFn : IFunctionCallback
{
var agent = new Agent
{
Id = _agent?.Id ?? BuiltInAgentId.UtilityAssistant,
Name = _agent?.Name ?? "Utility Assistant",
Id = _agent?.Id ?? BuiltInAgentId.FileAssistant,
Name = _agent?.Name ?? "File Assistant",
Instruction = description
};
@ -96,8 +96,8 @@ public class GenerateImageFn : IFunctionCallback
var llmConfig = _agent.LlmConfig;
var agent = new Agent
{
Id = _agent?.Id ?? BuiltInAgentId.UtilityAssistant,
Name = _agent?.Name ?? "Utility Assistant",
Id = _agent?.Id ?? BuiltInAgentId.FileAssistant,
Name = _agent?.Name ?? "File Assistant",
LlmConfig = new AgentLlmConfig
{
Provider = llmConfig?.Provider ?? "openai",
@ -123,8 +123,8 @@ public class GenerateImageFn : IFunctionCallback
return (provider, model);
}
provider = _settings?.Image?.Generation?.LlmProvider;
model = _settings?.Image?.Generation?.LlmModel;
provider = _settings?.Generation?.LlmProvider;
model = _settings?.Generation?.LlmModel;
if (!string.IsNullOrEmpty(provider) && !string.IsNullOrEmpty(model))
{

View file

@ -1,15 +1,15 @@
using BotSharp.Abstraction.Routing;
namespace BotSharp.Plugin.FileHandler.Functions;
namespace BotSharp.Plugin.ImageHandler.Functions;
public class ReadImageFn : IFunctionCallback
{
public string Name => "util-file-read_image";
public string Name => "util-image-read_image";
public string Indication => "Reading images";
private readonly IServiceProvider _services;
private readonly ILogger<ReadImageFn> _logger;
private readonly FileHandlerSettings _settings;
private readonly ImageHandlerSettings _settings;
private readonly IEnumerable<string> _imageContentTypes = new List<string>
{
@ -20,7 +20,7 @@ public class ReadImageFn : IFunctionCallback
public ReadImageFn(
IServiceProvider services,
ILogger<ReadImageFn> logger,
FileHandlerSettings settings)
ImageHandlerSettings settings)
{
_services = services;
_logger = logger;
@ -42,8 +42,8 @@ public class ReadImageFn : IFunctionCallback
var agent = new Agent
{
Id = fromAgent?.Id ?? BuiltInAgentId.UtilityAssistant,
Name = fromAgent?.Name ?? "Utility Assistant",
Id = fromAgent?.Id ?? BuiltInAgentId.FileAssistant,
Name = fromAgent?.Name ?? "File Assistant",
Instruction = fromAgent?.Instruction ?? args?.UserRequest ?? "Please describe the image(s).",
LlmConfig = fromAgent?.LlmConfig ?? new()
};
@ -144,8 +144,8 @@ public class ReadImageFn : IFunctionCallback
return (provider, model);
}
provider = _settings?.Image?.Reading?.LlmProvider;
model = _settings?.Image?.Reading?.LlmModel;
provider = _settings?.Reading?.LlmProvider;
model = _settings?.Reading?.LlmModel;
if (!string.IsNullOrEmpty(provider) && !string.IsNullOrEmpty(model))
{
@ -161,14 +161,13 @@ public class ReadImageFn : IFunctionCallback
private void SetImageDetailLevel()
{
var state = _services.GetRequiredService<IConversationStateService>();
var fileSettings = _services.GetRequiredService<FileHandlerSettings>();
var key = "chat_image_detail_level";
var level = state.GetState(key);
if (string.IsNullOrWhiteSpace(level) && !string.IsNullOrWhiteSpace(fileSettings.Image?.Reading?.ImageDetailLevel))
if (string.IsNullOrWhiteSpace(level) && !string.IsNullOrWhiteSpace(_settings.Reading?.ImageDetailLevel))
{
state.SetState(key, fileSettings.Image.Reading.ImageDetailLevel);
state.SetState(key, _settings.Reading.ImageDetailLevel);
}
}
}

View file

@ -0,0 +1,31 @@
namespace BotSharp.Plugin.ImageHandler.Helpers;
internal static class AiResponseHelper
{
internal static string GetDefaultResponse(IEnumerable<string> files)
{
if (files.IsNullOrEmpty())
{
return $"No image is generated.";
}
if (files.Count() > 1)
{
return $"Here are the images you asked for: {string.Join(", ", files)}";
}
return $"Here is the image you asked for: {string.Join(", ", files)}";
}
internal static async Task<string> GetImageGenerationResponse(IServiceProvider services, Agent agent, string description)
{
var text = $"Please generate a user-friendly response from the following description to " +
$"inform user that you have completed the required image: {description}";
var provider = agent?.LlmConfig?.Provider ?? "openai";
var model = agent?.LlmConfig?.Model ?? "gpt-4o-mini";
var completion = CompletionProvider.GetChatCompletion(services, provider: provider, model: model);
var response = await completion.GetChatCompletions(agent, [new RoleDialogModel(AgentRole.User, text)]);
return response.Content;
}
}

View file

@ -0,0 +1,53 @@
namespace BotSharp.Plugin.ImageHandler.Hooks;
public class ImageHandlerUtilityHook : IAgentUtilityHook
{
private const string READ_IMAGE_FN = "util-file-read_image";
private const string GENERATE_IMAGE_FN = "util-file-generate_image";
private const string EDIT_IMAGE_FN = "util-file-edit_image";
public void AddUtilities(List<AgentUtility> utilities)
{
var items = new List<AgentUtility>
{
new AgentUtility
{
Category = "image",
Name = UtilityName.ImageGenerator,
Items = [
new UtilityItem
{
FunctionName = GENERATE_IMAGE_FN,
TemplateName = $"{GENERATE_IMAGE_FN}.fn"
}
]
},
new AgentUtility
{
Category = "image",
Name = UtilityName.ImageReader,
Items = [
new UtilityItem
{
FunctionName = READ_IMAGE_FN,
TemplateName = $"{READ_IMAGE_FN}.fn"
}
]
},
new AgentUtility
{
Category = "image",
Name = UtilityName.ImageEditor,
Items = [
new UtilityItem
{
FunctionName = EDIT_IMAGE_FN,
TemplateName = $"{EDIT_IMAGE_FN}.fn"
}
]
}
};
utilities.AddRange(items);
}
}

View file

@ -0,0 +1,27 @@
using BotSharp.Plugin.ImageHandler.Converters;
using BotSharp.Plugin.ImageHandler.Hooks;
using Microsoft.Extensions.Configuration;
namespace BotSharp.Plugin.ImageHandler;
public class FileHandlerPlugin : IBotSharpPlugin
{
public string Id => "bac8bbf3-da91-4c92-98d8-db14d68e75ae";
public string Name => "Image Handler";
public string Description => "AI handles images.";
public string IconUrl => "https://lirp.cdn-website.com/6f8d6d8a/dms3rep/multi/opt/API_Icon-640w.png";
public string[] AgentIds => [];
public void RegisterDI(IServiceCollection services, IConfiguration config)
{
services.AddScoped(provider =>
{
var settingService = provider.GetRequiredService<ISettingService>();
return settingService.Bind<ImageHandlerSettings>("ImageHandler");
});
services.AddScoped<IAgentUtilityHook, ImageHandlerUtilityHook>();
services.AddScoped<IImageConverter, ImageHandlerImageConverter>();
}
}

View file

@ -0,0 +1,18 @@
using System.Text.Json.Serialization;
namespace BotSharp.Plugin.ImageHandler.LlmContexts;
public class LlmContextIn
{
[JsonPropertyName("user_request")]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public string? UserRequest { get; set; }
[JsonPropertyName("image_description")]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public string? ImageDescription { get; set; }
[JsonPropertyName("image_urls")]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public IEnumerable<string>? ImageUrls { get; set; }
}

View file

@ -0,0 +1,10 @@
using System.Text.Json.Serialization;
namespace BotSharp.Plugin.ImageHandler.LlmContexts;
public class LlmContextOut
{
[JsonPropertyName("selected_id")]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public int? Selected { get; set; }
}

View file

@ -0,0 +1,25 @@
using BotSharp.Abstraction.Models;
namespace BotSharp.Plugin.ImageHandler.Settings;
public class ImageHandlerSettings
{
public ImageReadSettings? Reading { get; set; }
public ImageGenerationSettings? Generation { get; set; }
public ImageEditSettings? Edit { get; set; }
}
public class ImageReadSettings : LlmBase
{
public string? ImageDetailLevel { get; set; }
}
public class ImageGenerationSettings : LlmBase
{
}
public class ImageEditSettings : LlmBase
{
public SettingBase? ImageConverter { get; set; }
}

View file

@ -0,0 +1,34 @@
global using System;
global using System.Collections.Generic;
global using System.Text;
global using System.Linq;
global using System.Text.Json;
global using System.Net.Mime;
global using System.Threading.Tasks;
global using Microsoft.Extensions.DependencyInjection;
global using Microsoft.Extensions.Logging;
global using BotSharp.Abstraction.Agents;
global using BotSharp.Abstraction.Conversations;
global using BotSharp.Abstraction.Plugins;
global using BotSharp.Abstraction.Conversations.Models;
global using BotSharp.Abstraction.Functions;
global using BotSharp.Abstraction.Agents.Models;
global using BotSharp.Abstraction.Agents.Enums;
global using BotSharp.Abstraction.Files.Enums;
global using BotSharp.Abstraction.Files.Models;
global using BotSharp.Abstraction.Files.Converters;
global using BotSharp.Abstraction.Files;
global using BotSharp.Abstraction.MLTasks;
global using BotSharp.Abstraction.Utilities;
global using BotSharp.Abstraction.Agents.Settings;
global using BotSharp.Abstraction.Functions.Models;
global using BotSharp.Abstraction.Repositories;
global using BotSharp.Abstraction.Settings;
global using BotSharp.Abstraction.Messaging;
global using BotSharp.Abstraction.Messaging.Models.RichContent;
global using BotSharp.Abstraction.Options;
global using BotSharp.Core.Infrastructures;
global using BotSharp.Plugin.ImageHandler.Enums;
global using BotSharp.Plugin.ImageHandler.Settings;
global using BotSharp.Plugin.ImageHandler.LlmContexts;
global using BotSharp.Plugin.ImageHandler.Helpers;

View file

@ -1,5 +1,5 @@
{
"name": "util-file-edit_image",
"name": "util-image-edit_image",
"description": "If the user requests you editting or changing an image or a picture, you can call this function to edit an image.",
"parameters": {
"type": "object",

View file

@ -1,5 +1,5 @@
{
"name": "util-file-generate_image",
"name": "util-image-generate_image",
"description": "If the user requests you providing or generating image or picture, you can call this function to generate image.",
"parameters": {
"type": "object",

View file

@ -1,5 +1,5 @@
{
"name": "util-file-read_image",
"name": "util-image-read_image",
"description": "If the user's request is related to describing or analyzing images, you can call this function to analyze images.",
"parameters": {
"type": "object",

View file

@ -0,0 +1 @@
Please call util-image-edit_image if user wants to edit, change or modify an image in the conversation.

View file

@ -0,0 +1,2 @@
** Please call util-image-generate_image if user wants you to provide or generate an image or picture.
** Please do not call util-image-generate_image, if user does not generate image explicitly or wants to change or edit the existing image.

View file

@ -0,0 +1,2 @@
Please call function util-image-read_image if user wants to describe an image or images.
You can also call function util-image-read_image to access the image or images that user uploaded.

View file

@ -37,6 +37,7 @@
<ProjectReference Include="..\..\tests\BotSharp.Plugin.PizzaBot\BotSharp.Plugin.PizzaBot.csproj" />
<ProjectReference Include="..\BotSharp.ServiceDefaults\BotSharp.ServiceDefaults.csproj" />
<ProjectReference Include="..\Plugins\BotSharp.Plugin.ExcelHandler\BotSharp.Plugin.ExcelHandler.csproj" />
<ProjectReference Include="..\Plugins\BotSharp.Plugin.ImageHandler\BotSharp.Plugin.ImageHandler.csproj" />
<ProjectReference Include="..\Plugins\BotSharp.Plugin.PythonInterpreter\BotSharp.Plugin.PythonInterpreter.csproj" />
</ItemGroup>

View file

@ -621,6 +621,7 @@
"BotSharp.Plugin.MetaGLM",
"BotSharp.Plugin.HttpHandler",
"BotSharp.Plugin.FileHandler",
"BotSharp.Plugin.ImageHandler",
"BotSharp.Plugin.EmailHandler",
"BotSharp.Plugin.AudioHandler",
"BotSharp.Plugin.ChartHandler",