mirror of
https://github.com/gnh1201/welsonjs.git
synced 2025-05-07 12:16:04 +00:00
Update AzureAi.cs
This commit is contained in:
parent
916154499c
commit
2a9ebaff51
|
@ -1,5 +1,8 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.IO;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace WelsonJS.Launcher.ResourceTools
|
namespace WelsonJS.Launcher.ResourceTools
|
||||||
|
@ -7,11 +10,18 @@ namespace WelsonJS.Launcher.ResourceTools
|
||||||
public class AzureAi : IResourceTool
|
public class AzureAi : IResourceTool
|
||||||
{
|
{
|
||||||
private ResourceServer Server;
|
private ResourceServer Server;
|
||||||
|
private static readonly HttpClient HttpClient = new HttpClient();
|
||||||
private const string Prefix = "azure-ai/";
|
private const string Prefix = "azure-ai/";
|
||||||
|
private const int StreamingBufferSize = 4096;
|
||||||
|
private readonly string AzureAiServiceUrl;
|
||||||
|
private readonly string AzureAiServiceApiKey;
|
||||||
|
|
||||||
public AzureAi(ResourceServer server)
|
public AzureAi(ResourceServer server)
|
||||||
{
|
{
|
||||||
Server = server;
|
Server = server;
|
||||||
|
|
||||||
|
AzureAiServiceUrl = Program.GetAppConfig("AzureAiServiceUrl");
|
||||||
|
AzureAiServiceApiKey = Program.GetAppConfig("AzureAiServiceApiKey");
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool CanHandle(string path)
|
public bool CanHandle(string path)
|
||||||
|
@ -21,9 +31,107 @@ namespace WelsonJS.Launcher.ResourceTools
|
||||||
|
|
||||||
public async Task HandleAsync(HttpListenerContext context, string path)
|
public async Task HandleAsync(HttpListenerContext context, string path)
|
||||||
{
|
{
|
||||||
await Task.Delay(0);
|
string apiKey = AzureAiServiceApiKey;
|
||||||
|
if (string.IsNullOrEmpty(apiKey))
|
||||||
|
{
|
||||||
|
WriteError(context, "Missing 'api-key' header.", HttpStatusCode.BadRequest);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: Pass Azure AI request to Azure AI Foundry
|
string requestBody = ReadRequestBody(context);
|
||||||
|
bool isStreaming = ContainsSequentialKeywords(requestBody, new[] { "\"stream\"", "true" }, 30);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using (var response = await SendAzureRequestAsync(apiKey, requestBody, isStreaming))
|
||||||
|
{
|
||||||
|
await ForwardResponseAsync(context, response, isStreaming);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (HttpRequestException ex)
|
||||||
|
{
|
||||||
|
WriteError(context, "Request error: " + ex.Message, HttpStatusCode.BadGateway);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private string ReadRequestBody(HttpListenerContext context)
|
||||||
|
{
|
||||||
|
using (var reader = new StreamReader(context.Request.InputStream, context.Request.ContentEncoding))
|
||||||
|
{
|
||||||
|
return reader.ReadToEnd();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<HttpResponseMessage> SendAzureRequestAsync(string apiKey, string requestBody, bool isStreaming)
|
||||||
|
{
|
||||||
|
var requestMessage = new HttpRequestMessage(HttpMethod.Post, AzureAiServiceUrl);
|
||||||
|
requestMessage.Headers.Add("api-key", apiKey);
|
||||||
|
requestMessage.Content = new StringContent(requestBody, Encoding.UTF8, "application/json");
|
||||||
|
|
||||||
|
var completionOption = isStreaming
|
||||||
|
? HttpCompletionOption.ResponseHeadersRead
|
||||||
|
: HttpCompletionOption.ResponseContentRead;
|
||||||
|
|
||||||
|
return await HttpClient.SendAsync(requestMessage, completionOption);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task ForwardResponseAsync(HttpListenerContext context, HttpResponseMessage response, bool isStreaming)
|
||||||
|
{
|
||||||
|
context.Response.StatusCode = (int)response.StatusCode;
|
||||||
|
context.Response.ContentType = response.Content.Headers.ContentType?.ToString() ?? "application/json";
|
||||||
|
|
||||||
|
using (var responseStream = await response.Content.ReadAsStreamAsync())
|
||||||
|
{
|
||||||
|
if (isStreaming)
|
||||||
|
{
|
||||||
|
context.Response.SendChunked = true;
|
||||||
|
context.Response.Headers.Add("Transfer-Encoding", "chunked");
|
||||||
|
context.Response.Headers.Add("Cache-Control", "no-cache");
|
||||||
|
|
||||||
|
byte[] buffer = new byte[StreamingBufferSize];
|
||||||
|
int bytesRead;
|
||||||
|
while ((bytesRead = await responseStream.ReadAsync(buffer, 0, buffer.Length)) > 0)
|
||||||
|
{
|
||||||
|
await context.Response.OutputStream.WriteAsync(buffer, 0, bytesRead);
|
||||||
|
context.Response.OutputStream.Flush();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
await responseStream.CopyToAsync(context.Response.OutputStream);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void WriteError(HttpListenerContext context, string message, HttpStatusCode statusCode)
|
||||||
|
{
|
||||||
|
context.Response.StatusCode = (int)statusCode;
|
||||||
|
using (var writer = new StreamWriter(context.Response.OutputStream, Encoding.UTF8))
|
||||||
|
{
|
||||||
|
writer.Write(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool ContainsSequentialKeywords(string input, string[] keywords, int maxDistance)
|
||||||
|
{
|
||||||
|
if (input == null || keywords == null || keywords.Length < 2)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
int position = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < keywords.Length; i++)
|
||||||
|
{
|
||||||
|
int index = input.IndexOf(keywords[i], position, StringComparison.OrdinalIgnoreCase);
|
||||||
|
if (index < 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (i > 0 && (index - position) > maxDistance)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
position = index + keywords[i].Length;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user