commit
c57ca81bee
|
|
@ -116,13 +116,14 @@ public abstract class AgentHookBase : IAgentHook
|
|||
return ([], []);
|
||||
}
|
||||
|
||||
var prefix = "util-";
|
||||
utilities = utilities?.Where(x => !string.IsNullOrEmpty(x.Name) && !x.Disabled)?.ToList() ?? [];
|
||||
var functionNames = utilities.SelectMany(x => x.Functions)
|
||||
.Where(x => !string.IsNullOrEmpty(x.Name))
|
||||
.Where(x => !string.IsNullOrEmpty(x.Name) && x.Name.StartsWith(prefix))
|
||||
.Select(x => x.Name)
|
||||
.Distinct().ToList();
|
||||
var templateNames = utilities.SelectMany(x => x.Templates)
|
||||
.Where(x => !string.IsNullOrEmpty(x.Name))
|
||||
.Where(x => !string.IsNullOrEmpty(x.Name) && x.Name.StartsWith(prefix))
|
||||
.Select(x => x.Name)
|
||||
.Distinct().ToList();
|
||||
|
||||
|
|
|
|||
|
|
@ -24,15 +24,15 @@
|
|||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Remove="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\functions\handle_audio_request.json" />
|
||||
<None Remove="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\templates\handle_audio_request.fn.liquid" />
|
||||
<None Remove="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\functions\util-audio-handle_audio_request.json" />
|
||||
<None Remove="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\templates\util-audio-handle_audio_request.fn.liquid" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Include="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\templates\handle_audio_request.fn.liquid">
|
||||
<Content Include="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\templates\util-audio-handle_audio_request.fn.liquid">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\functions\handle_audio_request.json">
|
||||
<Content Include="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\functions\util-audio-handle_audio_request.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
|
|
|
|||
|
|
@ -2,5 +2,5 @@ namespace BotSharp.Plugin.AudioHandler.Enums;
|
|||
|
||||
public class UtilityName
|
||||
{
|
||||
public const string AudioHandler = "audio-handler";
|
||||
public const string AudioHandler = "audio.audio-handler";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ namespace BotSharp.Plugin.AudioHandler.Functions;
|
|||
|
||||
public class HandleAudioRequestFn : IFunctionCallback
|
||||
{
|
||||
public string Name => "handle_audio_request";
|
||||
public string Name => "util-audio-handle_audio_request";
|
||||
public string Indication => "Handling audio request";
|
||||
|
||||
private readonly IServiceProvider _serviceProvider;
|
||||
|
|
|
|||
|
|
@ -2,7 +2,8 @@ namespace BotSharp.Plugin.AudioHandler.Hooks;
|
|||
|
||||
public class AudioHandlerUtilityHook : IAgentUtilityHook
|
||||
{
|
||||
private const string HANDLER_AUDIO = "handle_audio_request";
|
||||
private const string PREFIX = "util-audio-";
|
||||
private const string HANDLER_AUDIO = $"{PREFIX}handle_audio_request";
|
||||
|
||||
public void AddUtilities(List<AgentUtility> utilities)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"name": "handle_audio_request",
|
||||
"name": "util-audio-handle_audio_request",
|
||||
"description": "If the user requests to transcribe or summarize audio content, you need to call this function to transcribe the audio content to raw texts or provide sunmmary based on raw texts transcribed from audio",
|
||||
"parameters": {
|
||||
"type": "object",
|
||||
|
|
@ -1 +0,0 @@
|
|||
Please call handle_audio_request if user wants to transcribe or summarize the content of a audio file.
|
||||
|
|
@ -0,0 +1 @@
|
|||
Please call util-audio-handle_audio_request if user wants to transcribe or summarize the content of a audio file.
|
||||
|
|
@ -11,24 +11,23 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Remove="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\functions\handle_email_reader.json" />
|
||||
<None Remove="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\functions\handle_email_sender.json" />
|
||||
<None Remove="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\templates\handle_email_sender.fn.liquid" />
|
||||
<None Remove="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\templates\handle_email_reader.fn.liquid" />
|
||||
<None Remove="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\templates\select_attachment_prompt.liquid" />
|
||||
<None Remove="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\functions\util-email-handle_email_reader.json" />
|
||||
<None Remove="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\functions\util-email-handle_email_sender.json" />
|
||||
<None Remove="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\templates\util-email-handle_email_sender.fn.liquid" />
|
||||
<None Remove="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\templates\util-email-handle_email_reader.fn.liquid" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Include="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\functions\handle_email_reader.json">
|
||||
<Content Include="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\functions\util-email-handle_email_reader.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\functions\handle_email_sender.json">
|
||||
<Content Include="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\functions\util-email-handle_email_sender.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\templates\handle_email_sender.fn.liquid">
|
||||
<Content Include="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\templates\util-email-handle_email_sender.fn.liquid">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\templates\handle_email_reader.fn.liquid">
|
||||
<Content Include="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\templates\util-email-handle_email_reader.fn.liquid">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
|
|
|
|||
|
|
@ -1,13 +1,6 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
namespace BotSharp.Plugin.EmailHandler.Enums;
|
||||
|
||||
namespace BotSharp.Plugin.EmailHandler.Enums
|
||||
public class UtilityName
|
||||
{
|
||||
public class UtilityName
|
||||
{
|
||||
public const string EmailHandler = "email-handler";
|
||||
}
|
||||
public const string EmailHandler = "email.email-handler";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ namespace BotSharp.Plugin.EmailReader.Functions;
|
|||
|
||||
public class HandleEmailReaderFn : IFunctionCallback
|
||||
{
|
||||
public string Name => "handle_email_reader";
|
||||
public string Name => "util-email-handle_email_reader";
|
||||
public readonly static string PROMPT_SUMMARY = "Provide a text summary of the following content.";
|
||||
public readonly static string RICH_CONTENT_SUMMARIZE = "is_email_summarize: true. messageId";
|
||||
public readonly static string RICH_CONTENT_READ_EMAIL = "Read the email by messageId";
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ namespace BotSharp.Plugin.EmailHandler.Functions;
|
|||
|
||||
public class HandleEmailSenderFn : IFunctionCallback
|
||||
{
|
||||
public string Name => "handle_email_sender";
|
||||
public string Name => "util-email-handle_email_sender";
|
||||
public string Indication => "Handling email send request";
|
||||
|
||||
private readonly IServiceProvider _services;
|
||||
|
|
|
|||
|
|
@ -5,8 +5,9 @@ namespace BotSharp.Plugin.EmailHandler.Hooks;
|
|||
|
||||
public class EmailHandlerUtilityHook : IAgentUtilityHook
|
||||
{
|
||||
private static string EMAIL_READER_FN = "handle_email_reader";
|
||||
private static string EMAIL_SENDER_FN = "handle_email_sender";
|
||||
private static string PREFIX = "util-email-";
|
||||
private static string EMAIL_READER_FN = $"{PREFIX}handle_email_reader";
|
||||
private static string EMAIL_SENDER_FN = $"{PREFIX}handle_email_sender";
|
||||
|
||||
public void AddUtilities(List<AgentUtility> utilities)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"name": "handle_email_reader",
|
||||
"name": "util-email-handle_email_reader",
|
||||
"description": "If the user wants to read messages from email inbox or user wants to mark an email message as read.If message id is provided, capture it but it is not required. Then call this function to read the email message or mark any message as read.",
|
||||
"parameters": {
|
||||
"type": "object",
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"name": "handle_email_sender",
|
||||
"name": "util-email-handle_email_sender",
|
||||
"description": "If the user requests to send an email with or without attachments or files, you need to capture the email content and the recipient email address. If the user explicitly enter email subject use the same if not intelligently capture the email subject from the content. Then call this function to send out email.",
|
||||
"parameters": {
|
||||
"type": "object",
|
||||
|
|
@ -1 +0,0 @@
|
|||
Please call handle_email_reader if user wants to read messages from email inbox.
|
||||
|
|
@ -0,0 +1 @@
|
|||
Please call util-email-handle_email_reader if user wants to read messages from email inbox.
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
** Please take a look at the conversation and decide whether user wants to send email.
|
||||
** If yes, then decide whether user wants to send email with files/attachments/images or not.
|
||||
** If user does not want to send email explicitly or only upload images or files, please do not respond anything email related message.
|
||||
** Please call handle_email_sender if user wants to send email.
|
||||
** Please call util-email-handle_email_sender if user wants to send email.
|
||||
|
|
@ -13,15 +13,15 @@
|
|||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Remove="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\functions\handle_excel_request.json" />
|
||||
<None Remove="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\templates\handle_excel_request.fn.liquid" />
|
||||
<None Remove="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\functions\util-excel-handle_excel_request.json" />
|
||||
<None Remove="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\templates\util-excel-handle_excel_request.fn.liquid" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Include="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\functions\handle_excel_request.json">
|
||||
<Content Include="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\functions\util-excel-handle_excel_request.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\templates\handle_excel_request.fn.liquid">
|
||||
<Content Include="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\templates\util-excel-handle_excel_request.fn.liquid">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
|
|
|
|||
|
|
@ -2,5 +2,5 @@ namespace BotSharp.Plugin.ExcelHandler.Enums;
|
|||
|
||||
public class UtilityName
|
||||
{
|
||||
public const string ExcelHandler = "excel-handler";
|
||||
public const string ExcelHandler = "excel.excel-handler";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ using System.Linq.Dynamic.Core;
|
|||
using BotSharp.Abstraction.Files.Enums;
|
||||
using BotSharp.Abstraction.Files.Models;
|
||||
using BotSharp.Abstraction.Files.Utilities;
|
||||
using BotSharp.Plugin.ExcelHandler.Helpers.Sqlite;
|
||||
using BotSharp.Plugin.ExcelHandler.Models;
|
||||
using BotSharp.Plugin.ExcelHandler.Services;
|
||||
using NPOI.SS.UserModel;
|
||||
|
|
@ -12,7 +11,7 @@ namespace BotSharp.Plugin.ExcelHandler.Functions;
|
|||
|
||||
public class HandleExcelRequestFn : IFunctionCallback
|
||||
{
|
||||
public string Name => "handle_excel_request";
|
||||
public string Name => "util-excel-handle_excel_request";
|
||||
public string Indication => "Handling excel request";
|
||||
|
||||
private readonly IServiceProvider _serviceProvider;
|
||||
|
|
|
|||
|
|
@ -2,7 +2,8 @@ namespace BotSharp.Plugin.ExcelHandler.Hooks;
|
|||
|
||||
public class ExcelHandlerUtilityHook : IAgentUtilityHook
|
||||
{
|
||||
private const string HANDLER_EXCEL = "handle_excel_request";
|
||||
private static string PREFIX = "util-excel-";
|
||||
private static string HANDLER_EXCEL = $"{PREFIX}handle_excel_request";
|
||||
|
||||
public void AddUtilities(List<AgentUtility> utilities)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"name": "handle_excel_request",
|
||||
"name": "util-excel-handle_excel_request",
|
||||
"description": "If the user requests to read/load data from excel/csv files, you need to call this function to load the data from excel/csv files and transform into JSON format data",
|
||||
"parameters": {
|
||||
"type": "object",
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
Please call handle_excel_request if user wants to load the data from a excel/csv file.
|
||||
handle_excel_request can NOT generate excel/csv.
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
Please call util-excel-handle_excel_request if user wants to load the data from a excel/csv file.
|
||||
util-excel-handle_excel_request can NOT generate excel/csv.
|
||||
|
|
@ -11,40 +11,43 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Remove="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\functions\edit_image.json" />
|
||||
<None Remove="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\functions\generate_image.json" />
|
||||
<None Remove="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\functions\read_image.json" />
|
||||
<None Remove="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\functions\read_pdf.json" />
|
||||
<None Remove="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\templates\edit_image.fn.liquid" />
|
||||
<None Remove="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\templates\generate_image.fn.liquid" />
|
||||
<None Remove="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\templates\read_image.fn.liquid" />
|
||||
<None Remove="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\templates\read_pdf.fn.liquid" />
|
||||
<None Remove="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\templates\select_edit_image_prompt.liquid" />
|
||||
</ItemGroup>
|
||||
|
||||
<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" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Include="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\functions\generate_image.json">
|
||||
<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\functions\read_image.json">
|
||||
<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\templates\generate_image.fn.liquid">
|
||||
<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\read_image.fn.liquid">
|
||||
<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\read_pdf.json">
|
||||
<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\read_pdf.fn.liquid">
|
||||
<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\edit_image.json">
|
||||
<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\edit_image.fn.liquid">
|
||||
<Content Include="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\templates\util-file-edit_image.fn.liquid">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@ 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";
|
||||
public const string ImageGenerator = "file.image-generator";
|
||||
public const string ImageReader = "file.image-reader";
|
||||
public const string ImageEditor = "file.image-editor";
|
||||
public const string PdfReader = "file.pdf-reader";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ namespace BotSharp.Plugin.FileHandler.Functions;
|
|||
|
||||
public class EditImageFn : IFunctionCallback
|
||||
{
|
||||
public string Name => "edit_image";
|
||||
public string Name => "util-file-edit_image";
|
||||
public string Indication => "Editing image";
|
||||
|
||||
private readonly IServiceProvider _services;
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ namespace BotSharp.Plugin.FileHandler.Functions;
|
|||
|
||||
public class GenerateImageFn : IFunctionCallback
|
||||
{
|
||||
public string Name => "generate_image";
|
||||
public string Name => "util-file-generate_image";
|
||||
public string Indication => "Generating image";
|
||||
|
||||
private readonly IServiceProvider _services;
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ namespace BotSharp.Plugin.FileHandler.Functions;
|
|||
|
||||
public class ReadImageFn : IFunctionCallback
|
||||
{
|
||||
public string Name => "read_image";
|
||||
public string Name => "util-file-read_image";
|
||||
public string Indication => "Reading images";
|
||||
|
||||
private readonly IServiceProvider _services;
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ namespace BotSharp.Plugin.FileHandler.Functions;
|
|||
|
||||
public class ReadPdfFn : IFunctionCallback
|
||||
{
|
||||
public string Name => "read_pdf";
|
||||
public string Name => "util-file-read_pdf";
|
||||
public string Indication => "Reading pdf";
|
||||
|
||||
private readonly IServiceProvider _services;
|
||||
|
|
|
|||
|
|
@ -2,10 +2,10 @@ namespace BotSharp.Plugin.FileHandler.Hooks;
|
|||
|
||||
public class FileHandlerUtilityHook : IAgentUtilityHook
|
||||
{
|
||||
private const string READ_IMAGE_FN = "read_image";
|
||||
private const string READ_PDF_FN = "read_pdf";
|
||||
private const string GENERATE_IMAGE_FN = "generate_image";
|
||||
private const string EDIT_IMAGE_FN = "edit_image";
|
||||
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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,14 +0,0 @@
|
|||
{
|
||||
"name": "read_image",
|
||||
"description": "If the user's request is related to analyzing images, you can call this function to analyze images.",
|
||||
"parameters": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"user_request": {
|
||||
"type": "string",
|
||||
"description": "The request posted by user, which is related to analyzing requested images. User can request for multiple images to process at one time."
|
||||
}
|
||||
},
|
||||
"required": [ "user_request" ]
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"name": "edit_image",
|
||||
"name": "util-file-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",
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"name": "generate_image",
|
||||
"name": "util-file-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",
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"name": "util-file-read_image",
|
||||
"description": "If the user's request is related to analyzing images, you can call this function to analyze images.",
|
||||
"parameters": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"user_request": {
|
||||
"type": "string",
|
||||
"description": "The request posted by user, which is related to analyzing requested images. User can request for multiple images to process at one time."
|
||||
}
|
||||
},
|
||||
"required": [ "user_request" ]
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"name": "read_pdf",
|
||||
"name": "util-file-read_pdf",
|
||||
"description": "If the user's request is related to analyzing pdf files, you can call this function to analyze pdf.",
|
||||
"parameters": {
|
||||
"type": "object",
|
||||
|
|
@ -1 +0,0 @@
|
|||
Please call edit_image if user wants to edit or change an image in the conversation.
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
** Please call generate_image if user wants you to provide or generate an image or picture.
|
||||
** If user does not generate image explicitly, please do not call generate_image.
|
||||
|
|
@ -1 +0,0 @@
|
|||
Please call function read_image if user wants to describe an image or images.
|
||||
|
|
@ -1 +0,0 @@
|
|||
Please call function read_pdf if user wants to describe an pdf file or pdf files.
|
||||
|
|
@ -0,0 +1 @@
|
|||
Please call util-file-edit_image if user wants to edit or change an image in the conversation.
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
** Please call util-file-generate_image if user wants you to provide or generate an image or picture.
|
||||
** If user does not generate image explicitly, please do not call generate_image.
|
||||
|
|
@ -0,0 +1 @@
|
|||
Please call function util-file-read_image if user wants to describe an image or images.
|
||||
|
|
@ -0,0 +1 @@
|
|||
Please call function util-file-read_pdf if user wants to describe an pdf file or pdf files.
|
||||
|
|
@ -11,11 +11,11 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Remove="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\functions\handle_http_request.json" />
|
||||
<None Remove="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\templates\handle_http_request.fn.liquid" />
|
||||
<None Remove="data\agents\87c458fc-ec5f-40ae-8ed6-05dda8a07523\agent.json" />
|
||||
<None Remove="data\agents\87c458fc-ec5f-40ae-8ed6-05dda8a07523\functions.json" />
|
||||
<None Remove="data\agents\87c458fc-ec5f-40ae-8ed6-05dda8a07523\instructions\instruction.liquid" />
|
||||
<None Remove="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\functions\util-http-handle_http_request.json" />
|
||||
<None Remove="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\templates\util-http-handle_http_request.fn.liquid" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
@ -25,10 +25,10 @@
|
|||
<Content Include="data\agents\87c458fc-ec5f-40ae-8ed6-05dda8a07523\instructions\instruction.liquid">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\functions\handle_http_request.json">
|
||||
<Content Include="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\functions\util-http-handle_http_request.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\templates\handle_http_request.fn.liquid">
|
||||
<Content Include="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\templates\util-http-handle_http_request.fn.liquid">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
|
|
|
|||
|
|
@ -2,5 +2,5 @@ namespace BotSharp.Plugin.HttpHandler.Enums;
|
|||
|
||||
public class UtilityName
|
||||
{
|
||||
public const string HttpHandler = "http-handler";
|
||||
public const string HttpHandler = "http.http-handler";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ namespace BotSharp.Plugin.HttpHandler.Functions;
|
|||
|
||||
public class HandleHttpRequestFn : IFunctionCallback
|
||||
{
|
||||
public string Name => "handle_http_request";
|
||||
public string Name => "util-http-handle_http_request";
|
||||
public string Indication => "Handling http request";
|
||||
|
||||
private readonly IServiceProvider _services;
|
||||
|
|
|
|||
|
|
@ -4,7 +4,8 @@ namespace BotSharp.Plugin.HttpHandler.Hooks;
|
|||
|
||||
public class HttpHandlerUtilityHook : IAgentUtilityHook
|
||||
{
|
||||
private static string HTTP_HANDLER_FN = "handle_http_request";
|
||||
private static string PREFIX = "util-http-";
|
||||
private static string HTTP_HANDLER_FN = $"{PREFIX}handle_http_request";
|
||||
|
||||
public void AddUtilities(List<AgentUtility> utilities)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"name": "handle_http_request",
|
||||
"name": "util-http-handle_http_request",
|
||||
"description": "If the user requests to send an http request, you need to capture the http method and request content, and then call this function to send the http request.",
|
||||
"parameters": {
|
||||
"type": "object",
|
||||
|
|
@ -1 +0,0 @@
|
|||
Please call handle_http_request if user wants to send an http request.
|
||||
|
|
@ -0,0 +1 @@
|
|||
Please call util-http-handle_http_request if user wants to send an http request.
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>$(TargetFramework)</TargetFramework>
|
||||
|
|
@ -23,7 +23,8 @@
|
|||
<None Remove="data\agents\01acc3e5-0af7-49e6-ad7a-a760bd12dc40\instructions\instruction.liquid" />
|
||||
<None Remove="data\agents\01acc3e5-0af7-49e6-ad7a-a760bd12dc40\templates\knowledge.generation.plain.liquid" />
|
||||
<None Remove="data\agents\01acc3e5-0af7-49e6-ad7a-a760bd12dc40\templates\knowledge.generation.refine.liquid" />
|
||||
<None Remove="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\templates\knowledge_retrieval.fn.liquid" />
|
||||
<None Remove="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\functions\util-knowledge-knowledge_retrieval.json" />
|
||||
<None Remove="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\templates\util-knowledge-knowledge_retrieval.fn.liquid" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
@ -45,10 +46,10 @@
|
|||
<Content Include="data\agents\01acc3e5-0af7-49e6-ad7a-a760bd12dc40\templates\knowledge.generation.plain.liquid">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\functions\knowledge_retrieval.json">
|
||||
<Content Include="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\functions\util-knowledge-knowledge_retrieval.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\templates\knowledge_retrieval.fn.liquid">
|
||||
<Content Include="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\templates\util-knowledge-knowledge_retrieval.fn.liquid">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
|
|
|
|||
|
|
@ -2,5 +2,5 @@ namespace BotSharp.Plugin.KnowledgeBase.Enum;
|
|||
|
||||
public class UtilityName
|
||||
{
|
||||
public const string KnowledgeRetrieval = "knowledge-retrieval";
|
||||
public const string KnowledgeRetrieval = "knowledge.knowledge-retrieval";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ namespace BotSharp.Plugin.KnowledgeBase.Functions;
|
|||
|
||||
public class KnowledgeRetrievalFn : IFunctionCallback
|
||||
{
|
||||
public string Name => "knowledge_retrieval";
|
||||
public string Name => "util-knowledge-knowledge_retrieval";
|
||||
|
||||
public string Indication => "searching my brain";
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,8 @@ namespace BotSharp.Plugin.KnowledgeBase.Hooks;
|
|||
|
||||
public class KnowledgeBaseUtilityHook : IAgentUtilityHook
|
||||
{
|
||||
private const string KNOWLEDGE_RETRIEVAL_FN = "knowledge_retrieval";
|
||||
private static string PREFIX = "util-knowledge-";
|
||||
private static string KNOWLEDGE_RETRIEVAL_FN = $"{PREFIX}knowledge_retrieval";
|
||||
|
||||
public void AddUtilities(List<AgentUtility> utilities)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"name": "knowledge_retrieval",
|
||||
"name": "util-knowledge-knowledge_retrieval",
|
||||
"description": "Retrieve related domain knowledge to handle user request",
|
||||
"parameters": {
|
||||
"type": "object",
|
||||
|
|
@ -1,3 +1,3 @@
|
|||
Call function knowledge_retrieval to retrieve related domain knowledge to handle user request.
|
||||
Call function util-knowledge-knowledge_retrieval to retrieve related domain knowledge to handle user request.
|
||||
You must retrieve existing KnowledgeBase to get prerequisite informations before you writing SQL query;
|
||||
You must retrieve existing API specification from KnowledgeBase before calling a Web API;
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>$(TargetFramework)</TargetFramework>
|
||||
|
|
@ -19,10 +19,9 @@
|
|||
<None Remove="data\agents\282a7128-69a1-44b0-878c-a9159b88f3b9\templates\two_stage.2nd.plan.liquid" />
|
||||
<None Remove="data\agents\282a7128-69a1-44b0-878c-a9159b88f3b9\templates\two_stage.next.liquid" />
|
||||
<None Remove="data\agents\282a7128-69a1-44b0-878c-a9159b88f3b9\templates\two_stage.summarize.liquid" />
|
||||
<None Remove="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\templates\planner_prompt.two_stage.1st.plan.liquid" />
|
||||
<None Remove="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\templates\plan_primary_stage.fn.liquid" />
|
||||
<None Remove="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\templates\plan_secondary_stage.fn.liquid" />
|
||||
<None Remove="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\templates\plan_summary.fn.liquid" />
|
||||
<None Remove="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\templates\util-planner-plan_secondary_stage.fn.liquid" />
|
||||
<None Remove="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\templates\util-planner-plan_primary_stage.fn.liquid" />
|
||||
<None Remove="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\templates\util-planner-plan_summary.fn.liquid" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
@ -53,13 +52,13 @@
|
|||
<Content Include="data\agents\282a7128-69a1-44b0-878c-a9159b88f3b9\templates\two_stage.1st.plan.liquid">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\templates\plan_secondary_stage.fn.liquid">
|
||||
<Content Include="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\templates\util-planner-plan_secondary_stage.fn.liquid">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\templates\plan_primary_stage.fn.liquid">
|
||||
<Content Include="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\templates\util-planner-plan_primary_stage.fn.liquid">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\templates\plan_summary.fn.liquid">
|
||||
<Content Include="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\templates\util-planner-plan_summary.fn.liquid">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
|
|
|
|||
|
|
@ -2,5 +2,5 @@ namespace BotSharp.Plugin.Planner.Enums;
|
|||
|
||||
public class UtilityName
|
||||
{
|
||||
public const string TwoStagePlanner = "two-stage-planner";
|
||||
public const string TwoStagePlanner = "planner.two-stage-planner";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,12 +17,6 @@
|
|||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Remove="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\functions\sql_select.json" />
|
||||
<None Remove="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\functions\sql_table_definition.json" />
|
||||
<None Remove="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\functions\verify_dictionary_term.json" />
|
||||
<None Remove="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\templates\sql_executor.fn.liquid" />
|
||||
<None Remove="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\templates\sql_table_definition.fn.liquid" />
|
||||
<None Remove="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\templates\verify_dictionary_term.fn.liquid" />
|
||||
<None Remove="data\agents\beda4c12-e1ec-4b4b-b328-3df4a6687c4f\agent.json" />
|
||||
<None Remove="data\agents\beda4c12-e1ec-4b4b-b328-3df4a6687c4f\functions\execute_sql.json" />
|
||||
<None Remove="data\agents\beda4c12-e1ec-4b4b-b328-3df4a6687c4f\functions\lookup_dictionary.json" />
|
||||
|
|
@ -36,22 +30,29 @@
|
|||
<None Remove="data\agents\beda4c12-e1ec-4b4b-b328-3df4a6687c4f\templates\query_result_formatting.liquid" />
|
||||
<None Remove="data\agents\beda4c12-e1ec-4b4b-b328-3df4a6687c4f\templates\render_buttons.liquid" />
|
||||
<None Remove="data\agents\beda4c12-e1ec-4b4b-b328-3df4a6687c4f\templates\sql_statement_correctness.liquid" />
|
||||
|
||||
<None Remove="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\functions\util-db-sql_table_definition.json" />
|
||||
<None Remove="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\templates\util-db-sql_table_definition.fn.liquid" />
|
||||
<None Remove="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\functions\util-db-verify_dictionary_term.json" />
|
||||
<None Remove="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\templates\util-db-verify_dictionary_term.fn.liquid" />
|
||||
<None Remove="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\templates\util-db-sql_executor.fn.liquid" />
|
||||
<None Remove="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\functions\util-db-sql_select.json" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Include="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\functions\sql_table_definition.json">
|
||||
<Content Include="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\functions\util-db-sql_table_definition.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\functions\verify_dictionary_term.json">
|
||||
<Content Include="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\functions\util-db-verify_dictionary_term.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\templates\verify_dictionary_term.fn.liquid">
|
||||
<Content Include="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\templates\util-db-verify_dictionary_term.fn.liquid">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="data\agents\beda4c12-e1ec-4b4b-b328-3df4a6687c4f\functions\sql_table_definition.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\templates\sql_table_definition.fn.liquid">
|
||||
<Content Include="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\templates\util-db-sql_table_definition.fn.liquid">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="data\agents\beda4c12-e1ec-4b4b-b328-3df4a6687c4f\agent.json">
|
||||
|
|
@ -69,10 +70,10 @@
|
|||
<Content Include="data\agents\beda4c12-e1ec-4b4b-b328-3df4a6687c4f\functions\sql_select.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\functions\sql_select.json">
|
||||
<Content Include="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\functions\util-db-sql_select.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\templates\sql_executor.fn.liquid">
|
||||
<Content Include="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\templates\util-db-sql_executor.fn.liquid">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="data\agents\beda4c12-e1ec-4b4b-b328-3df4a6687c4f\templates\database.summarize.redshift.liquid">
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ namespace BotSharp.Plugin.SqlDriver.Enum;
|
|||
|
||||
public class UtilityName
|
||||
{
|
||||
public const string SqlExecutor = "sql-executor";
|
||||
public const string SqlDictionaryLookup = "sql-dictionary-lookup";
|
||||
public const string SqlTableDefinition = "sql-table-definition";
|
||||
public const string SqlExecutor = "db.sql-executor";
|
||||
public const string SqlDictionaryLookup = "db.sql-dictionary-lookup";
|
||||
public const string SqlTableDefinition = "db.sql-table-definition";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,9 +2,11 @@ namespace BotSharp.Plugin.SqlDriver.Hooks;
|
|||
|
||||
public class SqlUtilityHook : IAgentUtilityHook
|
||||
{
|
||||
private const string SQL_TABLE_DEFINITION_FN = "sql_table_definition";
|
||||
private const string VERIFY_DICTIONARY_TERM_FN = "verify_dictionary_term";
|
||||
private const string SQL_SELECT_FN = "sql_select";
|
||||
private const string PREFIX = "util-db-";
|
||||
private const string SQL_TABLE_DEFINITION_FN = $"{PREFIX}sql_table_definition";
|
||||
private const string VERIFY_DICTIONARY_TERM_FN = $"{PREFIX}verify_dictionary_term";
|
||||
private const string SQL_SELECT_FN = $"{PREFIX}sql_select";
|
||||
private const string SQL_EXECUTOR_FN = $"{PREFIX}sql_executor";
|
||||
|
||||
public void AddUtilities(List<AgentUtility> utilities)
|
||||
{
|
||||
|
|
@ -26,7 +28,7 @@ public class SqlUtilityHook : IAgentUtilityHook
|
|||
{
|
||||
Name = UtilityName.SqlExecutor,
|
||||
Functions = [new(SQL_SELECT_FN), new(SQL_TABLE_DEFINITION_FN)],
|
||||
Templates = [new($"sql_executor.fn")]
|
||||
Templates = [new($"{SQL_EXECUTOR_FN}.fn")]
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,168 @@
|
|||
using Microsoft.Data.SqlClient;
|
||||
using MySqlConnector;
|
||||
using Npgsql;
|
||||
|
||||
namespace BotSharp.Plugin.SqlDriver.UtilFunctions;
|
||||
|
||||
public class GetTableDefinitionFn : IFunctionCallback
|
||||
{
|
||||
public string Name => "util-db-sql_table_definition";
|
||||
public string Indication => "Obtain the relevant data structure definitions.";
|
||||
private readonly IServiceProvider _services;
|
||||
private readonly ILogger<GetTableDefinitionFn> _logger;
|
||||
|
||||
public GetTableDefinitionFn(
|
||||
IServiceProvider services,
|
||||
ILogger<GetTableDefinitionFn> logger)
|
||||
{
|
||||
_services = services;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public async Task<bool> Execute(RoleDialogModel message)
|
||||
{
|
||||
var args = JsonSerializer.Deserialize<SqlStatement>(message.FunctionArgs);
|
||||
var tables = args.Tables;
|
||||
var agentService = _services.GetRequiredService<IAgentService>();
|
||||
var dbHook = _services.GetRequiredService<ISqlDriverHook>();
|
||||
var dbType = dbHook.GetDatabaseType(message);
|
||||
|
||||
// Get table DDL from database
|
||||
var tableDdls = dbType switch
|
||||
{
|
||||
"mysql" => GetDdlFromMySql(tables),
|
||||
"sqlserver" => GetDdlFromSqlServer(tables),
|
||||
"redshift" => GetDdlFromRedshift(tables),
|
||||
_ => throw new NotImplementedException($"Database type {dbType} is not supported.")
|
||||
};
|
||||
|
||||
message.Content = string.Join("\r\n\r\n", tableDdls);
|
||||
return true;
|
||||
}
|
||||
|
||||
private List<string> GetDdlFromMySql(string[] tables)
|
||||
{
|
||||
var settings = _services.GetRequiredService<SqlDriverSetting>();
|
||||
var tableDdls = new List<string>();
|
||||
using var connection = new MySqlConnection(settings.MySqlMetaConnectionString ?? settings.MySqlConnectionString);
|
||||
connection.Open();
|
||||
|
||||
foreach (var table in tables)
|
||||
{
|
||||
try
|
||||
{
|
||||
var escapedTableName = MySqlHelper.EscapeString(table);
|
||||
var sql = $"SHOW CREATE TABLE `{escapedTableName}`";
|
||||
|
||||
using var command = new MySqlCommand(sql, connection);
|
||||
using var reader = command.ExecuteReader();
|
||||
if (reader.Read())
|
||||
{
|
||||
var result = reader.GetString(1);
|
||||
tableDdls.Add(result);
|
||||
}
|
||||
|
||||
reader.Close();
|
||||
command.Dispose();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogWarning($"Error when getting ddl statement of table {table}. {ex.Message}\r\n{ex.InnerException}");
|
||||
}
|
||||
}
|
||||
|
||||
connection.Close();
|
||||
return tableDdls;
|
||||
}
|
||||
|
||||
private List<string> GetDdlFromSqlServer(string[] tables)
|
||||
{
|
||||
var settings = _services.GetRequiredService<SqlDriverSetting>();
|
||||
var tableDdls = new List<string>();
|
||||
using var connection = new SqlConnection(settings.SqlServerExecutionConnectionString ?? settings.SqlServerConnectionString);
|
||||
connection.Open();
|
||||
|
||||
foreach (var table in tables)
|
||||
{
|
||||
try
|
||||
{
|
||||
var sql = @$"DECLARE @TableName NVARCHAR(128) = '{table}';
|
||||
DECLARE @SQL NVARCHAR(MAX) = 'CREATE TABLE ' + @TableName + ' (';
|
||||
|
||||
SELECT @SQL = @SQL + '
|
||||
' + COLUMN_NAME + ' ' +
|
||||
DATA_TYPE +
|
||||
CASE
|
||||
WHEN CHARACTER_MAXIMUM_LENGTH IS NOT NULL AND DATA_TYPE LIKE '%char%'
|
||||
THEN '(' + CAST(CHARACTER_MAXIMUM_LENGTH AS VARCHAR(10)) + ')'
|
||||
WHEN DATA_TYPE IN ('decimal', 'numeric')
|
||||
THEN '(' + CAST(NUMERIC_PRECISION AS VARCHAR(10)) + ',' + CAST(NUMERIC_SCALE AS VARCHAR(10)) + ')'
|
||||
ELSE ''
|
||||
END + ' ' +
|
||||
CASE WHEN IS_NULLABLE = 'NO' THEN 'NOT NULL' ELSE 'NULL' END + ','
|
||||
FROM INFORMATION_SCHEMA.COLUMNS
|
||||
WHERE TABLE_NAME = @TableName
|
||||
ORDER BY ORDINAL_POSITION;
|
||||
|
||||
-- Remove the last comma and add closing parenthesis
|
||||
SET @SQL = LEFT(@SQL, LEN(@SQL) - 1) + ');';
|
||||
|
||||
SELECT @SQL;";
|
||||
|
||||
using var command = new SqlCommand(sql, connection);
|
||||
using var reader = command.ExecuteReader();
|
||||
if (reader.Read())
|
||||
{
|
||||
var result = reader.GetString(0);
|
||||
tableDdls.Add(result);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogWarning($"Error when getting ddl statement of table {table}. {ex.Message}\r\n{ex.InnerException}");
|
||||
}
|
||||
}
|
||||
|
||||
connection.Close();
|
||||
return tableDdls;
|
||||
}
|
||||
|
||||
private List<string> GetDdlFromRedshift(string[] tables)
|
||||
{
|
||||
var settings = _services.GetRequiredService<SqlDriverSetting>();
|
||||
var tableDdls = new List<string>();
|
||||
var schemas = "'onebi_hour','onebi_day'";
|
||||
using var connection = new NpgsqlConnection(settings.RedshiftConnectionString);
|
||||
connection.Open();
|
||||
|
||||
foreach (var table in tables)
|
||||
{
|
||||
try
|
||||
{
|
||||
var sql = $"SELECT columnname, external_type, columnnum FROM svv_external_columns WHERE schemaname in ({schemas}) AND tablename = '{table}';";
|
||||
|
||||
using var command = new NpgsqlCommand(sql, connection);
|
||||
using var reader = command.ExecuteReader();
|
||||
var ddl = $"Table {table} contains below fields: \r\n";
|
||||
while (reader.Read())
|
||||
{
|
||||
/*var result = reader.GetString(0);
|
||||
tableDdls.Add(result);*/
|
||||
var columnName = reader.GetString(0);
|
||||
var dataType = reader.GetString(1);
|
||||
ddl += $"{columnName} {dataType}\n";
|
||||
}
|
||||
tableDdls.Add(ddl);
|
||||
|
||||
reader.Close();
|
||||
command.Dispose();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogWarning($"Error when getting ddl statement of table {table}. {ex.Message}\r\n{ex.InnerException}");
|
||||
}
|
||||
}
|
||||
connection.Close();
|
||||
return tableDdls;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,88 @@
|
|||
using Microsoft.Data.SqlClient;
|
||||
using MySqlConnector;
|
||||
using Npgsql;
|
||||
using static Dapper.SqlMapper;
|
||||
|
||||
namespace BotSharp.Plugin.SqlDriver.UtilFunctions;
|
||||
|
||||
public class SqlSelect : IFunctionCallback
|
||||
{
|
||||
public string Name => "util-db-sql_select";
|
||||
private readonly IServiceProvider _services;
|
||||
|
||||
public SqlSelect(IServiceProvider services)
|
||||
{
|
||||
_services = services;
|
||||
}
|
||||
|
||||
public async Task<bool> Execute(RoleDialogModel message)
|
||||
{
|
||||
var args = JsonSerializer.Deserialize<SqlStatement>(message.FunctionArgs);
|
||||
|
||||
if (args.GeneratedWithoutTableDefinition)
|
||||
{
|
||||
message.Content = $"Get the table definition first.";
|
||||
return false;
|
||||
}
|
||||
|
||||
// check if need to instantely
|
||||
var dbHook = _services.GetRequiredService<ISqlDriverHook>();
|
||||
var dbType = dbHook.GetDatabaseType(message);
|
||||
|
||||
var result = dbType switch
|
||||
{
|
||||
"mysql" => RunQueryInMySql(args),
|
||||
"sqlserver" => RunQueryInSqlServer(args),
|
||||
"redshift" => RunQueryInRedshift(args),
|
||||
_ => throw new NotImplementedException($"Database type {dbType} is not supported.")
|
||||
};
|
||||
|
||||
if (result == null)
|
||||
{
|
||||
message.Content = "Record not found";
|
||||
}
|
||||
else
|
||||
{
|
||||
message.Content = JsonSerializer.Serialize(result);
|
||||
args.Return.Value = message.Content;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private IEnumerable<dynamic> RunQueryInMySql(SqlStatement args)
|
||||
{
|
||||
var settings = _services.GetRequiredService<SqlDriverSetting>();
|
||||
using var connection = new MySqlConnection(settings.MySqlExecutionConnectionString);
|
||||
var dictionary = new Dictionary<string, object>();
|
||||
foreach (var p in args.Parameters)
|
||||
{
|
||||
dictionary["@" + p.Name] = p.Value;
|
||||
}
|
||||
return connection.Query(args.Statement, dictionary);
|
||||
}
|
||||
|
||||
private IEnumerable<dynamic> RunQueryInSqlServer(SqlStatement args)
|
||||
{
|
||||
var settings = _services.GetRequiredService<SqlDriverSetting>();
|
||||
using var connection = new SqlConnection(settings.SqlServerExecutionConnectionString ?? settings.SqlServerConnectionString);
|
||||
var dictionary = new Dictionary<string, object>();
|
||||
foreach (var p in args.Parameters)
|
||||
{
|
||||
dictionary["@" + p.Name] = p.Value;
|
||||
}
|
||||
return connection.Query(args.Statement, dictionary);
|
||||
}
|
||||
|
||||
private IEnumerable<dynamic> RunQueryInRedshift(SqlStatement args)
|
||||
{
|
||||
var settings = _services.GetRequiredService<SqlDriverSetting>();
|
||||
using var connection = new NpgsqlConnection(settings.RedshiftConnectionString);
|
||||
var dictionary = new Dictionary<string, object>();
|
||||
foreach (var p in args.Parameters)
|
||||
{
|
||||
dictionary["@" + p.Name] = p.Value;
|
||||
}
|
||||
return connection.Query(args.Statement, dictionary);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,130 @@
|
|||
using BotSharp.Core.Infrastructures;
|
||||
using MySqlConnector;
|
||||
using static Dapper.SqlMapper;
|
||||
|
||||
namespace BotSharp.Plugin.SqlDriver.UtilFunctions;
|
||||
|
||||
public class VerifyDictionaryTerm : IFunctionCallback
|
||||
{
|
||||
public string Name => "util-db-verify_dictionary_term";
|
||||
public string Indication => "Verifying dictionary term";
|
||||
|
||||
|
||||
private readonly IServiceProvider _services;
|
||||
|
||||
public VerifyDictionaryTerm(IServiceProvider services)
|
||||
{
|
||||
_services = services;
|
||||
}
|
||||
|
||||
public async Task<bool> Execute(RoleDialogModel message)
|
||||
{
|
||||
var args = JsonSerializer.Deserialize<LookupDictionary>(message.FunctionArgs);
|
||||
|
||||
// get table DDL
|
||||
var fn = _services.GetRequiredService<IRoutingService>();
|
||||
var msgCopy = RoleDialogModel.From(message);
|
||||
await fn.InvokeFunction("sql_table_definition", msgCopy);
|
||||
|
||||
// refine SQL
|
||||
var agentService = _services.GetRequiredService<IAgentService>();
|
||||
var currentAgent = await agentService.LoadAgent(message.CurrentAgentId);
|
||||
var dictionarySqlPrompt = await GetDictionarySQLPrompt(args.SqlStatement, msgCopy.Content);
|
||||
var agent = new Agent
|
||||
{
|
||||
Id = message.CurrentAgentId ?? string.Empty,
|
||||
Name = "sqlDriver_DictionarySearch",
|
||||
Instruction = dictionarySqlPrompt,
|
||||
TemplateDict = new Dictionary<string, object>(),
|
||||
LlmConfig = currentAgent.LlmConfig
|
||||
};
|
||||
|
||||
var response = await GetAiResponse(agent);
|
||||
args = response.Content.JsonContent<LookupDictionary>();
|
||||
|
||||
// check if need to instantely
|
||||
IEnumerable<dynamic>? result = null;
|
||||
if (!string.IsNullOrWhiteSpace(args.SqlStatement))
|
||||
{
|
||||
var settings = _services.GetRequiredService<SqlDriverSetting>();
|
||||
using var connection = new MySqlConnection(settings.MySqlExecutionConnectionString);
|
||||
result = connection.Query(args.SqlStatement);
|
||||
}
|
||||
|
||||
if (result.IsNullOrEmpty())
|
||||
{
|
||||
message.Content = "Record not found";
|
||||
}
|
||||
else
|
||||
{
|
||||
message.Content = JsonSerializer.Serialize(result);
|
||||
}
|
||||
|
||||
var states = _services.GetRequiredService<IConversationStateService>();
|
||||
var dictionaryItems = states.GetState("dictionary_items", "");
|
||||
var newItem = BuildDictionaryItem(args.Table, args.Reason, message.Content);
|
||||
dictionaryItems += !string.IsNullOrWhiteSpace(newItem) ? $"\r\n{newItem}\r\n" : string.Empty;
|
||||
states.SetState("dictionary_items", dictionaryItems);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private async Task<string> GetDictionarySQLPrompt(string originalSql, string tableStructure)
|
||||
{
|
||||
var agentService = _services.GetRequiredService<IAgentService>();
|
||||
var render = _services.GetRequiredService<ITemplateRender>();
|
||||
var knowledgeHooks = _services.GetServices<IKnowledgeHook>();
|
||||
|
||||
var agent = await agentService.GetAgent(BuiltInAgentId.SqlDriver);
|
||||
var template = agent.Templates.FirstOrDefault(x => x.Name == "database.dictionary.sql")?.Content ?? string.Empty;
|
||||
var responseFormat = JsonSerializer.Serialize(new LookupDictionary{ });
|
||||
|
||||
return render.Render(template, new Dictionary<string, object>
|
||||
{
|
||||
{ "original_sql", originalSql },
|
||||
{ "table_structure", tableStructure },
|
||||
{ "response_format", responseFormat }
|
||||
});
|
||||
}
|
||||
|
||||
private async Task<RoleDialogModel> GetAiResponse(Agent agent)
|
||||
{
|
||||
var text = "Check and correct the SQL statement.";
|
||||
var message = new RoleDialogModel(AgentRole.User, text);
|
||||
|
||||
var completion = CompletionProvider.GetChatCompletion(_services,
|
||||
provider: agent.LlmConfig.Provider,
|
||||
model: agent.LlmConfig.Model);
|
||||
|
||||
return await completion.GetChatCompletions(agent, new List<RoleDialogModel> { message });
|
||||
}
|
||||
|
||||
private string BuildDictionaryItem(string? table, string? reason, string? result)
|
||||
{
|
||||
var res = string.Empty;
|
||||
if (!string.IsNullOrWhiteSpace(table))
|
||||
{
|
||||
res += $"Table: {table}";
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(reason))
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(res))
|
||||
{
|
||||
res += "\r\n";
|
||||
}
|
||||
res += $"Reason: {reason}";
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(result))
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(res))
|
||||
{
|
||||
res += "\r\n";
|
||||
}
|
||||
res += $"Result: {result}";
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"name": "sql_select",
|
||||
"name": "util-db-sql_select",
|
||||
"description": "Get the specific value from table",
|
||||
"parameters": {
|
||||
"type": "object",
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"name": "sql_table_definition",
|
||||
"name": "util-db-sql_table_definition",
|
||||
"description": "Get table structure from database by table name",
|
||||
"parameters": {
|
||||
"type": "object",
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"name": "verify_dictionary_term",
|
||||
"name": "util-db-verify_dictionary_term",
|
||||
"description": "Get id from dictionary table by keyword. Call this function only if need_lookup_dictionary is true, is_table_from_knowledge is true and is_insert is false. You can only query one table at a time. The table name must come from the global/domain knowledge.",
|
||||
"parameters": {
|
||||
"type": "object",
|
||||
|
|
@ -1 +0,0 @@
|
|||
Call sql_table_definition to get the table definition of the table.
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
You are connecting to {{ db_type }} database. You can run provided SQL statements by following {{ db_type }} rules.
|
||||
|
||||
Please call function sql_select if user wants to get or retrieve data from data tables.
|
||||
Please call function util-db-sql_select if user wants to get or retrieve data from data tables.
|
||||
If there are any parameters, please add them in the WHERE clause, each of which starts with "@".
|
||||
Avoid returning the entire record and only return the fields you need.
|
||||
For example, SELECT Id FROM table WHERE Id=@Id AND Name=@Name
|
||||
|
|
@ -0,0 +1 @@
|
|||
Call util-db-sql_table_definition to get the table definition of the table.
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
Rules to call verify_dictionary_term:
|
||||
Rules to call util-db-verify_dictionary_term:
|
||||
=====
|
||||
1. The table name must come from the planning in conversation.
|
||||
2. You must return the id and name/code for existing dictionary.
|
||||
|
|
@ -7,17 +7,17 @@
|
|||
<GeneratePackageOnBuild>$(GeneratePackageOnBuild)</GeneratePackageOnBuild>
|
||||
<OutputPath>$(SolutionDir)packages</OutputPath>
|
||||
</PropertyGroup>
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<None Remove="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\functions\twilio_outbound_phone_call.json" />
|
||||
<None Remove="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\templates\twilio_outbound_phone_call.fn.liquid" />
|
||||
<None Remove="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\functions\util-twilio-twilio_outbound_phone_call.json" />
|
||||
<None Remove="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\templates\util-twilio-twilio_outbound_phone_call.fn.liquid" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<Content Include="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\functions\twilio_outbound_phone_call.json">
|
||||
<Content Include="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\functions\util-twilio-twilio_outbound_phone_call.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\templates\twilio_outbound_phone_call.fn.liquid">
|
||||
<Content Include="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\templates\util-twilio-twilio_outbound_phone_call.fn.liquid">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
|
|
|
|||
|
|
@ -2,6 +2,6 @@ namespace BotSharp.Plugin.Twilio.OutboundPhoneCallHandler.Enums
|
|||
{
|
||||
public class UtilityName
|
||||
{
|
||||
public const string OutboundPhoneCall = "twilio-outbound-phone-call";
|
||||
public const string OutboundPhoneCall = "twilio.twilio-outbound-phone-call";
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ namespace BotSharp.Plugin.Twilio.OutboundPhoneCallHandler.Functions
|
|||
private readonly BotSharpOptions _options;
|
||||
private readonly TwilioSetting _twilioSetting;
|
||||
|
||||
public string Name => "twilio_outbound_phone_call";
|
||||
public string Name => "util-twilio-twilio_outbound_phone_call";
|
||||
public string Indication => "Dialing the number";
|
||||
|
||||
public HandleOutboundPhoneCallFn(
|
||||
|
|
|
|||
|
|
@ -5,14 +5,15 @@ namespace BotSharp.Plugin.Twilio.OutboundPhoneCallHandler.Hooks;
|
|||
|
||||
public class OutboundPhoneCallHandlerUtilityHook : IAgentUtilityHook
|
||||
{
|
||||
private static string OUTBOUND_PHONE_CALL_FN = "twilio_outbound_phone_call";
|
||||
private static string PREFIX = "util-twilio-";
|
||||
private static string OUTBOUND_PHONE_CALL_FN = $"{PREFIX}twilio_outbound_phone_call";
|
||||
|
||||
public void AddUtilities(List<AgentUtility> utilities)
|
||||
{
|
||||
var utility = new AgentUtility
|
||||
{
|
||||
Name = UtilityName.OutboundPhoneCall,
|
||||
Functions = [new(OUTBOUND_PHONE_CALL_FN)],
|
||||
Functions = [new($"{OUTBOUND_PHONE_CALL_FN}")],
|
||||
Templates = [new($"{OUTBOUND_PHONE_CALL_FN}.fn")]
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"name": "twilio_outbound_phone_call",
|
||||
"name": "util-twilio-twilio_outbound_phone_call",
|
||||
"description": "If the user wants to initiate a phone call, you need to capture the phone number and compose the message the users wants to send. Then call this function to make an outbound call via Twilio.",
|
||||
"parameters": {
|
||||
"type": "object",
|
||||
|
|
@ -1,2 +1,2 @@
|
|||
** Please take a look at the conversation and decide whether user wants to make an outbound call.
|
||||
** Please call handle_outbound_call if user wants to make an outbound call.
|
||||
** Please call util-twilio-twilio_outbound_phone_call if user wants to make an outbound call.
|
||||
Loading…
Reference in a new issue