测试项目

This commit is contained in:
zpc 2024-06-22 12:38:23 +08:00
parent ef1c3c00b7
commit 70126fb307
13 changed files with 439 additions and 124 deletions

View File

@ -1,4 +1,6 @@
using System;
using HuanMeng.StableDiffusion.TextGeneration.api;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@ -11,7 +13,7 @@ namespace HuanMeng.StableDiffusion.TextGeneration.Abstractions
/// </summary>
public abstract class TextGenerationRequestAbstract
{
public TextGenerationModel textGenerationModel { get; set; }
/// <summary>
/// 发送数据
/// </summary>

View File

@ -26,26 +26,26 @@ namespace HuanMeng.StableDiffusion.TextGeneration.BLL
/// <param name="sessionId"></param>
/// <param name="message"></param>
/// <returns></returns>
public async IAsyncEnumerable<string> Chat(string sessionId, string message)
public async IAsyncEnumerable<string> Chat(string sessionId, string message, string character)
{
if (string.IsNullOrEmpty(sessionId))
{
sessionId = Guid.NewGuid().ToString();
}
var x = textGenerationTestContext.TextGenerationSessionDetails.Where(it => it.SessionId == sessionId).OrderBy(it => it.TimeStamp).ToList();
List<TextGenerationRequestHttpApiModel> textGenerationRequestHttpApiModels = new List<TextGenerationRequestHttpApiModel>();
var x = new List<TextGenerationSessionDetail>(); // textGenerationTestContext.TextGenerationSessionDetails.Where(it => it.SessionId == sessionId).OrderBy(it => it.TimeStamp).ToList();
List<TextGenerationRequestHttpApiStreamModel> textGenerationRequestHttpApiModels = new List<TextGenerationRequestHttpApiStreamModel>();
if (textGenerationRequestHttpApiModels != null)
{
foreach (var item in x)
{
textGenerationRequestHttpApiModels.Add(new TextGenerationRequestHttpApiModel
textGenerationRequestHttpApiModels.Add(new TextGenerationRequestHttpApiStreamModel
{
Role = item.Role,
Content = item.Message
});
}
}
textGenerationRequestHttpApiModels.Add(new TextGenerationRequestHttpApiModel
textGenerationRequestHttpApiModels.Add(new TextGenerationRequestHttpApiStreamModel
{
Role = "user",
Content = message
@ -65,30 +65,49 @@ namespace HuanMeng.StableDiffusion.TextGeneration.BLL
TimeStamp = ((DateTimeOffset)DateTime.Now).ToUnixTimeSeconds(),
TextGenerationSessionId = 0
};
textGenerationTestContext.TextGenerationSessionDetails.Add(d);
//textGenerationTestContext.TextGenerationSessionDetails.Add(d);
string datex = "";
if (!string.IsNullOrEmpty(character))
{
datex = $@" ""character"":""{character}"" ";
}
// string json = $@"
//{{
// ""messages"": {messageStr},
// ""stream"": true,
// ""mode"": ""chat"",
// {datex}
//}}
//";
string json = $@"
{{
""messages"": {messageStr},
""stream"": true
""mode"": ""chat"",
{datex}
}}
";
//TextGenerationRequestHttpApiStream textGenerationRequestHttpApi = new TextGenerationRequestHttpApiStream(json);
TextGenerationRequestHttpApi textGenerationRequestHttpApi = new TextGenerationRequestHttpApi(json);
await foreach (var item in textGenerationRequestHttpApi.SendMessageAsync())
{
if (item == "")
{
continue;
}
yield return item;
}
TextGenerationSessionDetail d1 = new TextGenerationSessionDetail()
{
CreateDateTime = DateTime.Now,
Message = textGenerationRequestHttpApi?.textGenerationRequestHttpModel?.Choices?[0]?.Delta?.Content ?? "",
Role = textGenerationRequestHttpApi?.textGenerationRequestHttpModel?.Choices?[0]?.Delta?.Role ?? "",
Model = textGenerationRequestHttpApi?.textGenerationRequestHttpModel?.Model ?? "",
Message = textGenerationRequestHttpApi?.textGenerationModel?.Content ?? "",
Role = textGenerationRequestHttpApi?.textGenerationModel?.Role ?? "",
Model = textGenerationRequestHttpApi?.textGenerationModel?.Model ?? "",
SessionId = sessionId,
TimeStamp = ((DateTimeOffset)DateTime.Now).ToUnixTimeSeconds(),
TextGenerationSessionId = 0
};
textGenerationTestContext.TextGenerationSessionDetails.Add(d1);
await textGenerationTestContext.SaveChangesAsync();
//textGenerationTestContext.TextGenerationSessionDetails.Add(d1);
//await textGenerationTestContext.SaveChangesAsync();
}
}
}

View File

@ -39,14 +39,14 @@ public partial class TextGenerationTestContext : DbContext
.HasComment("最后一次请求时间")
.HasColumnType("datetime");
entity.Property(e => e.SessionId)
.HasMaxLength(32)
.HasMaxLength(64)
.IsUnicode(false)
.HasComment("绘画Id");
entity.Property(e => e.SessionName)
.HasMaxLength(100)
.HasComment("绘画名称");
entity.Property(e => e.UserId)
.HasMaxLength(32)
.HasMaxLength(64)
.IsUnicode(false)
.HasComment("用户Id");
});
@ -66,7 +66,7 @@ public partial class TextGenerationTestContext : DbContext
.HasMaxLength(50)
.HasComment("角色");
entity.Property(e => e.SessionId)
.HasMaxLength(32)
.HasMaxLength(64)
.IsUnicode(false)
.HasComment("会话Id");
entity.Property(e => e.TextGenerationSessionId).HasComment("会话id");

