Merge branch 'master' into sk/text-completion
This commit is contained in:
commit
83e3c38999
11
BotSharp.sln
11
BotSharp.sln
|
|
@ -67,6 +67,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BotSharp.Plugin.SemanticKer
|
|||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BotSharp.Plugin.SemanticKernel.UnitTests", "tests\BotSharp.Plugin.SemanticKernel.UnitTests\BotSharp.Plugin.SemanticKernel.UnitTests.csproj", "{BC57D428-A1A4-4D38-A2D0-AC6CA943F247}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BotSharp.Plugin.Twilio", "src\Plugins\BotSharp.Plugin.Twilio\BotSharp.Plugin.Twilio.csproj", "{E627F1E3-BE03-443A-83A2-86A855A278EB}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
|
|
@ -243,6 +245,14 @@ Global
|
|||
{BC57D428-A1A4-4D38-A2D0-AC6CA943F247}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{BC57D428-A1A4-4D38-A2D0-AC6CA943F247}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{BC57D428-A1A4-4D38-A2D0-AC6CA943F247}.Release|x64.Build.0 = Release|Any CPU
|
||||
{E627F1E3-BE03-443A-83A2-86A855A278EB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{E627F1E3-BE03-443A-83A2-86A855A278EB}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{E627F1E3-BE03-443A-83A2-86A855A278EB}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{E627F1E3-BE03-443A-83A2-86A855A278EB}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{E627F1E3-BE03-443A-83A2-86A855A278EB}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{E627F1E3-BE03-443A-83A2-86A855A278EB}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{E627F1E3-BE03-443A-83A2-86A855A278EB}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{E627F1E3-BE03-443A-83A2-86A855A278EB}.Release|x64.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
|
@ -276,6 +286,7 @@ Global
|
|||
{8BC29F8A-78D6-422C-B522-10687ADC38ED} = {D5293208-2BEF-42FC-A64C-5954F61720BA}
|
||||
{73EE2CD0-3B27-4F02-A67B-762CBDD740D0} = {D5293208-2BEF-42FC-A64C-5954F61720BA}
|
||||
{BC57D428-A1A4-4D38-A2D0-AC6CA943F247} = {32FAFFFE-A4CB-4FEE-BF7C-84518BBC6DCC}
|
||||
{E627F1E3-BE03-443A-83A2-86A855A278EB} = {64264688-0F5C-4AB0-8F2B-B59B717CCE00}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {A9969D89-C98B-40A5-A12B-FC87E55B3A19}
|
||||
|
|
|
|||
39
README.md
39
README.md
|
|
@ -24,7 +24,7 @@ It's written in C# running on .Net Core that is full cross-platform framework, t
|
|||
* Built-in multi-agents and conversation with state management.
|
||||
* Support multiple LLM Planning approaches to handle different tasks.
|
||||
* Built-in RAG related interfaces, Memeory based vector searching.
|
||||
* Support multiple LLM platforms (ChatGPT 3.5 / 4.0, PaLM 2, LLaMA 2).
|
||||
* Support multiple LLM platforms (ChatGPT 3.5 / 4.0, PaLM 2, LLaMA 2, HuggingFace).
|
||||
* Allow multiple agents with different responsibilities cooperate to complete complex tasks.
|
||||
* Build, test, evaluate and audit your LLM agent in one place.
|
||||
* Support different open source UI [Chatbot UI](src/Plugins/BotSharp.Plugin.ChatbotUI/Chatbot-UI.md), [HuggingChat UI](src/Plugins/BotSharp.Plugin.HuggingFace/HuggingChat-UI.md).
|
||||
|
|
@ -39,14 +39,39 @@ It's written in C# running on .Net Core that is full cross-platform framework, t
|
|||
```
|
||||
2. Run UI project, reference to [Chatbot UI](src/Plugins/BotSharp.Plugin.ChatbotUI/Chatbot-UI.md).
|
||||
|
||||
### Extension Libraries
|
||||
### Plugins
|
||||
|
||||
BotSharp uses component design, the kernel is kept to a minimum, and business functions are implemented by external components. The modular design also allows contributors to better participate.
|
||||
BotSharp uses component design, the kernel is kept to a minimum, and business functions are implemented by external components. The modular design also allows contributors to better participate. Below are the bulit-in plugins:
|
||||
|
||||
* Chatbot UI connector.
|
||||
* A channel module of BotSharp for Facebook Messenger.
|
||||
* A channel module of BotSharp for Tencent Wechat.
|
||||
* A channel module of BotSharp for Telegram.
|
||||
#### Data Storages
|
||||
- BotSharp.Plugin.MongoStorage
|
||||
|
||||
#### LLMs
|
||||
- BotSharp.Plugin.AzureOpenAI
|
||||
- BotSharp.Plugin.GoogleAI
|
||||
- BotSharp.Plugin.MetaAI
|
||||
- BotSharp.Plugin.HuggingFace
|
||||
- BotSharp.Plugin.LLamaSharp
|
||||
|
||||
#### Messaging / Channel
|
||||
- BotSharp.OpenAPI
|
||||
- BotSharp.Plugin.MetaMessenger
|
||||
- BotSharp.Plugin.Twilio
|
||||
- BotSharp.Plugin.WeChat
|
||||
|
||||
#### RAGS
|
||||
- BotSharp.Plugin.KnowledgeBase
|
||||
- BotSharp.Plugin.Qdrant
|
||||
|
||||
#### Visions
|
||||
- BotSharp.Plugin.PaddleSharp
|
||||
|
||||
#### Tools
|
||||
- BotSharp.Plugin.RoutingSpeeder
|
||||
- BotSharp.Plugin.PizzaBot
|
||||
|
||||
#### UIs
|
||||
- BotSharp.Plugin.ChatbotUI
|
||||
|
||||
### Documents
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,6 @@
|
|||
namespace BotSharp.Abstraction.Conversations;
|
||||
|
||||
public interface IConversationAttachmentService
|
||||
{
|
||||
string GetDirectory(string conversationId);
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
namespace BotSharp.Abstraction.Conversations.Models;
|
||||
|
||||
public class Attachment
|
||||
{
|
||||
public string ContentType { get; set; }
|
||||
|
||||
//
|
||||
// Summary:
|
||||
// Gets the raw Content-Disposition header of the uploaded file.
|
||||
public string ContentDisposition { get; set; }
|
||||
|
||||
//
|
||||
// Summary:
|
||||
// Gets the file length in bytes.
|
||||
public long Length { get; set; }
|
||||
|
||||
//
|
||||
// Summary:
|
||||
// Gets the file name from the Content-Disposition header.
|
||||
public string FileName { get; set; }
|
||||
}
|
||||
|
|
@ -1,4 +1,6 @@
|
|||
using BotSharp.Abstraction.Functions.Models;
|
||||
using BotSharp.Abstraction.Messaging.Models;
|
||||
using BotSharp.Abstraction.Messaging.Models.RichContent;
|
||||
|
||||
namespace BotSharp.Abstraction.Conversations.Models;
|
||||
|
||||
|
|
@ -35,7 +37,7 @@ public class RoleDialogModel : ITrackableMessage
|
|||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public object Data { get; set; }
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public object? RichContent { get; set; }
|
||||
public RichContent<IMessageTemplate>? RichContent { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Stop conversation completion
|
||||
|
|
|
|||
|
|
@ -12,6 +12,8 @@ public class FunctionCallFromLlm : RoutingArgs
|
|||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public JsonDocument? Arguments { get; set; }
|
||||
|
||||
public bool IsExecutionOnce { get; set; }
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
var route = string.IsNullOrEmpty(AgentName) ? "" : $"<Route to {AgentName.ToUpper()} because {Reason}>";
|
||||
|
|
|
|||
|
|
@ -0,0 +1,6 @@
|
|||
namespace BotSharp.Abstraction.Messaging.Models;
|
||||
|
||||
public interface IMessageTemplate
|
||||
{
|
||||
string Text { get; set; }
|
||||
}
|
||||
|
|
@ -9,7 +9,6 @@ namespace BotSharp.Abstraction.Messaging.Models.RichContent
|
|||
public string? Payload { get; set; }
|
||||
[JsonPropertyName("image_url")]
|
||||
public string? ImageUrl { get; set; }
|
||||
[JsonPropertyName("postback_url")]
|
||||
public string? PostBackUrl { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
|
||||
namespace BotSharp.Abstraction.Messaging.Models.RichContent
|
||||
{
|
||||
public class QuickReplyMessage : TextMessage
|
||||
public class QuickReplyMessage : IMessageTemplate
|
||||
{
|
||||
public string Text { get; set; } = string.Empty;
|
||||
|
||||
[JsonPropertyName("quick_replies")]
|
||||
public List<QuickReplyElement> QuickReplies { get; set; } = new List<QuickReplyElement>();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
namespace BotSharp.Abstraction.Messaging.Models.RichContent
|
||||
{
|
||||
public class RichContent<T>
|
||||
public class RichContent<T> where T : IMessageTemplate
|
||||
{
|
||||
public Recipient Recipient { get; set; } = new Recipient();
|
||||
/// <summary>
|
||||
|
|
|
|||
|
|
@ -1,9 +0,0 @@
|
|||
|
||||
namespace BotSharp.Abstraction.Messaging.Models.RichContent.Template
|
||||
{
|
||||
public class AttachmentTemplate<T>
|
||||
{
|
||||
public string Type => "template";
|
||||
public T Payload { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -1,8 +1,10 @@
|
|||
|
||||
namespace BotSharp.Abstraction.Messaging.Models.RichContent.Template
|
||||
{
|
||||
public class ButtonTemplate : TextMessage
|
||||
public class ButtonTemplate : IMessageTemplate
|
||||
{
|
||||
public string Text { get; set; } = string.Empty;
|
||||
|
||||
[JsonPropertyName("template_type")]
|
||||
public string TemplateType => "button";
|
||||
public List<ButtonElement> Buttons { get; set; } = new List<ButtonElement>();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,19 @@
|
|||
|
||||
namespace BotSharp.Abstraction.Messaging.Models.RichContent.Template
|
||||
{
|
||||
public class MultiSelectTemplate : IMessageTemplate
|
||||
{
|
||||
public string Text { get; set; } = string.Empty;
|
||||
|
||||
[JsonPropertyName("template_type")]
|
||||
public string TemplateType => "multi-select";
|
||||
public List<OptionElement> Options { get; set; } = new List<OptionElement>();
|
||||
}
|
||||
|
||||
public class OptionElement
|
||||
{
|
||||
public string Title { get; set; } = string.Empty;
|
||||
public string Type { get; set; } = string.Empty;
|
||||
public string? Payload { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace BotSharp.Abstraction.Messaging.Models.RichContent.Template
|
||||
{
|
||||
public class TemplateMessage<T>
|
||||
{
|
||||
public T Attachment { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -1,8 +1,7 @@
|
|||
|
||||
namespace BotSharp.Abstraction.Messaging.Models.RichContent
|
||||
{
|
||||
public class TextMessage
|
||||
namespace BotSharp.Abstraction.Messaging.Models.RichContent;
|
||||
|
||||
public class TextMessage : IMessageTemplate
|
||||
{
|
||||
public string Text { get; set; } = string.Empty;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
using System.Text.Json;
|
||||
|
||||
namespace BotSharp.Abstraction.Messaging.Models;
|
||||
|
||||
public class RichContentJsonConverter : JsonConverter<IMessageTemplate>
|
||||
{
|
||||
public override IMessageTemplate? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override void Write(Utf8JsonWriter writer, IMessageTemplate value, JsonSerializerOptions options)
|
||||
{
|
||||
JsonSerializer.Serialize(writer, value, value.GetType(), options);
|
||||
}
|
||||
}
|
||||
|
|
@ -56,7 +56,6 @@
|
|||
<PackageReference Include="Colorful.Console" Version="1.2.15" />
|
||||
<PackageReference Include="EntityFrameworkCore.BootKit" Version="6.2.1" />
|
||||
<PackageReference Include="Fluid.Core" Version="2.5.0" />
|
||||
<PackageReference Include="TensorFlow.Keras" Version="0.11.4" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
|||
|
|
@ -102,6 +102,8 @@ public static class BotSharpServiceCollectionExtensions
|
|||
services.AddScoped<IEvaluatingService, EvaluatingService>();
|
||||
services.AddScoped<IExecutionLogger, ExecutionLogger>();
|
||||
|
||||
services.AddScoped<IConversationAttachmentService, ConversationAttachmentService>();
|
||||
|
||||
return services;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,28 @@
|
|||
using BotSharp.Abstraction.Repositories;
|
||||
using System.IO;
|
||||
|
||||
namespace BotSharp.Core.Conversations.Services;
|
||||
|
||||
public class ConversationAttachmentService : IConversationAttachmentService
|
||||
{
|
||||
private readonly BotSharpDatabaseSettings _dbSettings;
|
||||
private readonly IServiceProvider _services;
|
||||
|
||||
public ConversationAttachmentService(
|
||||
BotSharpDatabaseSettings dbSettings,
|
||||
IServiceProvider services)
|
||||
{
|
||||
_dbSettings = dbSettings;
|
||||
_services = services;
|
||||
}
|
||||
|
||||
public string GetDirectory(string conversationId)
|
||||
{
|
||||
var dir = Path.Combine(_dbSettings.FileRepository, "conversations", conversationId, "attachments");
|
||||
if (!Directory.Exists(dir))
|
||||
{
|
||||
Directory.CreateDirectory(dir);
|
||||
}
|
||||
return dir;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
using BotSharp.Abstraction.Agents.Models;
|
||||
using BotSharp.Abstraction.Messaging.Models;
|
||||
using BotSharp.Abstraction.Messaging.Models.RichContent;
|
||||
using BotSharp.Abstraction.Routing;
|
||||
using BotSharp.Abstraction.Routing.Settings;
|
||||
|
|
@ -100,9 +101,17 @@ public partial class ConversationService
|
|||
_logger.LogInformation(text);
|
||||
#endif
|
||||
|
||||
// Process rich content
|
||||
if (response.RichContent != null &&
|
||||
response.RichContent is RichContent<IMessageTemplate> template &&
|
||||
string.IsNullOrEmpty(template.Message.Text))
|
||||
{
|
||||
template.Message.Text = response.Content;
|
||||
}
|
||||
|
||||
// Only read content from RichContent for UI rendering. When richContent is null, create a basic text message for richContent.
|
||||
var state = _services.GetRequiredService<IConversationStateService>();
|
||||
response.RichContent = response.RichContent ?? new RichContent<TextMessage>
|
||||
response.RichContent = response.RichContent ?? new RichContent<IMessageTemplate>
|
||||
{
|
||||
Recipient = new Recipient { Id = state.GetConversationId() },
|
||||
Message = new TextMessage { Text = response.Content }
|
||||
|
|
|
|||
|
|
@ -36,6 +36,10 @@ public class RouteToAgentRoutingHandler : RoutingHandlerBase, IRoutingHandler
|
|||
var ret = await function.Execute(message);
|
||||
|
||||
var agentId = context.GetCurrentAgentId();
|
||||
if (inst.IsExecutionOnce)
|
||||
{
|
||||
message.Content = inst.Question;
|
||||
}
|
||||
ret = await routing.InvokeAgent(agentId, _dialogs);
|
||||
|
||||
var response = _dialogs.Last();
|
||||
|
|
|
|||
|
|
@ -44,7 +44,9 @@ public partial class RoutingService : IRoutingService
|
|||
Function = "route_to_agent",
|
||||
Question = message.Content,
|
||||
Reason = message.Content,
|
||||
AgentName = agent.Name
|
||||
AgentName = agent.Name,
|
||||
OriginalAgent = agent.Name,
|
||||
IsExecutionOnce = true
|
||||
};
|
||||
|
||||
var result = await handler.Handle(this, inst, message);
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@ using BotSharp.Abstraction.ApiAdapters;
|
|||
using BotSharp.Abstraction.Conversations.Models;
|
||||
using BotSharp.Abstraction.Models;
|
||||
using BotSharp.OpenAPI.ViewModels.Conversations;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using System.Net.Http.Headers;
|
||||
|
||||
namespace BotSharp.OpenAPI.Controllers;
|
||||
|
||||
|
|
@ -78,4 +80,31 @@ public class ConversationController : ControllerBase, IApiAdapter
|
|||
|
||||
return response;
|
||||
}
|
||||
|
||||
[HttpPost("/conversation/{agentId}/{conversationId}/attachments")]
|
||||
public IActionResult UploadAttachments([FromRoute] string agentId,
|
||||
[FromRoute] string conversationId,
|
||||
IFormFile[] files)
|
||||
{
|
||||
if (files != null && files.Length > 0)
|
||||
{
|
||||
var attachmentService = _services.GetRequiredService<IConversationAttachmentService>();
|
||||
var dir = attachmentService.GetDirectory(conversationId);
|
||||
foreach (var file in files)
|
||||
{
|
||||
// Save the file, process it, etc.
|
||||
var fileName = ContentDispositionHeaderValue.Parse(file.ContentDisposition).FileName.Trim('"');
|
||||
var filePath = Path.Combine(dir, fileName);
|
||||
|
||||
using (var stream = new FileStream(filePath, FileMode.Create))
|
||||
{
|
||||
file.CopyTo(stream);
|
||||
}
|
||||
}
|
||||
|
||||
return Ok(new { message = "File uploaded successfully." });
|
||||
}
|
||||
|
||||
return BadRequest(new { message = "Invalid file." });
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,19 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<LangVersion>$(LangVersion)</LangVersion>
|
||||
<VersionPrefix>$(BotSharpVersion)</VersionPrefix>
|
||||
<GeneratePackageOnBuild>$(GeneratePackageOnBuild)</GeneratePackageOnBuild>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Twilio.AspNet.Common" Version="8.0.2" />
|
||||
<PackageReference Include="Twilio.AspNet.Core" Version="8.0.2" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\Infrastructure\BotSharp.Abstraction\BotSharp.Abstraction.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
@ -0,0 +1,115 @@
|
|||
using BotSharp.Abstraction.Conversations;
|
||||
using BotSharp.Plugin.Twilio.Settings;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using Twilio.AspNet.Common;
|
||||
using Twilio.AspNet.Core;
|
||||
using Twilio.TwiML;
|
||||
using Twilio.TwiML.Voice;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using BotSharp.Abstraction.Routing.Settings;
|
||||
using Twilio.Http;
|
||||
using Twilio.TwiML.Messaging;
|
||||
using BotSharp.Abstraction.Agents.Enums;
|
||||
using BotSharp.Abstraction.Conversations.Models;
|
||||
|
||||
namespace BotSharp.Plugin.Twilio.Controllers;
|
||||
|
||||
[AllowAnonymous]
|
||||
public class TwilioVoiceController : TwilioController
|
||||
{
|
||||
private readonly TwilioSetting _settings;
|
||||
private readonly IServiceProvider _services;
|
||||
|
||||
public TwilioVoiceController(TwilioSetting settings, IServiceProvider services)
|
||||
{
|
||||
_settings = settings;
|
||||
_services = services;
|
||||
}
|
||||
|
||||
[HttpPost("/twilio/voice/welcome")]
|
||||
public async Task<TwiMLResult> StartConversation(VoiceRequest request)
|
||||
{
|
||||
string sessionId = $"TwilioVoice_{request.CallSid}";
|
||||
var response = ReturnInstructions("Hello, how may I help you?");
|
||||
return TwiML(response);
|
||||
}
|
||||
|
||||
[HttpPost("/twilio/voice/{agentId}")]
|
||||
public async Task<TwiMLResult> ReceivedVoiceMessage([FromRoute] string agentId, VoiceRequest input)
|
||||
{
|
||||
string sessionId = $"TwilioVoice_{input.CallSid}";
|
||||
|
||||
var conv = _services.GetRequiredService<IConversationService>();
|
||||
conv.SetConversationId(sessionId, new List<string>
|
||||
{
|
||||
"channel=phone",
|
||||
$"calling_phone={input.DialCallSid}"
|
||||
});
|
||||
|
||||
VoiceResponse response = default;
|
||||
|
||||
var result = await conv.SendMessage(agentId, new RoleDialogModel(AgentRole.User, input.SpeechResult), async msg =>
|
||||
{
|
||||
response = HangUp(msg.Content);
|
||||
}, async functionExecuting =>
|
||||
{
|
||||
}, async functionExecuted =>
|
||||
{
|
||||
});
|
||||
|
||||
return TwiML(response);
|
||||
}
|
||||
|
||||
private VoiceResponse ReturnInstructions(string message)
|
||||
{
|
||||
var routingSetting = _services.GetRequiredService<RoutingSettings>();
|
||||
|
||||
var response = new VoiceResponse();
|
||||
var gather = new Gather()
|
||||
{
|
||||
Input = new List<Gather.InputEnum>()
|
||||
{
|
||||
Gather.InputEnum.Speech
|
||||
},
|
||||
Action = new Uri($"{_settings.CallbackHost}/twilio/voice/{routingSetting.RouterId}")
|
||||
};
|
||||
gather.Say(message);
|
||||
response.Append(gather);
|
||||
return response;
|
||||
}
|
||||
|
||||
private VoiceResponse HangUp(string message)
|
||||
{
|
||||
var response = new VoiceResponse();
|
||||
if (!string.IsNullOrEmpty(message))
|
||||
{
|
||||
response.Say(message);
|
||||
}
|
||||
response.Hangup();
|
||||
return response;
|
||||
}
|
||||
|
||||
private VoiceResponse HoldOn(int interval, string message = null)
|
||||
{
|
||||
var routingSetting = _services.GetRequiredService<RoutingSettings>();
|
||||
|
||||
var response = new VoiceResponse();
|
||||
var gather = new Gather()
|
||||
{
|
||||
Input = new List<Gather.InputEnum>() { Gather.InputEnum.Speech },
|
||||
Action = new Uri($"{_settings.CallbackHost}/twilio/voice/{routingSetting.RouterId}"),
|
||||
ActionOnEmptyResult = true
|
||||
};
|
||||
if (!string.IsNullOrEmpty(message))
|
||||
{
|
||||
gather.Say(message);
|
||||
}
|
||||
gather.Pause(interval);
|
||||
response.Append(gather);
|
||||
return response;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
namespace BotSharp.Plugin.Twilio.Settings;
|
||||
|
||||
public class TwilioSetting
|
||||
{
|
||||
public string PhoneNumber { get; set; }
|
||||
public string AccountSID { get; set; }
|
||||
public string AuthToken { get; set; }
|
||||
public string CallbackHost { get; set; }
|
||||
}
|
||||
16
src/Plugins/BotSharp.Plugin.Twilio/TwilioPlugin.cs
Normal file
16
src/Plugins/BotSharp.Plugin.Twilio/TwilioPlugin.cs
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
using BotSharp.Abstraction.Plugins;
|
||||
using BotSharp.Plugin.Twilio.Settings;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace BotSharp.Plugin.Twilio;
|
||||
|
||||
public class TwilioPlugin : IBotSharpPlugin
|
||||
{
|
||||
public void RegisterDI(IServiceCollection services, IConfiguration config)
|
||||
{
|
||||
var setting = new TwilioSetting();
|
||||
config.Bind("Twilio", setting);
|
||||
services.AddSingleton(setting);
|
||||
}
|
||||
}
|
||||
17
src/Plugins/BotSharp.Plugin.Twilio/Using.cs
Normal file
17
src/Plugins/BotSharp.Plugin.Twilio/Using.cs
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
global using System;
|
||||
global using System.Collections.Generic;
|
||||
global using System.Text;
|
||||
global using System.Threading.Tasks;
|
||||
global using System.Linq;
|
||||
global using System.Text.Json;
|
||||
global using Microsoft.Extensions.DependencyInjection;
|
||||
global using Microsoft.Extensions.Configuration;
|
||||
global using Microsoft.Extensions.Logging;
|
||||
global using BotSharp.Abstraction.Functions;
|
||||
global using BotSharp.Abstraction.Functions.Models;
|
||||
global using BotSharp.Abstraction.Agents.Enums;
|
||||
global using BotSharp.Abstraction.Models;
|
||||
global using BotSharp.Abstraction.Agents;
|
||||
global using BotSharp.Abstraction.Conversations;
|
||||
global using BotSharp.Abstraction.Plugins;
|
||||
global using BotSharp.Abstraction.Conversations.Models;
|
||||
|
|
@ -63,6 +63,7 @@
|
|||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\tests\BotSharp.Plugin.PizzaBot\BotSharp.Plugin.PizzaBot.csproj" />
|
||||
<ProjectReference Include="..\Plugins\BotSharp.Plugin.Twilio\BotSharp.Plugin.Twilio.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -89,6 +89,13 @@
|
|||
"PageAccessToken": ""
|
||||
},
|
||||
|
||||
"Twilio": {
|
||||
"PhoneNumber": "+1",
|
||||
"AccountSID": "",
|
||||
"AuthToken": "",
|
||||
"CallbackHost": "https://"
|
||||
},
|
||||
|
||||
"Database": {
|
||||
"Default": "FileRepository",
|
||||
"TablePrefix": "BotSharp",
|
||||
|
|
@ -132,6 +139,7 @@
|
|||
"BotSharp.Plugin.AzureOpenAI",
|
||||
"BotSharp.Plugin.GoogleAI",
|
||||
"BotSharp.Plugin.MetaAI",
|
||||
// "BotSharp.Plugin.Twilio",
|
||||
"BotSharp.Plugin.HuggingFace",
|
||||
"BotSharp.Plugin.LLamaSharp",
|
||||
"BotSharp.Plugin.KnowledgeBase",
|
||||
|
|
|
|||
Loading…
Reference in a new issue