feat: Thor搭建
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
using SqlSugar;
|
||||
using Yi.Framework.AiHub.Application.Contracts.Dtos.OpenAi;
|
||||
using Yi.Framework.AiHub.Domain.Shared.Dtos;
|
||||
|
||||
namespace Yi.Framework.AiHub.Application.Contracts.Dtos;
|
||||
@@ -10,5 +11,5 @@ public class MessageInputDto
|
||||
public string ModelId { get; set; }
|
||||
public string? Remark { get; set; }
|
||||
|
||||
public TokenUsage? TokenUsage { get; set; }
|
||||
public ThorUsageResponse? TokenUsage { get; set; }
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
using System.Collections;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace Yi.Framework.AiHub.Application.Contracts.Dtos.OpenAiDto;
|
||||
|
||||
public class ChatCompletionsInput
|
||||
{
|
||||
public List<OpenAiMessage> Messages { get; set; }
|
||||
|
||||
public bool? Stream { get; set; }
|
||||
|
||||
public string? Prompt { get; set; }
|
||||
public string Model { get; set; }
|
||||
|
||||
public decimal? Temperature { get; set; }
|
||||
|
||||
public int? max_tokens { get; set; }
|
||||
}
|
||||
|
||||
public class OpenAiMessage
|
||||
{
|
||||
public string? Role { get; set; }
|
||||
public object? Content { get; set; }
|
||||
|
||||
public string ConvertContent()
|
||||
{
|
||||
if (Content is string content)
|
||||
{
|
||||
return content;
|
||||
}
|
||||
|
||||
if (Content is JsonElement jsonElement && jsonElement.ValueKind == JsonValueKind.Array)
|
||||
{
|
||||
var contentItems = jsonElement.Deserialize<List<ContentItem>>();
|
||||
var currentContentItem = contentItems.FirstOrDefault();
|
||||
if (currentContentItem.type == "text")
|
||||
{
|
||||
return currentContentItem.text;
|
||||
}
|
||||
}
|
||||
|
||||
throw new UserFriendlyException("当前格式暂不支持");
|
||||
}
|
||||
}
|
||||
|
||||
public class ContentItem
|
||||
{
|
||||
public string? type { get; set; }
|
||||
public string? text { get; set; }
|
||||
}
|
||||
@@ -1,115 +0,0 @@
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Yi.Framework.AiHub.Application.Contracts.Dtos.OpenAi;
|
||||
|
||||
public class ChatCompletionsOutput
|
||||
{
|
||||
[JsonProperty("id")]
|
||||
public string Id { get; set; }
|
||||
[JsonProperty("object")]
|
||||
public string Object { get; set; }
|
||||
[JsonProperty("created_at")]
|
||||
public long CreatedAt { get; set; }
|
||||
[JsonProperty("status")]
|
||||
public string Status { get; set; }
|
||||
[JsonProperty("error")]
|
||||
public object Error { get; set; }
|
||||
[JsonProperty("incomplete_details")]
|
||||
public object IncompleteDetails { get; set; }
|
||||
[JsonProperty("instructions")]
|
||||
public object Instructions { get; set; }
|
||||
[JsonProperty("max_output_tokens")]
|
||||
public object MaxOutputTokens { get; set; }
|
||||
[JsonProperty("model")]
|
||||
public string Model { get; set; }
|
||||
[JsonProperty("output")]
|
||||
public List<Output> Output { get; set; }
|
||||
[JsonProperty("parallel_tool_calls")]
|
||||
public bool ParallelToolCalls { get; set; }
|
||||
[JsonProperty("previous_response_id")]
|
||||
public object PreviousResponseId { get; set; }
|
||||
[JsonProperty("reasoning")]
|
||||
public Reasoning Reasoning { get; set; }
|
||||
[JsonProperty("store")]
|
||||
public bool Store { get; set; }
|
||||
[JsonProperty("temperature")]
|
||||
public double Temperature { get; set; }
|
||||
[JsonProperty("text")]
|
||||
public Text Text { get; set; }
|
||||
[JsonProperty("tool_choice")]
|
||||
public string ToolChoice { get; set; }
|
||||
[JsonProperty("tools")]
|
||||
public List<object> Tools { get; set; }
|
||||
[JsonProperty("top_p")]
|
||||
public double TopP { get; set; }
|
||||
[JsonProperty("truncation")]
|
||||
public string Truncation { get; set; }
|
||||
[JsonProperty("usage")]
|
||||
public Usage Usage { get; set; }
|
||||
[JsonProperty("user")]
|
||||
public object User { get; set; }
|
||||
[JsonProperty("metadata")]
|
||||
public Dictionary<string, object> Metadata { get; set; }
|
||||
}
|
||||
public class Output
|
||||
{
|
||||
[JsonProperty("type")]
|
||||
public string Type { get; set; }
|
||||
[JsonProperty("id")]
|
||||
public string Id { get; set; }
|
||||
[JsonProperty("status")]
|
||||
public string Status { get; set; }
|
||||
[JsonProperty("role")]
|
||||
public string Role { get; set; }
|
||||
[JsonProperty("content")]
|
||||
public List<Content> Content { get; set; }
|
||||
}
|
||||
public class Content
|
||||
{
|
||||
[JsonProperty("type")]
|
||||
public string Type { get; set; }
|
||||
[JsonProperty("text")]
|
||||
public string Text { get; set; }
|
||||
[JsonProperty("annotations")]
|
||||
public List<object> Annotations { get; set; }
|
||||
}
|
||||
public class Reasoning
|
||||
{
|
||||
[JsonProperty("effort")]
|
||||
public object Effort { get; set; }
|
||||
[JsonProperty("summary")]
|
||||
public object Summary { get; set; }
|
||||
}
|
||||
public class Text
|
||||
{
|
||||
[JsonProperty("format")]
|
||||
public Format Format { get; set; }
|
||||
}
|
||||
public class Format
|
||||
{
|
||||
[JsonProperty("type")]
|
||||
public string Type { get; set; }
|
||||
}
|
||||
public class Usage
|
||||
{
|
||||
[JsonProperty("input_tokens")]
|
||||
public int InputTokens { get; set; }
|
||||
[JsonProperty("input_tokens_details")]
|
||||
public InputTokensDetails InputTokensDetails { get; set; }
|
||||
[JsonProperty("output_tokens")]
|
||||
public int OutputTokens { get; set; }
|
||||
[JsonProperty("output_tokens_details")]
|
||||
public OutputTokensDetails OutputTokensDetails { get; set; }
|
||||
[JsonProperty("total_tokens")]
|
||||
public int TotalTokens { get; set; }
|
||||
}
|
||||
public class InputTokensDetails
|
||||
{
|
||||
[JsonProperty("cached_tokens")]
|
||||
public int CachedTokens { get; set; }
|
||||
}
|
||||
public class OutputTokensDetails
|
||||
{
|
||||
[JsonProperty("reasoning_tokens")]
|
||||
public int ReasoningTokens { get; set; }
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
namespace Yi.Framework.AiHub.Application.Contracts.Dtos.OpenAiDto;
|
||||
|
||||
public class ModelGetOutput
|
||||
{
|
||||
public List<ModelDataOutput> Data { get; set; }
|
||||
}
|
||||
|
||||
public class ModelDataOutput
|
||||
{
|
||||
public string ModelId { get; set; }
|
||||
public string Object { get; set; }
|
||||
public string Owned_by { get; set; }
|
||||
public List<string> Permission { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Yi.Framework.AiHub.Application.Contracts.Dtos.OpenAi;
|
||||
|
||||
public class ModelsListDto
|
||||
{
|
||||
[JsonPropertyName("object")] public string @object { get; set; }
|
||||
|
||||
[JsonPropertyName("data")] public List<ModelsDataDto> Data { get; set; }
|
||||
|
||||
public ModelsListDto()
|
||||
{
|
||||
Data = new();
|
||||
}
|
||||
}
|
||||
|
||||
public class ModelsDataDto
|
||||
{
|
||||
[JsonPropertyName("id")] public string Id { get; set; }
|
||||
|
||||
[JsonPropertyName("object")] public string @object { get; set; }
|
||||
|
||||
[JsonPropertyName("created")] public long Created { get; set; }
|
||||
|
||||
[JsonPropertyName("owned_by")] public string OwnedBy { get; set; }
|
||||
|
||||
[JsonPropertyName("type")] public string Type { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
namespace Yi.Framework.AiHub.Application.Contracts.Dtos.OpenAi;
|
||||
|
||||
/// <summary>
|
||||
/// OpenAI常量
|
||||
/// </summary>
|
||||
public static class OpenAIConstant
|
||||
{
|
||||
/// <summary>
|
||||
/// 字符串utf-8编码
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public const string Done = "[DONE]";
|
||||
|
||||
/// <summary>
|
||||
/// Data: 协议头
|
||||
/// </summary>
|
||||
public const string Data = "data:";
|
||||
|
||||
/// <summary>
|
||||
/// think: 协议头
|
||||
/// </summary>
|
||||
public const string ThinkStart = "<think>";
|
||||
|
||||
/// <summary>
|
||||
/// think: 协议尾
|
||||
/// </summary>
|
||||
public const string ThinkEnd = "</think>";
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Yi.Framework.AiHub.Application.Contracts.Dtos.OpenAi;
|
||||
|
||||
public sealed class ThorChatAudioRequest
|
||||
{
|
||||
[JsonPropertyName("voice")]
|
||||
public string? Voice { get; set; }
|
||||
|
||||
[JsonPropertyName("format")]
|
||||
public string? Format { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Yi.Framework.AiHub.Application.Contracts.Dtos.OpenAi;
|
||||
|
||||
/// <summary>
|
||||
/// 聊天完成选项列
|
||||
/// </summary>
|
||||
public record ThorChatChoiceResponse
|
||||
{
|
||||
/// <summary>
|
||||
/// 模型生成的聊天完成消息。【流式】模型响应生成的聊天完成增量存储在此属性。<br/>
|
||||
/// 在当前模型中,无论流式还是非流式,Message 和 Delta存储相同的值
|
||||
/// </summary>
|
||||
[JsonPropertyName("delta")]
|
||||
public ThorChatMessage Delta
|
||||
{
|
||||
get => Message;
|
||||
set => Message = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 模型生成的聊天完成消息。【非流式】返回的消息存储在此属性。<br/>
|
||||
/// 在当前模型中,无论流式还是非流式,Message 和 Delta存储相同的值
|
||||
/// </summary>
|
||||
[JsonPropertyName("message")]
|
||||
public ThorChatMessage Message { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 选项列表中选项的索引。
|
||||
/// </summary>
|
||||
[JsonPropertyName("index")]
|
||||
public int? Index { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 用于处理请求的服务层。仅当在请求中指定了 service_tier 参数时,才包含此字段。
|
||||
/// </summary>
|
||||
[JsonPropertyName("service_tier")]
|
||||
public string? ServiceTier { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 模型停止生成令牌的原因。
|
||||
/// stop 如果模型达到自然停止点或提供的停止序列,
|
||||
/// length 如果达到请求中指定的最大标记数,
|
||||
/// content_filter 如果由于内容过滤器中的标志而省略了内容,
|
||||
/// tool_calls 如果模型调用了工具,或者 function_call (已弃用)
|
||||
/// 如果模型调用了函数,则会出现这种情况。
|
||||
/// </summary>
|
||||
[JsonPropertyName("finish_reason")]
|
||||
public string? FinishReason { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 此指纹表示模型运行时使用的后端配置。
|
||||
/// 可以与 seed 请求参数结合使用,以了解何时进行了可能影响确定性的后端更改。
|
||||
/// </summary>
|
||||
[JsonPropertyName("finish_details")]
|
||||
public FinishDetailsResponse? FinishDetails { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class FinishDetailsResponse
|
||||
{
|
||||
[JsonPropertyName("type")] public string Type { get; set; }
|
||||
[JsonPropertyName("stop")] public string Stop { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Yi.Framework.AiHub.Application.Contracts.Dtos.OpenAi;
|
||||
|
||||
public class ThorChatClaudeThinking
|
||||
{
|
||||
[JsonPropertyName("type")]
|
||||
public string? Type { get; set; }
|
||||
|
||||
[JsonPropertyName("budget_tokens")]
|
||||
public int? BudgetToken { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,289 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Yi.Framework.AiHub.Application.Contracts.Dtos.OpenAi;
|
||||
|
||||
/// <summary>
|
||||
/// 对话补全请求参数对象
|
||||
/// </summary>
|
||||
public class ThorChatCompletionsRequest
|
||||
{
|
||||
public ThorChatCompletionsRequest()
|
||||
{
|
||||
Messages = new List<ThorChatMessage>();
|
||||
}
|
||||
|
||||
[JsonPropertyName("store")]
|
||||
public bool? Store { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 表示对话中支持的模态类型数组。可以为 null。
|
||||
/// </summary>
|
||||
[JsonPropertyName("modalities")]
|
||||
public string[]? Modalities { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 表示对话中的音频请求参数。可以为 null。
|
||||
/// </summary>
|
||||
[JsonPropertyName("audio")] public ThorChatAudioRequest? Audio { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 包含迄今为止对话的消息列表
|
||||
/// </summary>
|
||||
[JsonPropertyName("messages")]
|
||||
public List<ThorChatMessage> Messages { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 模型唯一编码值,如 gpt-4,gpt-3.5-turbo,moonshot-v1-8k,看底层具体平台定义
|
||||
/// </summary>
|
||||
[JsonPropertyName("model")]
|
||||
public string Model { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 温度采样的替代方法称为核采样,介于 0 和 1 之间,其中模型考虑具有 top_p 概率质量的标记的结果。
|
||||
/// 因此 0.1 意味着仅考虑包含前 10% 概率质量的标记。
|
||||
/// 我们通常建议更改此项或 temperature ,但不要同时更改两者。
|
||||
/// 默认 1
|
||||
/// </summary>
|
||||
[JsonPropertyName("top_p")]
|
||||
public float? TopP { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 使用什么采样温度,介于 0 和 2 之间。
|
||||
/// 较高的值(如 0.8)将使输出更加随机,而较低的值(如 0.2)将使其更加集中和确定性。
|
||||
/// 我们通常建议更改此项或 top_p ,但不要同时更改两者。
|
||||
/// 默认 1
|
||||
/// </summary>
|
||||
[JsonPropertyName("temperature")]
|
||||
public float? Temperature { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 为每条输入消息生成多少个结果
|
||||
/// <para>
|
||||
/// 默认为 1,不得大于 5。特别的,当 temperature 非常小靠近 0 的时候,
|
||||
/// 我们只能返回 1 个结果,如果这个时候 n 已经设置并且 > 1,
|
||||
/// 我们的服务会返回不合法的输入参数(invalid_request_error)
|
||||
/// </para>
|
||||
/// </summary>
|
||||
[JsonPropertyName("n")]
|
||||
public int? N { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 如果设置,将发送部分消息增量,就像在 ChatGPT 中一样。
|
||||
/// 令牌可用时将作为仅数据服务器发送事件发送,流由 data: [DONE] 消息终止。
|
||||
/// </summary>
|
||||
[JsonPropertyName("stream")]
|
||||
public bool? Stream { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 流响应选项。仅当您设置 stream: true 时才设置此项。
|
||||
/// </summary>
|
||||
[JsonPropertyName("stream_options")]
|
||||
public ThorStreamOptions? StreamOptions { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 停止词,当全匹配这个(组)词后会停止输出,这个(组)词本身不会输出。
|
||||
/// 最多不能超过 5 个字符串,每个字符串不得超过 32 字节,
|
||||
/// 默认 null
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
public string? Stop { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 停止词,当全匹配这个(组)词后会停止输出,这个(组)词本身不会输出。
|
||||
/// 最多不能超过 5 个字符串,每个字符串不得超过 32 字节,
|
||||
/// 默认 null
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
public IList<string>? StopAsList { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 停止词,当全匹配这个(组)词后会停止输出,这个(组)词本身不会输出。
|
||||
/// 最多不能超过 5 个字符串,每个字符串不得超过 32 字节,
|
||||
/// 默认 null
|
||||
/// </summary>
|
||||
[JsonPropertyName("stop")]
|
||||
public IList<string>? StopCalculated
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Stop is not null && StopAsList is not null)
|
||||
{
|
||||
throw new ValidationException(
|
||||
"Stop 和 StopAsList 不能同时有值,其中一个应该为 null");
|
||||
}
|
||||
|
||||
if (Stop is not null)
|
||||
{
|
||||
return new List<string> { Stop };
|
||||
}
|
||||
|
||||
return StopAsList;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 生成的答案允许的最大令牌数。默认情况下,模型可以返回的令牌数量为(4096个提示令牌)。
|
||||
/// </summary>
|
||||
/// <see href="https://platform.openai.com/docs/api-reference/completions/create#completions/create-max_tokens" />
|
||||
[JsonPropertyName("max_tokens")]
|
||||
public int? MaxTokens { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 可为补全生成的令牌数量的上限,包括可见输出令牌和推理令牌。
|
||||
/// </summary>
|
||||
[JsonPropertyName("max_completion_tokens")]
|
||||
public int? MaxCompletionTokens { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 存在惩罚,介于 -2.0 到 2.0 之间的数字。
|
||||
/// 正值会根据新生成的词汇是否出现在文本中来进行惩罚,增加模型讨论新话题的可能性,
|
||||
/// 默认为 0
|
||||
/// </summary>
|
||||
/// <seealso href="https://platform.openai.com/docs/api-reference/parameter-details" />
|
||||
[JsonPropertyName("presence_penalty")]
|
||||
public float? PresencePenalty { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 频率惩罚,介于-2.0到2.0之间的数字。
|
||||
/// 正值会根据新生成的词汇在文本中现有的频率来进行惩罚,减少模型一字不差重复同样话语的可能性.
|
||||
/// 默认为 0
|
||||
/// </summary>
|
||||
/// <seealso href="https://platform.openai.com/docs/api-reference/parameter-details" />
|
||||
[JsonPropertyName("frequency_penalty")]
|
||||
public float? FrequencyPenalty { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 接受一个 JSON 对象,该对象将标记(由标记生成器中的标记 ID 指定)映射到从 -100 到 100 的关联偏差值。
|
||||
/// 从数学上讲,偏差会在采样之前添加到模型生成的 logits 中。
|
||||
/// 每个模型的确切效果会有所不同,但 -1 和 1 之间的值应该会降低或增加选择的可能性;
|
||||
/// 像 -100 或 100 这样的值应该会导致相关令牌的禁止或独占选择。
|
||||
/// </summary>
|
||||
/// <seealso href="https://platform.openai.com/tokenizer?view=bpe" />
|
||||
[JsonPropertyName("logit_bias")]
|
||||
public object? LogitBias { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否返回输出标记的对数概率。如果为 true,则返回 message 的 content 中返回的每个输出标记的对数概率。
|
||||
/// </summary>
|
||||
[JsonPropertyName("logprobs")]
|
||||
public bool? Logprobs { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 0 到 20 之间的整数,指定每个标记位置最有可能返回的标记数量,每个标记都有关联的对数概率。
|
||||
/// 如果使用此参数, logprobs 必须设置为 true 。
|
||||
/// </summary>
|
||||
[JsonPropertyName("top_logprobs")]
|
||||
public int? TopLogprobs { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 指定用于处理请求的延迟层。此参数与订阅规模层服务的客户相关:
|
||||
/// 如果设置为“auto”,系统将使用规模等级积分,直至用完。
|
||||
/// 如果设置为“default”,则将使用具有较低正常运行时间 SLA 且无延迟保证的默认服务层来处理请求。
|
||||
/// 默认null
|
||||
/// </summary>
|
||||
[JsonPropertyName("service_tier")]
|
||||
public string? ServiceTier { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 模型可能调用的工具列表。目前,仅支持函数作为工具。使用它来提供模型可以为其生成 JSON 输入的函数列表。最多支持 128 个功能。
|
||||
/// </summary>
|
||||
[JsonPropertyName("tools")]
|
||||
public List<ThorToolDefinition>? Tools { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 控制模型调用哪个(如果有)工具。
|
||||
/// none 表示模型不会调用任何工具,而是生成一条消息。
|
||||
/// auto 表示模型可以在生成消息或调用一个或多个工具之间进行选择。
|
||||
/// required 表示模型必须调用一个或多个工具。
|
||||
/// 通过 {"type": "function", "function": {"name": "my_function"}} 指定特定工具会强制模型调用该工具。
|
||||
/// 当不存在任何工具时, none 是默认值。如果存在工具,则 auto 是默认值。
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
public ThorToolChoice? ToolChoice { get; set; }
|
||||
|
||||
[JsonPropertyName("tool_choice")]
|
||||
public object? ToolChoiceCalculated
|
||||
{
|
||||
get
|
||||
{
|
||||
if (ToolChoice != null &&
|
||||
ToolChoice.Type != ThorToolChoiceTypeConst.Function &&
|
||||
ToolChoice.Function != null)
|
||||
{
|
||||
throw new ValidationException(
|
||||
"当 type 为 \"function\" 时,属性 Function 不可为null。");
|
||||
}
|
||||
|
||||
if (ToolChoice?.Type == ThorToolChoiceTypeConst.Function)
|
||||
{
|
||||
return ToolChoice;
|
||||
}
|
||||
|
||||
return ToolChoice?.Type;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value is JsonElement jsonElement)
|
||||
{
|
||||
if (jsonElement.ValueKind == JsonValueKind.String)
|
||||
{
|
||||
ToolChoice = new ThorToolChoice
|
||||
{
|
||||
Type = jsonElement.GetString()
|
||||
};
|
||||
}
|
||||
else if (jsonElement.ValueKind == JsonValueKind.Object)
|
||||
{
|
||||
ToolChoice = jsonElement.Deserialize<ThorToolChoice>();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ToolChoice = (ThorToolChoice)value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置为 {"type": "json_object"} 可启用 JSON 模式,从而保证模型生成的信息是有效的 JSON。
|
||||
/// 当你将 response_format 设置为 {"type": "json_object"} 时,
|
||||
/// 你需要在 prompt 中明确地引导模型输出 JSON 格式的内容,
|
||||
/// 并告知模型该 JSON 的具体格式,否则将可能导致不符合预期的结果。
|
||||
/// 默认为 {"type": "text"}
|
||||
/// </summary>
|
||||
[JsonPropertyName("response_format")]
|
||||
public ThorResponseFormat? ResponseFormat { get; set; }
|
||||
|
||||
[JsonPropertyName("metadata")] public Dictionary<string, string> Metadata { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 此功能处于测试阶段。
|
||||
/// 如果指定,我们的系统将尽最大努力进行确定性采样,
|
||||
/// 以便具有相同 seed 和参数的重复请求应返回相同的结果。
|
||||
/// 不保证确定性,您应该参考 system_fingerprint 响应参数来监控后端的变化。
|
||||
/// </summary>
|
||||
[JsonPropertyName("seed")]
|
||||
public int? Seed { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 代表您的最终用户的唯一标识符,可以帮助 OpenAI 监控和检测滥用行为。
|
||||
/// </summary>
|
||||
[JsonPropertyName("user")]
|
||||
public string User { get; set; }
|
||||
|
||||
[JsonPropertyName("thinking")] public ThorChatClaudeThinking Thinking { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 参数验证
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="NotImplementedException"></exception>
|
||||
public IEnumerable<ValidationResult> Validate()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Yi.Framework.AiHub.Application.Contracts.Dtos.OpenAi;
|
||||
|
||||
/// <summary>
|
||||
/// 对话补全服务返回结果
|
||||
/// </summary>
|
||||
public record ThorChatCompletionsResponse
|
||||
{
|
||||
/// <summary>
|
||||
/// 对话补全的唯一标识符。<br/>
|
||||
/// 聊天完成的唯一标识符。如果是流式对话,每个区块都具有相同的 ID。
|
||||
/// </summary>
|
||||
[JsonPropertyName("id")]
|
||||
public string Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 用于对话补全的模型。
|
||||
/// </summary>
|
||||
[JsonPropertyName("model")]
|
||||
public string? Model { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 对象类型<br/>
|
||||
/// 非流式对话补全始终为 chat.completion<br/>
|
||||
/// 流式对话补全始终为 chat.completion.chunk<br/>
|
||||
/// </summary>
|
||||
[JsonPropertyName("object")]
|
||||
public string? ObjectTypeName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 对话补全选项列表。如果 n 大于 1,则可以是多个。
|
||||
/// </summary>
|
||||
[JsonPropertyName("choices")]
|
||||
public List<ThorChatChoiceResponse>? Choices { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 完成请求的使用情况统计信息。
|
||||
/// 仅在您 stream_options: {"include_usage": true} 设置请求时才会显示。
|
||||
/// 如果存在,则它包含一个 null 值,但最后一个块除外,该块包含整个请求的令牌使用情况统计信息。
|
||||
/// </summary>
|
||||
[JsonPropertyName("usage")]
|
||||
public ThorUsageResponse? Usage { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 创建对话补全时的 Unix 时间戳(以秒为单位)。
|
||||
/// </summary>
|
||||
[JsonPropertyName("created")]
|
||||
public int Created { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 此指纹表示模型运行时使用的后端配置。
|
||||
/// 可以与 seed 请求参数结合使用,以了解何时进行了可能影响确定性的后端更改。
|
||||
/// </summary>
|
||||
[JsonPropertyName("system_fingerprint")]
|
||||
public string SystemFingerPrint { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 错误信息
|
||||
/// </summary>
|
||||
[JsonPropertyName("error")]
|
||||
public ThorError? Error { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,193 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Yi.Framework.AiHub.Application.Contracts.Dtos.OpenAi;
|
||||
|
||||
/// <summary>
|
||||
/// 聊天消息体,建议使用CreeateXXX系列方法构建内容
|
||||
/// </summary>
|
||||
public class ThorChatMessage
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public ThorChatMessage()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 【必填】发出消息的角色,请使用<see cref="ThorChatMessageRoleConst.User"/>赋值,如:ThorChatMessageRoleConst.User
|
||||
/// </summary>
|
||||
[JsonPropertyName("role")]
|
||||
public string Role { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 发出的消息内容,如:你好
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
public string? Content { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 发出的消息内容,仅当使用 gpt-4o 模型时才支持图像输入。
|
||||
/// </summary>
|
||||
/// <example>
|
||||
/// 示例数据:
|
||||
/// "content": [
|
||||
/// {
|
||||
/// "type": "text",
|
||||
/// "text": "What'\''s in this image?"
|
||||
/// },
|
||||
/// {
|
||||
/// "type": "image_url",
|
||||
/// "image_url": {
|
||||
/// "url": "https://upload.wikimedia.org/wikipedia/commons/thumb/d/dd/Gfp-wisconsin-madison-the-nature-boardwalk.jpg/2560px-Gfp-wisconsin-madison-the-nature-boardwalk.jpg"
|
||||
/// }
|
||||
/// }
|
||||
/// ]
|
||||
/// </example>
|
||||
[JsonIgnore]
|
||||
public IList<ThorChatMessageContent>? Contents { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 发出的消息内容计算,用于json序列号和反序列化,Content 和 Contents 不能同时赋值,只能二选一
|
||||
/// </summary>
|
||||
[JsonPropertyName("content")]
|
||||
public object ContentCalculated
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Content is not null && Contents is not null)
|
||||
{
|
||||
throw new ValidationException("Messages 中 Content 和 Contents 字段不能同时有值");
|
||||
}
|
||||
|
||||
if (Content is not null)
|
||||
{
|
||||
return Content;
|
||||
}
|
||||
|
||||
return Contents!;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value is JsonElement str)
|
||||
{
|
||||
if (str.ValueKind == JsonValueKind.String)
|
||||
{
|
||||
Content = value?.ToString();
|
||||
}
|
||||
else if (str.ValueKind == JsonValueKind.Array)
|
||||
{
|
||||
Contents = JsonSerializer.Deserialize<IList<ThorChatMessageContent>>(value?.ToString());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Content = value?.ToString();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 【可选】参与者的可选名称。提供模型信息以区分相同角色的参与者。
|
||||
/// </summary>
|
||||
[JsonPropertyName("name")]
|
||||
public string? Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 工具调用 ID,此消息正在响应的工具调用。
|
||||
/// </summary>
|
||||
[JsonPropertyName("tool_call_id")]
|
||||
public string? ToolCallId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 函数调用,已过期,不要使用,请使用 ToolCalls
|
||||
/// </summary>
|
||||
[JsonPropertyName("function_call")]
|
||||
public ThorChatMessageFunction? FunctionCall { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 【可选】推理内容
|
||||
/// </summary>
|
||||
[JsonPropertyName("reasoning_content")]
|
||||
public string? ReasoningContent { get; set; }
|
||||
|
||||
[JsonPropertyName("id")]
|
||||
public string? Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 工具调用列表,模型生成的工具调用,例如函数调用。<br/>
|
||||
/// 此属性存储在客户端进行tool use 第一次调用模型返回的使用的函数名和传入的参数
|
||||
/// </summary>
|
||||
[JsonPropertyName("tool_calls")]
|
||||
public List<ThorToolCall>? ToolCalls { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 创建系统消息
|
||||
/// </summary>
|
||||
/// <param name="content">系统消息内容</param>
|
||||
/// <param name="name">参与者的可选名称。提供模型信息以区分同一角色的参与者。</param>
|
||||
/// <returns></returns>
|
||||
public static ThorChatMessage CreateSystemMessage(string content, string? name = null)
|
||||
{
|
||||
return new()
|
||||
{
|
||||
Role = ThorChatMessageRoleConst.System,
|
||||
Content = content,
|
||||
Name = name
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建用户消息
|
||||
/// </summary>
|
||||
/// <param name="content">系统消息内容</param>
|
||||
/// <param name="name">参与者的可选名称。提供模型信息以区分同一角色的参与者。</param>
|
||||
/// <returns></returns>
|
||||
public static ThorChatMessage CreateUserMessage(string content, string? name = null)
|
||||
{
|
||||
return new()
|
||||
{
|
||||
Role = ThorChatMessageRoleConst.User,
|
||||
Content = content,
|
||||
Name = name
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建助手消息
|
||||
/// </summary>
|
||||
/// <param name="content">系统消息内容</param>
|
||||
/// <param name="name">参与者的可选名称。提供模型信息以区分同一角色的参与者。</param>
|
||||
/// <param name="toolCalls">工具调用参数列表</param>
|
||||
/// <returns></returns>
|
||||
public static ThorChatMessage CreateAssistantMessage(string content, string? name = null, List<ThorToolCall> toolCalls = null)
|
||||
{
|
||||
return new()
|
||||
{
|
||||
Role = ThorChatMessageRoleConst.Assistant,
|
||||
Content = content,
|
||||
Name = name,
|
||||
ToolCalls=toolCalls,
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建工具消息
|
||||
/// </summary>
|
||||
/// <param name="content">系统消息内容</param>
|
||||
/// <param name="toolCallId">工具调用 ID,此消息正在响应的工具调用。</param>
|
||||
/// <returns></returns>
|
||||
public static ThorChatMessage CreateToolMessage(string content, string toolCallId = null)
|
||||
{
|
||||
return new()
|
||||
{
|
||||
Role = ThorChatMessageRoleConst.Tool,
|
||||
Content = content,
|
||||
ToolCallId= toolCallId
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
public sealed class ThorChatMessageAudioContent
|
||||
{
|
||||
[JsonPropertyName("data")]
|
||||
public string? Data { get; set; }
|
||||
|
||||
[JsonPropertyName("format")]
|
||||
public string? Format { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Yi.Framework.AiHub.Application.Contracts.Dtos.OpenAi;
|
||||
|
||||
/// <summary>
|
||||
/// 发出的消息内容,包含图文,一般是一文一图,一文多图两种情况,请使用CreeateXXX系列方法构建内容
|
||||
/// </summary>
|
||||
public class ThorChatMessageContent
|
||||
{
|
||||
public ThorChatMessageContent()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 消息内容类型,只能使用<see cref="ThorMessageContentTypeConst"/> 定义的值赋值,如:ThorMessageContentTypeConst.Text
|
||||
/// </summary>
|
||||
[JsonPropertyName("type")]
|
||||
public string Type { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 消息内容类型为 text 时候的赋值,如:图片上描述了什么
|
||||
/// </summary>
|
||||
[JsonPropertyName("text")]
|
||||
public string? Text { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 消息内容类型为 image_url 时候的赋值
|
||||
/// </summary>
|
||||
[JsonPropertyName("image_url")]
|
||||
public ThorVisionImageUrl? ImageUrl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 音频消息内容,包含音频数据和格式信息。
|
||||
/// </summary>
|
||||
[JsonPropertyName("input_audio")]
|
||||
public ThorChatMessageAudioContent? InputAudio { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 创建文本类消息
|
||||
/// <param name="text">文本内容</param>
|
||||
/// </summary>
|
||||
public static ThorChatMessageContent CreateTextContent(string text)
|
||||
{
|
||||
return new()
|
||||
{
|
||||
Type = ThorMessageContentTypeConst.Text,
|
||||
Text = text
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建图片类消息,图片url形式
|
||||
/// <param name="imageUrl">图片 url</param>
|
||||
/// <param name="detail">指定图像的详细程度。通过控制 detail 参数(该参数具有三个选项: low 、 high 或 auto ),您
|
||||
/// 可以控制模型的处理方式图像并生成其文本理解。默认情况下,模型将使用 auto 设置,
|
||||
/// 该设置将查看图像输入大小并决定是否应使用 low 或 high 设置。</param>
|
||||
/// </summary>
|
||||
public static ThorChatMessageContent CreateImageUrlContent(string imageUrl, string? detail = "auto")
|
||||
{
|
||||
return new()
|
||||
{
|
||||
Type = ThorMessageContentTypeConst.ImageUrl,
|
||||
ImageUrl = new()
|
||||
{
|
||||
Url = imageUrl,
|
||||
Detail = detail
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建图片类消息,字节流转base64字符串形式
|
||||
/// <param name="binaryImage">The image binary data as byte array</param>
|
||||
/// <param name="imageType">图片类型,如 png,jpg</param>
|
||||
/// <param name="detail">指定图像的详细程度。</param>
|
||||
/// </summary>
|
||||
public static ThorChatMessageContent CreateImageBinaryContent(
|
||||
byte[] binaryImage,
|
||||
string imageType,
|
||||
string? detail = "auto"
|
||||
)
|
||||
{
|
||||
return new()
|
||||
{
|
||||
Type = ThorMessageContentTypeConst.ImageUrl,
|
||||
ImageUrl = new()
|
||||
{
|
||||
Url = string.Format(
|
||||
"data:image/{0};base64,{1}",
|
||||
imageType,
|
||||
Convert.ToBase64String(binaryImage)
|
||||
),
|
||||
Detail = detail
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Yi.Framework.AiHub.Application.Contracts.Dtos.OpenAi
|
||||
{
|
||||
/// <summary>
|
||||
/// 模型调用的函数。
|
||||
/// </summary>
|
||||
public class ThorChatMessageFunction
|
||||
{
|
||||
/// <summary>
|
||||
/// 功能名,如:get_current_weather
|
||||
/// </summary>
|
||||
[JsonPropertyName("name")]
|
||||
public string? Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 调用函数所用的参数,由模型以 JSON 格式生成。请注意,该模型并不总是生成有效的 JSON,
|
||||
/// 并且可能会产生未由函数架构定义的参数。
|
||||
/// 在调用函数之前验证代码中的参数。
|
||||
/// 如:"{\"location\": \"San Francisco, USA\", \"format\": \"celsius\"}"
|
||||
/// </summary>
|
||||
[JsonPropertyName("arguments")]
|
||||
public string? Arguments { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 转换参数为字典
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public Dictionary<string, object> ParseArguments()
|
||||
{
|
||||
var result = string.IsNullOrWhiteSpace(Arguments) == false ? JsonSerializer.Deserialize<Dictionary<string, object>>(Arguments) : new Dictionary<string, object>();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
namespace Yi.Framework.AiHub.Application.Contracts.Dtos.OpenAi
|
||||
{
|
||||
/// <summary>
|
||||
/// 对话消息角色定义
|
||||
/// </summary>
|
||||
public class ThorChatMessageRoleConst
|
||||
{
|
||||
/// <summary>
|
||||
/// 系统角色
|
||||
/// <para>
|
||||
/// 用于为聊天助手分配特定的行为或上下文,以影响对话的模型行为。
|
||||
/// 例如,可以将系统角色设定为“您是足球专家”,
|
||||
/// 那么 ChatGPT 在对话中会表现出特定的个性或专业知识。
|
||||
/// </para>
|
||||
/// </summary>
|
||||
public static string System => "system";
|
||||
|
||||
/// <summary>
|
||||
/// 用户角色
|
||||
/// <para>
|
||||
/// 代表实际的最终用户,向 ChatGPT 发送提示或消息,
|
||||
/// 用于指示消息/提示来自最终用户或人类。
|
||||
/// </para>
|
||||
/// </summary>
|
||||
public static string User => "user";
|
||||
|
||||
/// <summary>
|
||||
/// 助手角色
|
||||
/// <para>
|
||||
/// 表示对最终用户提示的响应实体,用于保持对话的连贯性。
|
||||
/// 它是由模型自动生成并回复的,用于设置模型的先前响应,以继续对话流程。
|
||||
/// </para>
|
||||
/// </summary>
|
||||
public static string Assistant => "assistant";
|
||||
|
||||
/// <summary>
|
||||
/// 工具角色
|
||||
/// <para>
|
||||
/// 表示对最终用户提示的响应实体,用于保持对话的连贯性。
|
||||
/// 它是由模型自动生成并回复的,用于设置模型的先前响应,以继续对话流程。
|
||||
/// </para>
|
||||
/// </summary>
|
||||
public static string Tool => "tool";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Yi.Framework.AiHub.Application.Contracts.Dtos.OpenAi
|
||||
{
|
||||
public class ThorError
|
||||
{
|
||||
/// <summary>
|
||||
/// 错误码
|
||||
/// </summary>
|
||||
[JsonPropertyName("code")]
|
||||
public string? Code { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 参数
|
||||
/// </summary>
|
||||
[JsonPropertyName("param")]
|
||||
public string? Param { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 类型
|
||||
/// </summary>
|
||||
[JsonPropertyName("type")]
|
||||
public string? Type { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 错误信息
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
public string? Message { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 错误信息
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
public List<string?> Messages { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 错误信息
|
||||
/// </summary>
|
||||
[JsonPropertyName("message")]
|
||||
public object MessageObject
|
||||
{
|
||||
set
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
case string s:
|
||||
Message = s;
|
||||
Messages = new() { s };
|
||||
break;
|
||||
case List<object> list when list.All(i => i is JsonElement):
|
||||
Messages = list.Cast<JsonElement>().Select(e => e.GetString()).ToList();
|
||||
Message = string.Join(Environment.NewLine, Messages);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
get
|
||||
{
|
||||
if (Messages?.Count > 1)
|
||||
{
|
||||
return Messages;
|
||||
}
|
||||
|
||||
return Message;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
namespace Yi.Framework.AiHub.Application.Contracts.Dtos.OpenAi
|
||||
{
|
||||
/// <summary>
|
||||
/// 支持图片识别的消息体内容类型
|
||||
/// </summary>
|
||||
public class ThorMessageContentTypeConst
|
||||
{
|
||||
/// <summary>
|
||||
/// 文本内容
|
||||
/// </summary>
|
||||
public static string Text => "text";
|
||||
|
||||
/// <summary>
|
||||
/// 图片 Url 类型
|
||||
/// </summary>
|
||||
public static string ImageUrl => "image_url";
|
||||
|
||||
/// <summary>
|
||||
/// 图片 Url 类型
|
||||
/// </summary>
|
||||
public static string Image => "image";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Yi.Framework.AiHub.Application.Contracts.Dtos.OpenAi;
|
||||
|
||||
/// <summary>
|
||||
/// 指定模型必须输出的格式的对象。用于启用JSON模式。
|
||||
/// </summary>
|
||||
public class ThorResponseFormat
|
||||
{
|
||||
/// <summary>
|
||||
/// 设置为json_object启用json模式。
|
||||
/// 这保证了模型生成的消息是有效的JSON。
|
||||
/// 注意,如果finish_reason=“length”,则消息内容可能是部分的,
|
||||
/// 这表示生成超过了max_tokens或对话超过了最大上下文长度。
|
||||
/// </summary>
|
||||
[JsonPropertyName("type")]
|
||||
public string? Type { get; set; }
|
||||
|
||||
[JsonPropertyName("json_schema")]
|
||||
public ThorResponseJsonSchema JsonSchema { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Yi.Framework.AiHub.Application.Contracts.Dtos.OpenAi;
|
||||
|
||||
public class ThorResponseJsonSchema
|
||||
{
|
||||
[JsonPropertyName("name")]
|
||||
public string Name { get; set; }
|
||||
|
||||
[JsonPropertyName("description")]
|
||||
public string? Description { get; set; }
|
||||
|
||||
[JsonPropertyName("strict")]
|
||||
public bool? Strict { get; set; }
|
||||
|
||||
[JsonPropertyName("schema")]
|
||||
public object Schema { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Yi.Framework.AiHub.Application.Contracts.Dtos.OpenAi
|
||||
{
|
||||
/// <summary>
|
||||
/// 流响应选项。仅当您设置 stream: true 时才设置此项。
|
||||
/// </summary>
|
||||
public class ThorStreamOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// 如果设置,则会在 data: [DONE] 消息之前传输附加块。
|
||||
/// 该块上的 usage 字段显示整个请求的令牌使用统计信息,
|
||||
/// choices 字段将始终为空数组。所有其他块也将包含一个 usage 字段,但具有空值。
|
||||
/// </summary>
|
||||
[JsonPropertyName("include_usage")]
|
||||
public bool? IncludeUsage { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Yi.Framework.AiHub.Application.Contracts.Dtos.OpenAi;
|
||||
|
||||
/// <summary>
|
||||
/// 工具调用对象定义
|
||||
/// </summary>
|
||||
public class ThorToolCall
|
||||
{
|
||||
public ThorToolCall()
|
||||
{
|
||||
Id = Guid.NewGuid().ToString("N");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 工具调用序号值
|
||||
/// </summary>
|
||||
[JsonPropertyName("index")]
|
||||
public int Index { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 工具调用的 ID
|
||||
/// </summary>
|
||||
[JsonPropertyName("id")]
|
||||
public string? Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 工具的类型。目前仅支持 function
|
||||
/// </summary>
|
||||
[JsonPropertyName("type")]
|
||||
public string? Type { get; set; } = "function";
|
||||
|
||||
/// <summary>
|
||||
/// 模型调用的函数。
|
||||
/// </summary>
|
||||
[JsonPropertyName("function")]
|
||||
public ThorChatMessageFunction? Function { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Yi.Framework.AiHub.Application.Contracts.Dtos.OpenAi;
|
||||
|
||||
/// <summary>
|
||||
/// 工具
|
||||
/// </summary>
|
||||
public class ThorToolChoice
|
||||
{
|
||||
/// <summary>
|
||||
/// 表示模型不会调用任何工具
|
||||
/// </summary>
|
||||
public static ThorToolChoice GetNone() => new() { Type = ThorToolChoiceTypeConst.None };
|
||||
|
||||
/// <summary>
|
||||
/// 表示模型可以在生成消息或调用一个或多个工具之间进行选择
|
||||
/// </summary>
|
||||
public static ThorToolChoice GetAuto() => new() { Type = ThorToolChoiceTypeConst.Auto };
|
||||
|
||||
/// <summary>
|
||||
/// 表示模型必须调用一个或多个工具
|
||||
/// </summary>
|
||||
public static ThorToolChoice GetRequired() => new() { Type = ThorToolChoiceTypeConst.Required };
|
||||
|
||||
/// <summary>
|
||||
/// 指定特定工具会强制模型调用该工具
|
||||
/// </summary>
|
||||
/// <param name="functionName">函数名</param>
|
||||
/// <returns></returns>
|
||||
public static ThorToolChoice GetFunction(string functionName) => new()
|
||||
{
|
||||
Type = ThorToolChoiceTypeConst.Function,
|
||||
Function = new ThorToolChoiceFunctionTool()
|
||||
{
|
||||
Name = functionName
|
||||
}
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// "none" 表示模型不会调用任何工具<br />
|
||||
/// "auto" 表示模型可以在生成消息或调用一个或多个工具之间进行选择 <br />
|
||||
/// "required" 表示模型必须调用一个或多个工具 <br />
|
||||
/// "function" 指定特定工具会强制模型调用该工具<br />
|
||||
/// 使用<see cref="ThorToolChoiceTypeConst"/> 赋值
|
||||
/// </summary>
|
||||
[JsonPropertyName("type")]
|
||||
public string Type { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 调用的函数定义
|
||||
/// </summary>
|
||||
[JsonPropertyName("function")]
|
||||
public ThorToolChoiceFunctionTool? Function { get; set; }
|
||||
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Yi.Framework.AiHub.Application.Contracts.Dtos.OpenAi
|
||||
{
|
||||
public class ThorToolChoiceFunctionTool
|
||||
{
|
||||
[JsonPropertyName("name")]
|
||||
public string Name { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
namespace Yi.Framework.AiHub.Application.Contracts.Dtos.OpenAi
|
||||
{
|
||||
public class ThorToolChoiceTypeConst
|
||||
{
|
||||
/// <summary>
|
||||
/// 指定特定工具会强制模型调用该工具
|
||||
/// </summary>
|
||||
public static string Function => "function";
|
||||
|
||||
/// <summary>
|
||||
/// 表示模型可以在生成消息或调用一个或多个工具之间进行选择
|
||||
/// </summary>
|
||||
public static string Auto => "auto";
|
||||
|
||||
/// <summary>
|
||||
/// 表示模型不会调用任何工具
|
||||
/// </summary>
|
||||
public static string None => "none";
|
||||
|
||||
/// <summary>
|
||||
/// 表示模型必须调用一个或多个工具
|
||||
/// </summary>
|
||||
public static string Required => "required ";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Yi.Framework.AiHub.Application.Contracts.Dtos.OpenAi;
|
||||
|
||||
/// <summary>
|
||||
/// 有效工具的定义。
|
||||
/// </summary>
|
||||
public class ThorToolDefinition
|
||||
{
|
||||
/// <summary>
|
||||
/// 必修的。工具的类型。目前仅支持 function 。
|
||||
/// </summary>
|
||||
[JsonPropertyName("type")]
|
||||
public string Type { get; set; } = ThorToolTypeConst.Function;
|
||||
|
||||
/// <summary>
|
||||
/// 函数对象
|
||||
/// </summary>
|
||||
[JsonPropertyName("function")]
|
||||
public ThorToolFunctionDefinition? Function { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 创建函数工具
|
||||
/// </summary>
|
||||
/// <param name="function"></param>
|
||||
/// <returns></returns>
|
||||
public static ThorToolDefinition CreateFunctionTool(ThorToolFunctionDefinition function) => new()
|
||||
{
|
||||
Type = ThorToolTypeConst.Function,
|
||||
Function = function
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Yi.Framework.AiHub.Application.Contracts.Dtos.OpenAi;
|
||||
|
||||
/// <summary>
|
||||
/// 有效函数调用的定义。
|
||||
/// </summary>
|
||||
public class ThorToolFunctionDefinition
|
||||
{
|
||||
[JsonPropertyName("type")]
|
||||
public string? Type { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 要调用的函数的名称。必须是 a-z、A-Z、0-9 或包含下划线和破折号,最大长度为 64。
|
||||
/// </summary>
|
||||
[JsonPropertyName("name")]
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 函数功能的描述,模型使用它来选择何时以及如何调用函数。
|
||||
/// </summary>
|
||||
[JsonPropertyName("description")]
|
||||
public string? Description { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 函数接受的参数,描述为 JSON 架构对象。有关示例,请参阅指南,有关格式的文档,请参阅 JSON 架构参考。
|
||||
/// 省略 parameters 定义一个参数列表为空的函数。
|
||||
/// See the <a href="https://platform.openai.com/docs/guides/gpt/function-calling">guide</a> for examples,
|
||||
/// and the <a href="https://json-schema.org/understanding-json-schema/">JSON Schema reference</a> for
|
||||
/// documentation about the format.
|
||||
/// </summary>
|
||||
[JsonPropertyName("parameters")]
|
||||
public ThorToolFunctionPropertyDefinition Parameters { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,260 @@
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Yi.Framework.AiHub.Application.Contracts.Dtos.OpenAi;
|
||||
|
||||
/// <summary>
|
||||
/// 函数参数是JSON格式对象
|
||||
/// https://json-schema.org/understanding-json-schema/reference/object.html
|
||||
/// </summary>
|
||||
/// <example>
|
||||
/// 定义属性示例:
|
||||
/// [JsonPropertyName("location")]
|
||||
/// public ThorToolFunctionPropertyDefinition Location = ThorToolFunctionPropertyDefinition.DefineString("The city and state, e.g. San Francisco, CA");
|
||||
///
|
||||
/// [JsonPropertyName("unit")]
|
||||
/// public ThorToolFunctionPropertyDefinition Unit = ThorToolFunctionPropertyDefinition.DefineEnum(["celsius", "fahrenheit"]);
|
||||
/// </example>
|
||||
public class ThorToolFunctionPropertyDefinition
|
||||
{
|
||||
/// <summary>
|
||||
/// 定义了函数对象的类型枚举
|
||||
/// </summary>
|
||||
public enum FunctionObjectTypes
|
||||
{
|
||||
/// <summary>
|
||||
/// 表示字符串类型的函数对象
|
||||
/// </summary>
|
||||
String,
|
||||
/// <summary>
|
||||
/// 表示整数类型的函数对象
|
||||
/// </summary>
|
||||
Integer,
|
||||
/// <summary>
|
||||
/// 表示数字(包括浮点数等)类型的函数对象
|
||||
/// </summary>
|
||||
Number,
|
||||
/// <summary>
|
||||
/// 表示对象类型的函数对象
|
||||
/// </summary>
|
||||
Object,
|
||||
/// <summary>
|
||||
/// 表示数组类型的函数对象
|
||||
/// </summary>
|
||||
Array,
|
||||
/// <summary>
|
||||
/// 表示布尔类型的函数对象
|
||||
/// </summary>
|
||||
Boolean,
|
||||
/// <summary>
|
||||
/// 表示空值类型的函数对象
|
||||
/// </summary>
|
||||
Null
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 必填的。函数参数对象类型。默认值为“object”。
|
||||
/// </summary>
|
||||
[JsonPropertyName("type")]
|
||||
public string Type { get; set; } = "object";
|
||||
|
||||
/// <summary>
|
||||
/// 可选。“函数参数”列表,作为从参数名称映射的字典
|
||||
/// 对于描述类型的对象,可能还有可能的枚举值等等。
|
||||
/// </summary>
|
||||
[JsonPropertyName("properties")]
|
||||
public IDictionary<string, ThorToolFunctionPropertyDefinition>? Properties { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 可选。列出必需的“function arguments”列表。
|
||||
/// </summary>
|
||||
[JsonPropertyName("required")]
|
||||
public List<string>? Required { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 可选。是否允许附加属性。默认值为true。
|
||||
/// </summary>
|
||||
[JsonPropertyName("additionalProperties")]
|
||||
public bool? AdditionalProperties { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 可选。参数描述。
|
||||
/// </summary>
|
||||
[JsonPropertyName("description")]
|
||||
public string? Description { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 可选。此参数的允许值列表。
|
||||
/// </summary>
|
||||
[JsonPropertyName("enum")]
|
||||
public List<string>? Enum { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 可以使用minProperties和maxProperties关键字限制对象上的属性数量。每一个
|
||||
/// 这些必须是非负整数。
|
||||
/// </summary>
|
||||
[JsonPropertyName("minProperties")]
|
||||
public int? MinProperties { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 可以使用minProperties和maxProperties关键字限制对象上的属性数量。每一个
|
||||
/// 这些必须是非负整数。
|
||||
/// </summary>
|
||||
[JsonPropertyName("maxProperties")]
|
||||
public int? MaxProperties { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 如果type为“array”,则指定数组中所有项目的元素类型。
|
||||
/// 如果类型不是“array”,则应为null。
|
||||
/// 有关更多详细信息,请参阅 https://json-schema.org/understanding-json-schema/reference/array.html
|
||||
/// </summary>
|
||||
[JsonPropertyName("items")]
|
||||
public ThorToolFunctionPropertyDefinition? Items { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 定义数组
|
||||
/// </summary>
|
||||
/// <param name="arrayItems"></param>
|
||||
/// <returns></returns>
|
||||
public static ThorToolFunctionPropertyDefinition DefineArray(ThorToolFunctionPropertyDefinition? arrayItems = null)
|
||||
{
|
||||
return new ThorToolFunctionPropertyDefinition
|
||||
{
|
||||
Items = arrayItems,
|
||||
Type = ConvertTypeToString(FunctionObjectTypes.Array)
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 定义枚举
|
||||
/// </summary>
|
||||
/// <param name="enumList"></param>
|
||||
/// <param name="description"></param>
|
||||
/// <returns></returns>
|
||||
public static ThorToolFunctionPropertyDefinition DefineEnum(List<string> enumList, string? description = null)
|
||||
{
|
||||
return new ThorToolFunctionPropertyDefinition
|
||||
{
|
||||
Description = description,
|
||||
Enum = enumList,
|
||||
Type = ConvertTypeToString(FunctionObjectTypes.String)
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 定义整型
|
||||
/// </summary>
|
||||
/// <param name="description"></param>
|
||||
/// <returns></returns>
|
||||
public static ThorToolFunctionPropertyDefinition DefineInteger(string? description = null)
|
||||
{
|
||||
return new ThorToolFunctionPropertyDefinition
|
||||
{
|
||||
Description = description,
|
||||
Type = ConvertTypeToString(FunctionObjectTypes.Integer)
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 定义数字
|
||||
/// </summary>
|
||||
/// <param name="description"></param>
|
||||
/// <returns></returns>
|
||||
public static ThorToolFunctionPropertyDefinition DefineNumber(string? description = null)
|
||||
{
|
||||
return new ThorToolFunctionPropertyDefinition
|
||||
{
|
||||
Description = description,
|
||||
Type = ConvertTypeToString(FunctionObjectTypes.Number)
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 定义字符串
|
||||
/// </summary>
|
||||
/// <param name="description"></param>
|
||||
/// <returns></returns>
|
||||
public static ThorToolFunctionPropertyDefinition DefineString(string? description = null)
|
||||
{
|
||||
return new ThorToolFunctionPropertyDefinition
|
||||
{
|
||||
Description = description,
|
||||
Type = ConvertTypeToString(FunctionObjectTypes.String)
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 定义布尔值
|
||||
/// </summary>
|
||||
/// <param name="description"></param>
|
||||
/// <returns></returns>
|
||||
public static ThorToolFunctionPropertyDefinition DefineBoolean(string? description = null)
|
||||
{
|
||||
return new ThorToolFunctionPropertyDefinition
|
||||
{
|
||||
Description = description,
|
||||
Type = ConvertTypeToString(FunctionObjectTypes.Boolean)
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 定义null
|
||||
/// </summary>
|
||||
/// <param name="description"></param>
|
||||
/// <returns></returns>
|
||||
public static ThorToolFunctionPropertyDefinition DefineNull(string? description = null)
|
||||
{
|
||||
return new ThorToolFunctionPropertyDefinition
|
||||
{
|
||||
Description = description,
|
||||
Type = ConvertTypeToString(FunctionObjectTypes.Null)
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 定义对象
|
||||
/// </summary>
|
||||
/// <param name="properties"></param>
|
||||
/// <param name="required"></param>
|
||||
/// <param name="additionalProperties"></param>
|
||||
/// <param name="description"></param>
|
||||
/// <param name="enum"></param>
|
||||
/// <returns></returns>
|
||||
public static ThorToolFunctionPropertyDefinition DefineObject(IDictionary<string, ThorToolFunctionPropertyDefinition>? properties,
|
||||
List<string>? required,
|
||||
bool? additionalProperties,
|
||||
string? description,
|
||||
List<string>? @enum)
|
||||
{
|
||||
return new ThorToolFunctionPropertyDefinition
|
||||
{
|
||||
Properties = properties,
|
||||
Required = required,
|
||||
AdditionalProperties = additionalProperties,
|
||||
Description = description,
|
||||
Enum = @enum,
|
||||
Type = ConvertTypeToString(FunctionObjectTypes.Object)
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 将 `FunctionObjectTypes` 枚举值转换为其对应的字符串表示形式。
|
||||
/// </summary>
|
||||
/// <param name="type">要转换的类型</param>
|
||||
/// <returns>给定类型的字符串表示形式</returns>
|
||||
|
||||
public static string ConvertTypeToString(FunctionObjectTypes type)
|
||||
{
|
||||
return type switch
|
||||
{
|
||||
FunctionObjectTypes.String => "string",
|
||||
FunctionObjectTypes.Integer => "integer",
|
||||
FunctionObjectTypes.Number => "number",
|
||||
FunctionObjectTypes.Object => "object",
|
||||
FunctionObjectTypes.Array => "array",
|
||||
FunctionObjectTypes.Boolean => "boolean",
|
||||
FunctionObjectTypes.Null => "null",
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(type), $"Unknown type: {type}")
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
namespace Yi.Framework.AiHub.Application.Contracts.Dtos.OpenAi
|
||||
{
|
||||
/// <summary>
|
||||
/// 工具类型定义
|
||||
/// </summary>
|
||||
public class ThorToolTypeConst
|
||||
{
|
||||
/// <summary>
|
||||
/// 函数
|
||||
/// </summary>
|
||||
public static string Function => "function";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Yi.Framework.AiHub.Application.Contracts.Dtos.OpenAi;
|
||||
|
||||
/// <summary>
|
||||
/// 统计信息模型
|
||||
/// </summary>
|
||||
public record ThorUsageResponse
|
||||
{
|
||||
/// <summary>
|
||||
/// 提示中的令牌数。
|
||||
/// </summary>
|
||||
[JsonPropertyName("prompt_tokens")]
|
||||
public int? PromptTokens { get; set; }
|
||||
|
||||
[JsonPropertyName("input_tokens")]
|
||||
public int? InputTokens { get; set; }
|
||||
|
||||
[JsonPropertyName("output_tokens")]
|
||||
public int? OutputTokens { get; set; }
|
||||
|
||||
[JsonPropertyName("input_tokens_details")]
|
||||
public ThorUsageResponseInputTokensDetails? InputTokensDetails { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 生成的完成中的令牌数。
|
||||
/// </summary>
|
||||
[JsonPropertyName("completion_tokens")]
|
||||
public long? CompletionTokens { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 请求中使用的令牌总数(提示 + 完成)。
|
||||
/// </summary>
|
||||
[JsonPropertyName("total_tokens")]
|
||||
public long? TotalTokens { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// ThorUsageResponsePromptTokensDetails
|
||||
/// </summary>
|
||||
[JsonPropertyName("prompt_tokens_details")]
|
||||
public ThorUsageResponsePromptTokensDetails? PromptTokensDetails { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// ThorUsageResponseCompletionTokensDetails
|
||||
/// </summary>
|
||||
[JsonPropertyName("completion_tokens_details")]
|
||||
public ThorUsageResponseCompletionTokensDetails? CompletionTokensDetails { get; set; }
|
||||
}
|
||||
|
||||
public class ThorUsageResponseInputTokensDetails
|
||||
{
|
||||
[JsonPropertyName("image_tokens")]
|
||||
public int? ImageTokens { get; set; }
|
||||
|
||||
[JsonPropertyName("text_tokens")]
|
||||
public int? TextTokens { get; set; }
|
||||
}
|
||||
|
||||
public record ThorUsageResponsePromptTokensDetails
|
||||
{
|
||||
/// <summary>
|
||||
/// 缓存的令牌数。
|
||||
/// </summary>
|
||||
[JsonPropertyName("cached_tokens")]
|
||||
public int? CachedTokens { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// audio_tokens
|
||||
/// </summary>
|
||||
[JsonPropertyName("audio_tokens")]
|
||||
public int? AudioTokens { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// completion_tokens_details
|
||||
/// </summary>
|
||||
public record ThorUsageResponseCompletionTokensDetails
|
||||
{
|
||||
/// <summary>
|
||||
/// 使用 Predicted Outputs 时, Prediction 的 Final。
|
||||
/// </summary>
|
||||
[JsonPropertyName("accepted_prediction_tokens")]
|
||||
public int? AcceptedPredictionTokens { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 模型生成的音频输入令牌。
|
||||
/// </summary>
|
||||
[JsonPropertyName("audio_tokens")]
|
||||
public int? AudioTokens { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 模型生成的用于推理的 Token。
|
||||
/// </summary>
|
||||
[JsonPropertyName("reasoning_tokens")]
|
||||
public int? ReasoningTokens { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 使用 Predicted Outputs 时, 预测,但未出现在 completion 中。但是,与 reasoning 令牌,这些令牌仍然计入总数 用于 Billing、Output 和 Context Window 的完成令牌 限制。
|
||||
/// </summary>
|
||||
[JsonPropertyName("rejected_prediction_tokens")]
|
||||
public int? RejectedPredictionTokens { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Yi.Framework.AiHub.Application.Contracts.Dtos.OpenAi;
|
||||
|
||||
/// <summary>
|
||||
/// 图片消息内容对象
|
||||
/// </summary>
|
||||
public class ThorVisionImageUrl
|
||||
{
|
||||
/// <summary>
|
||||
/// 图片的url地址,如:https://localhost/logo.jpg ,一般只支持 .png , .jpg .webp .gif
|
||||
/// 也可以是base64字符串,如:data:image/jpeg;base64,{base64_image}
|
||||
/// 要看底层平台具体要求
|
||||
/// </summary>
|
||||
[JsonPropertyName("url")]
|
||||
public string Url { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 指定图像的细节级别。在愿景指南中了解更多信息。https://platform.openai.com/docs/guides/vision/low-or-high-fidelity-image-understanding
|
||||
/// <para>
|
||||
/// 指定图像的详细程度。通过控制 detail 参数(该参数具有三个选项: low 、 high 或 auto ),您
|
||||
/// 可以控制模型的处理方式图像并生成其文本理解。默认情况下,模型将使用 auto 设置,
|
||||
/// 该设置将查看图像输入大小并决定是否应使用 low 或 high 设置。
|
||||
/// </para>
|
||||
/// </summary>
|
||||
[JsonPropertyName("detail")]
|
||||
public string? Detail { get; set; } = "auto";
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user