View File

@ -0,0 +1,48 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.Json.Serialization;
using System.Threading.Tasks;
namespace HuanMeng.StableDiffusion.TextGeneration.api
{
/// <summary>
///
/// </summary>
public class TextGenerationModel
{
/// <summary>
/// 文本生成请求的唯一标识符。
/// </summary>
public string? Id { get; set; }
/// <summary>
/// 返回的对象类型(例如,"text_completion")。
/// </summary>
public string? Object { get; set; }
/// <summary>
/// 请求创建的时间戳。
/// </summary>
public long? Created { get; set; }
/// <summary>
/// 用于文本生成的模型。
/// </summary>
public string? Model { get; set; }
/// <summary>
/// 文本内容
/// </summary>
public string? Content { get; set; }
/// <summary>
/// 角色
/// </summary>
public string? Role { get; set; }
}
}

View File

@ -3,27 +3,27 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http.Headers;
using System.Net.Http.Json;
using System.Text;
using System.Text.Json.Serialization;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace HuanMeng.StableDiffusion.TextGeneration.api
{
/// <summary>
///
/// </summary>
public class TextGenerationRequestHttpApi : TextGenerationRequestAbstract
{
public string Url = "http://117.50.182.144:5000/v1/chat/completions";
string jsonContent = "{\"messages\":[{\"role\":\"user\",\"content\":\"你好?\"}],\"stream\":true}";
//http://127.0.0.1:7860/
public string Url = "http://127.0.0.1:5000/v1/chat/completions";
//public string Url = "http://117.50.182.144:5000/v1/chat/completions";
string jsonContent = "{\"messages\":[{\"role\":\"user\",\"content\":\"你好?\"}]}";
string analysisStr = "data:";
/// <summary>
/// 请求内容
/// </summary>
public TextGenerationRequestHttpModel textGenerationRequestHttpModel { get; set; }
public TextGenerationRequestHttpApi(string jsonContent)
{
this.jsonContent = jsonContent;
@ -34,71 +34,32 @@ namespace HuanMeng.StableDiffusion.TextGeneration.api
{
// 设置请求头
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
//httpClient.DefaultRequestHeaders.Add("Content-Type", "application/json");
var content = new StringContent(jsonContent, Encoding.UTF8, "application/json");
// 发送请求
using (var response = await httpClient.PostAsync(Url, content))
{
if (response.IsSuccessStatusCode)
{
// 获取响应流
using (var stream = await response.Content.ReadAsStreamAsync())
using (var reader = new System.IO.StreamReader(stream))
var x = await response.Content.ReadFromJsonAsync<TextGenerationRequestHttpApiModel?>();
if (x != null)
{
string textContent = "";
// 持续读取流中的事件
while (!reader.EndOfStream)
yield return x.Choices[0].Message.Content;
textGenerationModel = new TextGenerationModel()
{
var line = await reader.ReadLineAsync();
if (!string.IsNullOrEmpty(line))
{
var index = line.IndexOf(analysisStr);
if (index > -1)
{
line = line.Substring(index + analysisStr.Length).Trim();
}
if (!string.IsNullOrEmpty(line))
{
var linex = JsonConvert.DeserializeObject<TextGenerationRequestHttpModel>(line);
if (linex != null)
{
textGenerationRequestHttpModel = linex;
textContent += linex?.Choices?[0].Delta?.Content ?? "";
yield return linex?.Choices?[0].Delta?.Content ?? "";
}
}
//yield return line;
}
}
if (textGenerationRequestHttpModel != null)
{
if (textGenerationRequestHttpModel?.Choices?.Length == 0)
{
textGenerationRequestHttpModel.Choices = new Choice[1] { new Choice() { Delta = new Delta() } };
}
textGenerationRequestHttpModel.Choices[0].Delta.Content = textContent;
}
Id = x.Id,
Content = x.Choices[0].Message.Content,
Created = x.Created,
Model = x.Model,
Object = x.Object,
Role = x.Choices[0].Message.Role
};
}
}
}
}
}
/// <summary>
/// 解析
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
public string DecodeUnicodeString(string input)
{
// 使用正则表达式匹配 \u 后面跟随的 4 个十六进制数字
return Regex.Replace(input, @"\\u([0-9A-Fa-f]{4})", m =>
{
return ((char)Convert.ToInt32(m.Groups[1].Value, 16)).ToString();
});
}
}
}

