feat: 完成功能
This commit is contained in:
@@ -258,7 +258,7 @@ public class ThorChatCompletionsRequest
|
|||||||
[JsonPropertyName("response_format")]
|
[JsonPropertyName("response_format")]
|
||||||
public ThorResponseFormat? ResponseFormat { get; set; }
|
public ThorResponseFormat? ResponseFormat { get; set; }
|
||||||
|
|
||||||
[JsonPropertyName("metadata")] public Dictionary<string, string> Metadata { get; set; }
|
[JsonPropertyName("metadata")] public Dictionary<string, string>? Metadata { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 此功能处于测试阶段。
|
/// 此功能处于测试阶段。
|
||||||
@@ -273,9 +273,9 @@ public class ThorChatCompletionsRequest
|
|||||||
/// 代表您的最终用户的唯一标识符,可以帮助 OpenAI 监控和检测滥用行为。
|
/// 代表您的最终用户的唯一标识符,可以帮助 OpenAI 监控和检测滥用行为。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[JsonPropertyName("user")]
|
[JsonPropertyName("user")]
|
||||||
public string User { get; set; }
|
public string? User { get; set; }
|
||||||
|
|
||||||
[JsonPropertyName("thinking")] public ThorChatClaudeThinking Thinking { get; set; }
|
[JsonPropertyName("thinking")] public ThorChatClaudeThinking? Thinking { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 参数验证
|
/// 参数验证
|
||||||
|
|||||||
@@ -92,6 +92,7 @@ public class AiChatService : ApplicationService
|
|||||||
/// 发送消息
|
/// 发送消息
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="input"></param>
|
/// <param name="input"></param>
|
||||||
|
/// <param name="sessionId"></param>
|
||||||
/// <param name="cancellationToken"></param>
|
/// <param name="cancellationToken"></param>
|
||||||
public async Task PostSendAsync([FromBody] ThorChatCompletionsRequest input, [FromQuery] Guid sessionId,
|
public async Task PostSendAsync([FromBody] ThorChatCompletionsRequest input, [FromQuery] Guid sessionId,
|
||||||
CancellationToken cancellationToken)
|
CancellationToken cancellationToken)
|
||||||
|
|||||||
@@ -50,5 +50,10 @@ public class AiModelDescribe
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 额外url
|
/// 额外url
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string? ExtraUrl { get; set; }
|
public string? AppExtraUrl { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 模型额外信息
|
||||||
|
/// </summary>
|
||||||
|
public string? ModelExtraInfo { get; set; }
|
||||||
}
|
}
|
||||||
@@ -12,18 +12,19 @@ namespace Yi.Framework.AiHub.Domain.AiGateWay.Impl.ThorAzureDatabricks.Chats;
|
|||||||
public class AzureDatabricksChatCompletionsService(ILogger<AzureDatabricksChatCompletionsService> logger)
|
public class AzureDatabricksChatCompletionsService(ILogger<AzureDatabricksChatCompletionsService> logger)
|
||||||
: IChatCompletionService
|
: IChatCompletionService
|
||||||
{
|
{
|
||||||
private string GetAddress(AiModelDescribe? options, string model)
|
private string GetAddress(AiModelDescribe? options)
|
||||||
{
|
{
|
||||||
// This method should return the appropriate URL for the Azure Databricks API
|
// This method should return the appropriate URL for the Azure Databricks API
|
||||||
// based on the provided options and model.
|
// based on the provided options and model.
|
||||||
// For now, we will return a placeholder URL.
|
// For now, we will return a placeholder URL.
|
||||||
return $"{options?.Endpoint.TrimEnd('/')}/serving-endpoints/{model}/invocations";
|
return $"{options?.Endpoint.TrimEnd('/')}/serving-endpoints/{options.ModelExtraInfo}/invocations";
|
||||||
}
|
}
|
||||||
|
|
||||||
public async IAsyncEnumerable<ThorChatCompletionsResponse> CompleteChatStreamAsync(AiModelDescribe options, ThorChatCompletionsRequest chatCompletionCreate,
|
public async IAsyncEnumerable<ThorChatCompletionsResponse> CompleteChatStreamAsync(AiModelDescribe options,
|
||||||
|
ThorChatCompletionsRequest chatCompletionCreate,
|
||||||
CancellationToken cancellationToken)
|
CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var address = GetAddress(options, chatCompletionCreate.Model);
|
var address = GetAddress(options);
|
||||||
using var openai =
|
using var openai =
|
||||||
Activity.Current?.Source.StartActivity("OpenAI 对话流式补全");
|
Activity.Current?.Source.StartActivity("OpenAI 对话流式补全");
|
||||||
|
|
||||||
@@ -138,10 +139,11 @@ public class AzureDatabricksChatCompletionsService(ILogger<AzureDatabricksChatCo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<ThorChatCompletionsResponse> CompleteChatAsync(AiModelDescribe options, ThorChatCompletionsRequest chatCompletionCreate,
|
public async Task<ThorChatCompletionsResponse> CompleteChatAsync(AiModelDescribe options,
|
||||||
|
ThorChatCompletionsRequest chatCompletionCreate,
|
||||||
CancellationToken cancellationToken)
|
CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var address = GetAddress(options, chatCompletionCreate.Model);
|
var address = GetAddress(options);
|
||||||
|
|
||||||
using var openai =
|
using var openai =
|
||||||
Activity.Current?.Source.StartActivity("OpenAI 对话补全");
|
Activity.Current?.Source.StartActivity("OpenAI 对话补全");
|
||||||
@@ -168,7 +170,8 @@ public class AzureDatabricksChatCompletionsService(ILogger<AzureDatabricksChatCo
|
|||||||
if (response.StatusCode >= HttpStatusCode.BadRequest)
|
if (response.StatusCode >= HttpStatusCode.BadRequest)
|
||||||
{
|
{
|
||||||
var error = await response.Content.ReadAsStringAsync(cancellationToken).ConfigureAwait(false);
|
var error = await response.Content.ReadAsStringAsync(cancellationToken).ConfigureAwait(false);
|
||||||
logger.LogError("OpenAI对话异常 请求地址:{Address}, StatusCode: {StatusCode} Response: {Response}", options.Endpoint,
|
logger.LogError("OpenAI对话异常 请求地址:{Address}, StatusCode: {StatusCode} Response: {Response}",
|
||||||
|
options.Endpoint,
|
||||||
response.StatusCode, error);
|
response.StatusCode, error);
|
||||||
|
|
||||||
throw new BusinessException("OpenAI对话异常", response.StatusCode.ToString());
|
throw new BusinessException("OpenAI对话异常", response.StatusCode.ToString());
|
||||||
|
|||||||
@@ -18,47 +18,47 @@ public static class AzureOpenAIFactory
|
|||||||
|
|
||||||
public static string GetAudioTranscriptionsAddress(AiModelDescribe options, string model)
|
public static string GetAudioTranscriptionsAddress(AiModelDescribe options, string model)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(options.ExtraUrl))
|
if (string.IsNullOrEmpty(options.AppExtraUrl))
|
||||||
{
|
{
|
||||||
options.ExtraUrl = "2025-03-01-preview";
|
options.AppExtraUrl = "2025-03-01-preview";
|
||||||
}
|
}
|
||||||
|
|
||||||
return string.Format(AudioTranscriptions, options.Endpoint.TrimEnd('/'), model, options.ExtraUrl);
|
return string.Format(AudioTranscriptions, options.Endpoint.TrimEnd('/'), model, options.AppExtraUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string GetAudioSpeechAddress(AiModelDescribe options, string model)
|
public static string GetAudioSpeechAddress(AiModelDescribe options, string model)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(options.ExtraUrl))
|
if (string.IsNullOrEmpty(options.AppExtraUrl))
|
||||||
{
|
{
|
||||||
options.ExtraUrl = "2025-03-01-preview";
|
options.AppExtraUrl = "2025-03-01-preview";
|
||||||
}
|
}
|
||||||
|
|
||||||
return string.Format(AudioSpeechTemplate, options.Endpoint.TrimEnd('/'), model, options.ExtraUrl);
|
return string.Format(AudioSpeechTemplate, options.Endpoint.TrimEnd('/'), model, options.AppExtraUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string GetAddress(AiModelDescribe options, string model)
|
public static string GetAddress(AiModelDescribe options, string model)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(options.ExtraUrl))
|
if (string.IsNullOrEmpty(options.AppExtraUrl))
|
||||||
{
|
{
|
||||||
options.ExtraUrl = "2025-03-01-preview";
|
options.AppExtraUrl = "2025-03-01-preview";
|
||||||
}
|
}
|
||||||
|
|
||||||
return string.Format(AddressTemplate, options.Endpoint.TrimEnd('/'), model, options.ExtraUrl);
|
return string.Format(AddressTemplate, options.Endpoint.TrimEnd('/'), model, options.AppExtraUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string GetEditImageAddress(AiModelDescribe options, string model)
|
public static string GetEditImageAddress(AiModelDescribe options, string model)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(options.ExtraUrl))
|
if (string.IsNullOrEmpty(options.AppExtraUrl))
|
||||||
{
|
{
|
||||||
options.ExtraUrl = "2025-03-01-preview";
|
options.AppExtraUrl = "2025-03-01-preview";
|
||||||
}
|
}
|
||||||
|
|
||||||
return string.Format(EditImageAddressTemplate, options.Endpoint.TrimEnd('/'), model, options.ExtraUrl);
|
return string.Format(EditImageAddressTemplate, options.Endpoint.TrimEnd('/'), model, options.AppExtraUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static AzureOpenAIClient CreateClient(AiModelDescribe options)
|
public static AzureOpenAIClient CreateClient(AiModelDescribe options)
|
||||||
{
|
{
|
||||||
return Clients.GetOrAdd($"{options.ApiKey}_{options.Endpoint}_{options.ExtraUrl}", (_) =>
|
return Clients.GetOrAdd($"{options.ApiKey}_{options.Endpoint}_{options.AppExtraUrl}", (_) =>
|
||||||
{
|
{
|
||||||
const AzureOpenAIClientOptions.ServiceVersion version = AzureOpenAIClientOptions.ServiceVersion.V2024_06_01;
|
const AzureOpenAIClientOptions.ServiceVersion version = AzureOpenAIClientOptions.ServiceVersion.V2024_06_01;
|
||||||
|
|
||||||
|
|||||||
@@ -45,4 +45,8 @@ public class AiModelEntity : Entity<Guid>, IOrderNum,ISoftDelete
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public Guid AiAppId { get; set; }
|
public Guid AiAppId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 额外信息
|
||||||
|
/// </summary>
|
||||||
|
public string? ExtraInfo { get; set; }
|
||||||
}
|
}
|
||||||
@@ -56,7 +56,8 @@ public class AiGateWayManager : DomainService
|
|||||||
ModelId = model.ModelId,
|
ModelId = model.ModelId,
|
||||||
ModelName = model.Name,
|
ModelName = model.Name,
|
||||||
Description = model.Description,
|
Description = model.Description,
|
||||||
ExtraUrl = app.ExtraUrl
|
AppExtraUrl = app.ExtraUrl,
|
||||||
|
ModelExtraInfo = model.ExtraInfo
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user