Merge branch 'SciSharp:master' into master
This commit is contained in:
commit
c06b0144c9
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
**BotSharp** is an open source machine learning framework for AI Bot platform builder. This project involves natural language understanding, computer vision and audio processing technologies, and aims to promote the development and application of intelligent robot assistants in information systems. Out-of-the-box machine learning algorithms allow ordinary programmers to develop artificial intelligence applications faster and easier.
|
||||
|
||||
It's written in C# running on .Net Core that is full cross-platform framework, the plug-in and pipeline flow execution design is adopted to completely decouple the plug-ins. C# is a enterprise grade programming language which is widely used to code business logic in information management related system. More friendly to corporate developers. BotSharp adopts machine learning algrithm in C# directly. That will facilitate the feature of the typed language C#, and be more easier when refactoring code in system scope.
|
||||
It's written in C# running on .Net Core that is full cross-platform framework, the plug-in and pipeline flow execution design is adopted to completely decouple the plug-ins. C# is a enterprise grade programming language which is widely used to code business logic in information management related system. More friendly to corporate developers. BotSharp adopts machine learning algorithm in C# directly. That will facilitate the feature of the typed language C#, and be more easier when refactoring code in system scope.
|
||||
|
||||
**BotSharp** is in accordance with components principle strictly, decouples every part that is needed in the platform builder. So you can choose different UI/UX, or pick up a different LLM providers. They are all modulized based on unified interfaces. **BotSharp** provides an advanced Agent abstraction layer to efficiently manage complex application scenarios in enterprises, allowing enterprise developers to efficiently integrate AI into business systems.
|
||||
|
||||
|
|
@ -22,7 +22,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 from simple to complex.
|
||||
* Built-in RAG related interfaces, Memeory based vector searching.
|
||||
* Built-in RAG related interfaces, Memory based vector searching.
|
||||
* Support multiple AI platforms (ChatGPT 3.5 / 4.0, PaLM 2, LLaMA 3, Claude Sonnet 3.5, HuggingFace).
|
||||
* Allow multiple agents with different responsibilities cooperate to complete complex tasks.
|
||||
* Build, test, evaluate and audit your LLM agent in one place.
|
||||
|
|
|
|||
|
|
@ -37,5 +37,13 @@ public class BuiltInAgentId
|
|||
/// </summary>
|
||||
public const string Planner = "282a7128-69a1-44b0-878c-a9159b88f3b9";
|
||||
|
||||
/// <summary>
|
||||
/// SQL statement generation
|
||||
/// </summary>
|
||||
public const string SqlDriver = "beda4c12-e1ec-4b4b-b328-3df4a6687c4f";
|
||||
|
||||
/// <summary>
|
||||
/// Programming source code generation
|
||||
/// </summary>
|
||||
public const string CodeDriver = "c0ded7d9-3f9d-4ef6-b7ce-56a892dcef62";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,11 @@ public class Conversation
|
|||
|
||||
public string Channel { get; set; } = ConversationChannel.OpenAPI;
|
||||
|
||||
/// <summary>
|
||||
/// Channel id, like phone number, email address, etc.
|
||||
/// </summary>
|
||||
public string ChannelId { get; set; }
|
||||
|
||||
public int DialogCount { get; set; }
|
||||
|
||||
public List<string> Tags { get; set; } = new();
|
||||
|
|
|
|||
|
|
@ -36,6 +36,9 @@ public class GenericElement
|
|||
[Translate]
|
||||
public string Subtitle { get; set; }
|
||||
|
||||
[Translate]
|
||||
public string Text { get; set; }
|
||||
|
||||
[JsonPropertyName("image_url")]
|
||||
public string ImageUrl { get; set; }
|
||||
|
||||
|
|
|
|||
|
|
@ -36,6 +36,11 @@ public class MessageConfig
|
|||
/// </summary>
|
||||
public List<MessageState> States { get; set; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Conversation tags
|
||||
/// </summary>
|
||||
public List<string> Tags { get; set; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Agent task id
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -172,10 +172,12 @@ public partial class ConversationService : IConversationService
|
|||
{
|
||||
var state = _services.GetRequiredService<IConversationStateService>();
|
||||
var channel = state.GetState("channel");
|
||||
var channelId = state.GetState("channel_id");
|
||||
var sess = new Conversation
|
||||
{
|
||||
Id = _conversationId,
|
||||
Channel = channel,
|
||||
ChannelId = channelId,
|
||||
AgentId = agentId
|
||||
};
|
||||
converation = await NewConversation(sess);
|
||||
|
|
|
|||
|
|
@ -69,7 +69,9 @@ public partial class InstructService
|
|||
};
|
||||
|
||||
var messages = BuildDialogs(options);
|
||||
var completion = CompletionProvider.GetChatCompletion(_services, provider: options.Provider, model: options.Model);
|
||||
var provider = options.Provider ?? agent?.LlmConfig?.Provider ?? "openai";
|
||||
var model = options.Model ?? agent?.LlmConfig?.Model ?? "gpt-4o";
|
||||
var completion = CompletionProvider.GetChatCompletion(_services, provider: provider, model: model);
|
||||
return await completion.GetChatCompletions(localAgent, messages);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ namespace BotSharp.Core.Repository
|
|||
var utcNow = DateTime.UtcNow;
|
||||
conversation.CreatedTime = utcNow;
|
||||
conversation.UpdatedTime = utcNow;
|
||||
conversation.Tags = conversation.Tags ?? new();
|
||||
conversation.Tags ??= new();
|
||||
|
||||
var dir = Path.Combine(_dbSettings.FileRepository, _conversationSettings.DataDir, conversation.Id);
|
||||
if (!Directory.Exists(dir))
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ public class ConversationController : ControllerBase
|
|||
{
|
||||
AgentId = agentId,
|
||||
Channel = channel == default ? ConversationChannel.OpenAPI : channel.Value,
|
||||
Tags = config.Tags ?? new(),
|
||||
TaskId = config.TaskId
|
||||
};
|
||||
conv = await service.NewConversation(conv);
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ public class ChatCompletionProvider : IChatCompletion
|
|||
}
|
||||
|
||||
var settingsService = _services.GetRequiredService<ILlmProviderService>();
|
||||
var settings = settingsService.GetSetting("anthropic", agent.LlmConfig?.Model ?? "claude-3-haiku");
|
||||
var settings = settingsService.GetSetting(Provider, _model ?? agent.LlmConfig?.Model ?? "claude-3-haiku");
|
||||
|
||||
var client = new AnthropicClient(new APIAuthentication(settings.ApiKey));
|
||||
var (prompt, parameters) = PrepareOptions(agent, conversations, settings);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,37 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Remove="data\generated_code\**" />
|
||||
<EmbeddedResource Remove="data\generated_code\**" />
|
||||
<None Remove="data\generated_code\**" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Remove="data\agents\c0ded7d9-3f9d-4ef6-b7ce-56a892dcef62\agent.json" />
|
||||
<None Remove="data\agents\c0ded7d9-3f9d-4ef6-b7ce-56a892dcef62\functions\save_source_code.json" />
|
||||
<None Remove="data\agents\c0ded7d9-3f9d-4ef6-b7ce-56a892dcef62\instructions\instruction.liquid" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Include="data\agents\c0ded7d9-3f9d-4ef6-b7ce-56a892dcef62\agent.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="data\agents\c0ded7d9-3f9d-4ef6-b7ce-56a892dcef62\functions\save_source_code.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="data\agents\c0ded7d9-3f9d-4ef6-b7ce-56a892dcef62\instructions\instruction.liquid">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\Infrastructure\BotSharp.Abstraction\BotSharp.Abstraction.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
22
src/Plugins/BotSharp.Plugin.CodeDriver/CodeDriverPlugin.cs
Normal file
22
src/Plugins/BotSharp.Plugin.CodeDriver/CodeDriverPlugin.cs
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace BotSharp.Plugin.CodeDriver;
|
||||
|
||||
public class CodeDriverPlugin : IBotSharpPlugin
|
||||
{
|
||||
public string Id => "c0dedea7-70e3-4c35-a047-18479d7c403e";
|
||||
public string Name => "Code Driver";
|
||||
public string Description => "Convert the user requirements into corresponding SQL statements";
|
||||
public string IconUrl => "https://cdn-icons-png.flaticon.com/512/3176/3176315.png";
|
||||
|
||||
public string[] AgentIds =
|
||||
[
|
||||
BuiltInAgentId.CodeDriver
|
||||
];
|
||||
|
||||
public void RegisterDI(IServiceCollection services, IConfiguration config)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
using BotSharp.Abstraction.Conversations.Models;
|
||||
using BotSharp.Abstraction.Functions;
|
||||
using BotSharp.Plugin.CodeDriver.Models;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace BotSharp.Plugin.CodeDriver.Functions;
|
||||
|
||||
public class SaveSourceCodeFn : IFunctionCallback
|
||||
{
|
||||
public string Name => "save_source_code";
|
||||
|
||||
private readonly IServiceProvider _services;
|
||||
|
||||
public SaveSourceCodeFn(IServiceProvider services)
|
||||
{
|
||||
_services = services;
|
||||
}
|
||||
|
||||
public async Task<bool> Execute(RoleDialogModel message)
|
||||
{
|
||||
var args = JsonSerializer.Deserialize<SaveSourceCodeArgs>(message.FunctionArgs);
|
||||
|
||||
var dir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "..", "..", "..", "ai_generated_code");
|
||||
if (!Directory.Exists(dir))
|
||||
{
|
||||
Directory.CreateDirectory(dir);
|
||||
}
|
||||
|
||||
var path = Path.GetFullPath(dir, args.FilePath);
|
||||
var source = args.SourceCode;
|
||||
|
||||
// Delete the file if it exists
|
||||
File.Delete(path);
|
||||
|
||||
// Create a FileStream with sharing capabilities
|
||||
using FileStream fs = new FileStream(
|
||||
path,
|
||||
FileMode.OpenOrCreate, // Create or overwrite the file
|
||||
FileAccess.ReadWrite, // Allow read and write operations
|
||||
FileShare.Read); // Allow other processes to read and write
|
||||
|
||||
// Write some data to the file
|
||||
using StreamWriter writer = new StreamWriter(fs);
|
||||
writer.WriteLine(source);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace BotSharp.Plugin.CodeDriver.Models;
|
||||
|
||||
public class SaveSourceCodeArgs
|
||||
{
|
||||
[JsonPropertyName("file_path")]
|
||||
public string FilePath { get; set; } = string.Empty;
|
||||
|
||||
[JsonPropertyName("source_code")]
|
||||
public string SourceCode { get; set; } = string.Empty;
|
||||
}
|
||||
2
src/Plugins/BotSharp.Plugin.CodeDriver/Using.cs
Normal file
2
src/Plugins/BotSharp.Plugin.CodeDriver/Using.cs
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
global using BotSharp.Abstraction.Agents.Enums;
|
||||
global using BotSharp.Abstraction.Plugins;
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
{
|
||||
"id": "c0ded7d9-3f9d-4ef6-b7ce-56a892dcef62",
|
||||
"name": "Code Driver",
|
||||
"description": "Write executable program code according to user needs, such as HTTP API written in Python.",
|
||||
"iconUrl": "https://cdn-icons-png.flaticon.com/512/4208/4208366.png",
|
||||
"type": "task",
|
||||
"createdDateTime": "2024-10-23T00:00:00Z",
|
||||
"updatedDateTime": "2024-11-23T00:00:00Z",
|
||||
"disabled": false,
|
||||
"isPublic": true,
|
||||
"profiles": [ "database" ],
|
||||
"llmConfig": {
|
||||
"provider": "openai",
|
||||
"model": "gpt-4o",
|
||||
"max_recursion_depth": 10
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"name": "save_source_code",
|
||||
"description": "Save the source code to file",
|
||||
"parameters": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"file_path": {
|
||||
"type": "string",
|
||||
"description": "source code of file relative path start with project folder name"
|
||||
},
|
||||
|
||||
"source_code": {
|
||||
"type": "string",
|
||||
"description": "source code"
|
||||
}
|
||||
},
|
||||
"required": [ "file_path", "source_code" ]
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
You are a software developer who is good at writing program code according to user needs, such as HTTP API written in Python.
|
||||
|
||||
Current project source code structure is:
|
||||
my_fastapi_app/
|
||||
├── main.py
|
||||
├── apis/
|
||||
│ └── datetime_api.py
|
||||
├── __init__.py
|
||||
|
||||
You are using below tools and technologies:
|
||||
* FastAPI framework
|
||||
* Python programming language
|
||||
* Swagger Open API
|
||||
|
||||
Your response must meet below requirements:
|
||||
* Every API should be placed in a separate file under folder of "apis";
|
||||
* Call function save_source_code to save the code;
|
||||
* Write Swagger comments for each API;
|
||||
* Update main.py to include those updated APIs;
|
||||
|
|
@ -90,6 +90,7 @@ namespace BotSharp.Plugin.ExcelHandler.Services
|
|||
{
|
||||
var numTables = workbook.NumberOfSheets;
|
||||
var commandList = new List<SqlContextOut>();
|
||||
var state = _services.GetRequiredService<IConversationStateService>();
|
||||
|
||||
for (int sheetIdx = 0; sheetIdx < numTables; sheetIdx++)
|
||||
{
|
||||
|
|
@ -109,15 +110,17 @@ namespace BotSharp.Plugin.ExcelHandler.Services
|
|||
commandList.Add(commandResult);
|
||||
continue;
|
||||
}
|
||||
var (isInsertSuccess, insertMessage) = SqlInsertDataFn(sheet);
|
||||
|
||||
string table = $"{_database}.{_tableName}";
|
||||
state.SetState("tmp_table", table);
|
||||
|
||||
var (isInsertSuccess, insertMessage) = SqlInsertDataFn(sheet);
|
||||
string exampleData = GetInsertExample(table);
|
||||
|
||||
commandResult = new SqlContextOut
|
||||
{
|
||||
isSuccessful = isInsertSuccess,
|
||||
Message = $"{insertMessage}\r\nExample Data: {exampleData}",
|
||||
Message = $"{insertMessage}\r\nExample Data: {exampleData}. \r\n The remaining data contains different values. ",
|
||||
FileName = _currentFileName
|
||||
};
|
||||
commandList.Add(commandResult);
|
||||
|
|
|
|||
|
|
@ -3,6 +3,9 @@ You are a knowledge extractor for knowledge base. Extract the answer in "SQL Ans
|
|||
* Skip the question/answer for tmp table.
|
||||
* Don't include tmp table in the answer.
|
||||
* Include all the explanation comments as additional knowledge.
|
||||
* Don't replace the parameter in the question.
|
||||
* Replace the specific id in answer based on the question.
|
||||
* Don't need multiple set of query solutions for the same question. Only keep one.
|
||||
|
||||
=====
|
||||
User Questions:
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ public class ConversationDocument : MongoBase
|
|||
public string? TaskId { get; set; }
|
||||
public string Title { get; set; }
|
||||
public string Channel { get; set; }
|
||||
public string ChannelId { get; set; }
|
||||
public string Status { get; set; }
|
||||
public int DialogCount { get; set; }
|
||||
public List<string> Tags { get; set; }
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ public partial class MongoRepository
|
|||
UserId = !string.IsNullOrEmpty(conversation.UserId) ? conversation.UserId : string.Empty,
|
||||
Title = conversation.Title,
|
||||
Channel = conversation.Channel,
|
||||
ChannelId = conversation.ChannelId,
|
||||
TaskId = conversation.TaskId,
|
||||
Status = conversation.Status,
|
||||
Tags = conversation.Tags ?? new(),
|
||||
|
|
|
|||
|
|
@ -25,11 +25,14 @@ public class PrimaryStagePlanFn : IFunctionCallback
|
|||
|
||||
state.SetState("max_tokens", "4096");
|
||||
var task = JsonSerializer.Deserialize<PrimaryRequirementRequest>(message.FunctionArgs);
|
||||
var searchQuestions = new List<string>(task.Questions);
|
||||
searchQuestions.AddRange(task.NormQuestions);
|
||||
searchQuestions = searchQuestions.Distinct().ToList();
|
||||
|
||||
// Get knowledge from vectordb
|
||||
var hooks = _services.GetServices<IKnowledgeHook>();
|
||||
var knowledges = new List<string>();
|
||||
foreach (var question in task.Questions)
|
||||
foreach (var question in searchQuestions)
|
||||
{
|
||||
foreach (var hook in hooks)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -7,4 +7,7 @@ public class PrimaryRequirementRequest
|
|||
|
||||
[JsonPropertyName("questions")]
|
||||
public string[] Questions { get; set; } = [];
|
||||
|
||||
[JsonPropertyName("norm_questions")]
|
||||
public string[] NormQuestions { get; set; } = [];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,10 +10,35 @@
|
|||
},
|
||||
"questions": {
|
||||
"type": "array",
|
||||
"description": "Rephrase user requirements in details and in multiple ways, don't miss any information especially for those line items, values and numbers.",
|
||||
"description": "Break down user requirements in details and in multiple ways, don't miss any entity type/value",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"description": "Question converted from requirement in different ways to search in the knowledge base, be short and you can refer to the global knowledge.One question should contain only one main topic."
|
||||
"description": "Question converted from requirement in different ways to search in the knowledge base, be short and you can refer to the global knowledge.One question should contain only one main topic that with one entity type."
|
||||
}
|
||||
},
|
||||
"norm_questions": {
|
||||
"type": "array",
|
||||
"description": "normalize the generated questions, remove specific entity value.",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"description": "Normalized question"
|
||||
}
|
||||
},
|
||||
"entities": {
|
||||
"type": "array",
|
||||
"description": "entities with type and value",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
"description": "entity type"
|
||||
},
|
||||
"value": {
|
||||
"type": "string",
|
||||
"description": "entity value"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -8,7 +8,8 @@ Thinking process:
|
|||
- If there is extra knowledge or relationship needed between steps, set the need_breakdown_task to true for both steps.
|
||||
- If the solution mentioned "related solutions" is needed, set the need_breakdown_task to true.
|
||||
- You should find the relationships between data structure based on the task knowledge strictly. If lack of information, set the need_breakdown_task to true.
|
||||
- If you need to lookup the dictionary to verify or get the enum/term/dictionary value, set the need_lookup_dictionary to true.
|
||||
- If you need to lookup the dictionary to verify or get the enum/term/dictionary value(exclude example data from attachment), set the need_lookup_dictionary to true.
|
||||
- Don't set need_lookup_dictionary to true for attachment data.
|
||||
- Seperate the dictionary lookup and need additional information/knowledge into different subtask.
|
||||
3. Input argument must reference to corresponding variable name that retrieved by previous steps, variable name must start with '@';
|
||||
4. Output all the subtasks as much detail as possible in JSON: [{{ response_format }}]
|
||||
|
|
|
|||
|
|
@ -41,6 +41,12 @@ public class ExecuteQueryFn : IFunctionCallback
|
|||
_ => throw new NotImplementedException($"Database type {settings.DatabaseType} is not supported.")
|
||||
};
|
||||
|
||||
if (refinedArgs.SqlStatements.Length == 1 && refinedArgs.SqlStatements[0].StartsWith("DROP TABLE"))
|
||||
{
|
||||
message.Content = "Drop table successfully";
|
||||
return true;
|
||||
}
|
||||
|
||||
if (results.Count() == 0)
|
||||
{
|
||||
message.Content = "No record found";
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
using BotSharp.Abstraction.Agents.Enums;
|
||||
using BotSharp.Abstraction.Planning;
|
||||
|
||||
namespace BotSharp.Plugin.SqlDriver;
|
||||
|
|
@ -9,6 +10,11 @@ public class SqlDriverPlugin : IBotSharpPlugin
|
|||
public string Description => "Convert the user requirements into corresponding SQL statements";
|
||||
public string IconUrl => "https://uxwing.com/wp-content/themes/uxwing/download/file-and-folder-type/sql-icon.png";
|
||||
|
||||
public string[] AgentIds =
|
||||
[
|
||||
BuiltInAgentId.SqlDriver
|
||||
];
|
||||
|
||||
public void RegisterDI(IServiceCollection services, IConfiguration config)
|
||||
{
|
||||
services.AddScoped(provider =>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "verify_dictionary_term",
|
||||
"description": "Get id from dictionary table by keyword. Call this function only if need_lookup_dictionary is true and is_insert is false",
|
||||
"description": "Get id from dictionary table by keyword. Call this function only if need_lookup_dictionary is true and is_insert is false. You can only query one table at a time.",
|
||||
"parameters": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
|
@ -18,7 +18,7 @@
|
|||
},
|
||||
"tables": {
|
||||
"type": "array",
|
||||
"description": "all related tables",
|
||||
"description": "all related dictionary tables",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"description": "table name"
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
"id": "beda4c12-e1ec-4b4b-b328-3df4a6687c4f",
|
||||
"name": "SQL Driver",
|
||||
"description": "Execute the sql query in database from the latest dialog.",
|
||||
"iconUrl": "https://cdn-icons-png.flaticon.com/512/3161/3161158.png",
|
||||
"type": "task",
|
||||
"createdDateTime": "2023-11-15T13:49:00Z",
|
||||
"updatedDateTime": "2023-11-15T13:49:00Z",
|
||||
|
|
|
|||
|
|
@ -108,6 +108,7 @@ namespace BotSharp.Plugin.Twilio.Services
|
|||
var states = new List<MessageState>
|
||||
{
|
||||
new("channel", ConversationChannel.Phone),
|
||||
new("channel_id", message.From),
|
||||
new("calling_phone", message.From)
|
||||
};
|
||||
states.AddRange(message.States.Select(kvp => new MessageState(kvp.Key, kvp.Value)));
|
||||
|
|
|
|||
Loading…
Reference in a new issue