View File

@ -1,25 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace HuanMeng.StableDiffusion.TextGeneration.api
{
/// <summary>
/// 消息内容
/// </summary>
public class TextGenerationRequestHttpApiModel
{
/// <summary>
/// 角色
/// </summary>
public string Role { get; set; }
/// <summary>
/// 控制器
/// </summary>
public string Content { get; set; }
}
}

View File

@ -0,0 +1,129 @@
using HuanMeng.StableDiffusion.TextGeneration.Abstractions;
using Newtonsoft.Json;
using System;
using System.Data;
using System.Net.Http.Headers;
using System.Text;
using System.Text.Json.Serialization;
using System.Text.RegularExpressions;
namespace HuanMeng.StableDiffusion.TextGeneration.api
{
/// <summary>
///
/// </summary>
public class TextGenerationRequestHttpApiStream : TextGenerationRequestAbstract
{
//http://127.0.0.1:7860/
public string Url = "http://127.0.0.1:5000/v1/chat/completions";
//public string Url = "http://117.50.182.144:5000/v1/chat/completions";
string jsonContent = "{\"messages\":[{\"role\":\"user\",\"content\":\"你好?\"}],\"stream\":true}";
string analysisStr = "data:";
/// <summary>
/// 请求内容
/// </summary>
public TextGenerationRequestHttpModel textGenerationRequestHttpModel { get; set; }
public TextGenerationRequestHttpApiStream(string jsonContent)
{
this.jsonContent = jsonContent;
}
public override async IAsyncEnumerable<string> SendMessageAsync()
{
using (var httpClient = new HttpClient())
{
// 设置请求头
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
//httpClient.DefaultRequestHeaders.Add("Content-Type", "application/json");
var content = new StringContent(jsonContent, Encoding.UTF8, "application/json");
// 发送请求
using (var response = await httpClient.PostAsync(Url, content))
{
if (response.IsSuccessStatusCode)
{
// 获取响应流
using (var stream = await response.Content.ReadAsStreamAsync())
using (var reader = new System.IO.StreamReader(stream))
{
string textContent = "";
// 持续读取流中的事件
while (!reader.EndOfStream)
{
string t = "";
var line = await reader.ReadLineAsync();
try
{
if (!string.IsNullOrEmpty(line))
{
var index = line.IndexOf(analysisStr);
if (index > -1)
{
line = line.Substring(index + analysisStr.Length).Trim();
}
if (!string.IsNullOrEmpty(line))
{
var linex = JsonConvert.DeserializeObject<TextGenerationRequestHttpModel>(line);
if (linex != null)
{
textGenerationRequestHttpModel = linex;
textContent += linex?.Choices?[0].Delta?.Content ?? "";
t = linex?.Choices?[0].Delta?.Content ?? "";
}
}
//yield return line;
}
}
catch (Exception ex)
{
}
yield return t;
}
if (textGenerationRequestHttpModel != null)
{
if (textGenerationRequestHttpModel?.Choices?.Length == 0)
{
textGenerationRequestHttpModel.Choices = new TextGenerationRequestHttpApiChoice[1] { new TextGenerationRequestHttpApiChoice() { Delta = new Delta() } };
}
textGenerationRequestHttpModel.Choices[0].Delta.Content = textContent;
textGenerationModel = new TextGenerationModel()
{
Id = textGenerationRequestHttpModel.Id,
Content = textContent,
Created = textGenerationRequestHttpModel.Created,
Model = textGenerationRequestHttpModel.Model,
Object = textGenerationRequestHttpModel.Object,
Role = textGenerationRequestHttpModel?.Choices?[0]?.Delta?.Role ?? ""
};
}
}
}
}
}
}
/// <summary>
/// 解析
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
public string DecodeUnicodeString(string input)
{
// 使用正则表达式匹配 \u 后面跟随的 4 个十六进制数字
return Regex.Replace(input, @"\\u([0-9A-Fa-f]{4})", m =>
{
return ((char)Convert.ToInt32(m.Groups[1].Value, 16)).ToString();
});
}
}
}

View File

@ -0,0 +1,82 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.Json.Serialization;
using System.Threading.Tasks;
namespace HuanMeng.StableDiffusion.TextGeneration.api
{
/// <summary>
///
/// </summary>
public class TextGenerationRequestHttpApiModel
{
/// <summary>
/// 文本生成请求的唯一标识符。
/// </summary>
[JsonPropertyName("id")]
public string Id { get; set; }
/// <summary>
/// 返回的对象类型(例如,"text_completion")。
/// </summary>
[JsonPropertyName("object")]
public string Object { get; set; }
/// <summary>
/// 请求创建的时间戳。
/// </summary>
[JsonPropertyName("created")]
public int Created { get; set; }
/// <summary>
/// 用于文本生成的模型。
/// </summary>
[JsonPropertyName("model")]
public string Model { get; set; }
/// <summary>
/// 包含生成文本和相关信息的选项数组。
/// </summary>
[JsonPropertyName("choices")]
public TextGenerationRequestHttpApiChoiceExtend[] Choices { get; set; }
/// <summary>
/// 请求的使用统计信息,包括令牌计数。
/// </summary>
[JsonPropertyName("usage")]
public TextGenerationRequestHttpApiUsage Usage { get; set; }
}
public class TextGenerationRequestHttpApiChoiceExtend : TextGenerationRequestHttpApiChoice
{
/// <summary>
/// 包含生成文本的角色和内容的 delta 对象。
/// </summary>
[JsonPropertyName("message")]
public Delta? Message { get; set; }
}
/// <summary>
/// 消息内容
/// </summary>
public class TextGenerationRequestHttpApiStreamModel
{
/// <summary>
/// 角色
/// </summary>
public string Role { get; set; }
/// <summary>
/// 控制器
/// </summary>
public string Content { get; set; }
}
}

View File

@ -41,16 +41,16 @@ namespace HuanMeng.StableDiffusion.TextGeneration.api
/// 包含生成文本和相关信息的选项数组。
/// </summary>
[JsonPropertyName("choices")]
public Choice[]? Choices { get; set; }
public TextGenerationRequestHttpApiChoice[]? Choices { get; set; }
/// <summary>
/// 请求的使用统计信息,包括令牌计数。
/// </summary>
[JsonPropertyName("usage")]
public Usage? Usage { get; set; }
public TextGenerationRequestHttpApiUsage? Usage { get; set; }
}
public class Usage
public class TextGenerationRequestHttpApiUsage
{
/// <summary>
/// 提示中使用的令牌数。
@ -73,7 +73,7 @@ namespace HuanMeng.StableDiffusion.TextGeneration.api
/// <summary>
/// 消息内容
/// </summary>
public class Choice
public class TextGenerationRequestHttpApiChoice
{
/// <summary>
/// 返回列表中选项的索引。

View File

@ -0,0 +1,13 @@
{
"version": 1,
"isRoot": true,
"tools": {
"dotnet-ef": {
"version": "8.0.6",
"commands": [
"dotnet-ef"
],
"rollForward": false
}
}
}

View File

@ -13,26 +13,112 @@ namespace TextGenerationApi.Controllers
[ApiController]
public class TextGenerationApiController(TextGenerationTestContext textGenerationTestContext) : ControllerBase
{
[HttpPost]
/// <summary>
/// 聊天接口
/// 对话接口
/// </summary>
/// <param name="sessionId"></param>
/// <param name="message"></param>
/// <param name="message">消息</param>
/// <param name="character">角色</param>
/// <param name="sessionId">会话Id</param>
/// <returns></returns>
public async Task Chat(string sessionId, string message)
[HttpPost]
public async Task<IActionResult> Chat(string? message, string? character = "Assistant", string? sessionId = "")
{
var outputStream = this.Response.Body;
TextGenerationBLL textGenerationBLL = new TextGenerationBLL(textGenerationTestContext);
await foreach (var item in textGenerationBLL.Chat(sessionId, message))
Response.ContentType = "text/plain"; // 设置响应内容类型
Response.StatusCode = 200; // 设置状态码
try
{
if (item == null)
TextGenerationBLL textGenerationBLL = new TextGenerationBLL(textGenerationTestContext);
await foreach (var item in textGenerationBLL.Chat(sessionId, message, character))
{
continue;
if (item == null)
{
continue;
}
await outputStream.WriteAsync(Encoding.UTF8.GetBytes(item));
await outputStream.FlushAsync();
}
await outputStream.WriteAsync(Encoding.UTF8.GetBytes(item));
await outputStream.FlushAsync();
}
catch (Exception ex)
{
await outputStream.WriteAsync(Encoding.UTF8.GetBytes(ex.Message));
await outputStream.FlushAsync();
}
return new EmptyResult();
//return StatusCode(200); // 表示响应已完成
}
/// <summary>
/// 对话接口
/// </summary>
/// <param name="message">消息</param>
/// <param name="character">角色</param>
/// <param name="sessionId">会话Id</param>
/// <returns></returns>
[HttpPost]
public async Task<string> ChatStr(string? message, string? character = "Assistant", string? sessionId = "")
{
var outputStream = this.Response.Body;
string content = "";
try
{
TextGenerationBLL textGenerationBLL = new TextGenerationBLL(textGenerationTestContext);
await foreach (var item in textGenerationBLL.Chat(sessionId, message, character))
{
content += item;
}
}
catch (Exception ex)
{
content = ex.Message;
}
return content;
//return StatusCode(200); // 表示响应已完成
}
/// <summary>
/// 对话接口
/// </summary>
/// <param name="sessionId">会话Id</param>
/// <param name="message">消息</param>
/// <param name="character">角色</param>
/// <returns></returns>
[HttpPost]
public async Task<IActionResult> IChat()
{
var outputStream = Response.Body;
Response.ContentType = "text/plain"; // 设置响应内容类型
Response.StatusCode = 200; // 设置状态码
try
{
TextGenerationBLL textGenerationBLL = new TextGenerationBLL(textGenerationTestContext);
await foreach (var item in textGenerationBLL.Chat("", "哈喽", "Assistant"))
{
if (item == null)
{
continue;
}
await outputStream.WriteAsync(Encoding.UTF8.GetBytes(item));
await outputStream.FlushAsync();
}
}
catch (Exception ex)
{
}
//await outputStream.WriteAsync(Encoding.UTF8.GetBytes("aaaa"));
//await outputStream.FlushAsync();
return new EmptyResult();
}
}
}

View File

@ -34,8 +34,8 @@ builder.Services.AddSwaggerGen();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
//if (app.Environment.IsDevelopment())
//{
app.UseSwagger();
app.UseSwaggerUI(c =>
{
@ -47,9 +47,9 @@ if (app.Environment.IsDevelopment())
//c.RoutePrefix = "swagger";
//c.SwaggerEndpoint("/swagger/v1/swagger.json", "Your API V1");
});
//}
}
//}
//}
app.MapGet("/", () => "请求成功").WithName("默认请求");
//app.UseHttpsRedirection();
//使用跨域
app.UseCors(_myAllowSpecificOrigins);

View File

@ -14,7 +14,7 @@ namespace HuanMeng.StableDiffusion.TextGeneration.api.Tests
[TestMethod()]
public async Task SendMessageAsyncTest()
{
TextGenerationRequestHttpApi textGenerationRequestHttpApi = new TextGenerationRequestHttpApi();
TextGenerationRequestHttpApiStream textGenerationRequestHttpApi = new TextGenerationRequestHttpApi();
await foreach (var item in textGenerationRequestHttpApi.SendMessageAsync())
{
Console.WriteLine(item);