Files
team-api/relaykit/dto/openai.go
T
Qian 2ef5a40c26 新的调度方式 (#14)
重构模型渠道调度系统
2026-08-01 22:55:08 +08:00

239 lines
9.0 KiB
Go

package dto
import "encoding/json"
// GeneralOpenAIRequest OpenAI 兼容的 Chat Completions 请求
type GeneralOpenAIRequest struct {
Model string `json:"model"`
Messages []Message `json:"messages"`
MaxTokens *int `json:"max_tokens,omitempty"`
MaxCompletionTokens *int `json:"max_completion_tokens,omitempty"`
Temperature *float64 `json:"temperature,omitempty"`
TopP *float64 `json:"top_p,omitempty"`
TopK *int `json:"top_k,omitempty"`
N *int `json:"n,omitempty"`
Stream *bool `json:"stream,omitempty"`
StreamOptions *StreamOptions `json:"stream_options,omitempty"`
Stop any `json:"stop,omitempty"`
PresencePenalty *float64 `json:"presence_penalty,omitempty"`
FrequencyPenalty *float64 `json:"frequency_penalty,omitempty"`
User string `json:"user,omitempty"`
Seed *int64 `json:"seed,omitempty"`
Tools []Tool `json:"tools,omitempty"`
ToolChoice any `json:"tool_choice,omitempty"`
ParallelToolCalls *bool `json:"parallel_tool_calls,omitempty"`
ResponseFormat *ResponseFormat `json:"response_format,omitempty"`
LogProbs *bool `json:"logprobs,omitempty"`
TopLogProbs *int `json:"top_logprobs,omitempty"`
ReasoningEffort string `json:"reasoning_effort,omitempty"`
LogitBias map[string]int `json:"logit_bias,omitempty"`
ServiceTier string `json:"service_tier,omitempty"`
Modalities []string `json:"modalities,omitempty"`
Audio json.RawMessage `json:"audio,omitempty"`
Store *bool `json:"store,omitempty"`
WebSearchOptions json.RawMessage `json:"web_search_options,omitempty"`
Prediction json.RawMessage `json:"prediction,omitempty"`
Metadata json.RawMessage `json:"metadata,omitempty"`
SafetyIdentifier string `json:"safety_identifier,omitempty"`
Verbosity string `json:"verbosity,omitempty"`
PromptCacheKey string `json:"prompt_cache_key,omitempty"`
PromptCacheRetention string `json:"prompt_cache_retention,omitempty"`
ImageConfig *ImageConfigDTO `json:"image_config,omitempty"`
}
// ImageConfigDTO OpenAI 请求中的图片生成配置透传字段(用于 Banana 等内生图模型)
type ImageConfigDTO struct {
AspectRatio string `json:"aspect_ratio,omitempty"`
ImageSize string `json:"image_size,omitempty"`
}
// Message OpenAI 消息格式
type Message struct {
Role string `json:"role"`
Content any `json:"content"` // string 或 []ContentPart
Refusal *string `json:"refusal,omitempty"` // 结构化输出拒绝原因
ReasoningContent *string `json:"reasoning_content,omitempty"` // 推理模型(DeepSeek/o1)的思考内容
Name string `json:"name,omitempty"`
ToolCalls []ToolCall `json:"tool_calls,omitempty"`
ToolCallID string `json:"tool_call_id,omitempty"`
Annotations []any `json:"annotations,omitempty"`
}
// ContentPart 多模态内容块
type ContentPart struct {
Type string `json:"type"`
Text string `json:"text,omitempty"`
ImageURL *ImageURL `json:"image_url,omitempty"`
InputAudio *InputAudio `json:"input_audio,omitempty"`
File *FileData `json:"file,omitempty"`
}
// ImageURL 图片 URL
type ImageURL struct {
URL string `json:"url"`
Detail string `json:"detail,omitempty"`
}
// InputAudio 音频输入
type InputAudio struct {
Data string `json:"data"`
Format string `json:"format"`
}
// FileData 文件附件
type FileData struct {
FileID string `json:"file_id,omitempty"`
FileData string `json:"file_data,omitempty"`
Filename string `json:"filename,omitempty"`
}
// Tool 工具定义
type Tool struct {
Type string `json:"type"`
Function FunctionDef `json:"function"`
}
// FunctionDef 函数定义
type FunctionDef struct {
Name string `json:"name"`
Description string `json:"description,omitempty"`
Parameters any `json:"parameters,omitempty"`
Strict *bool `json:"strict,omitempty"`
}
// ToolCall 工具调用
type ToolCall struct {
Index int `json:"index,omitempty"`
ID string `json:"id"`
Type string `json:"type"`
Function FunctionCall `json:"function"`
}
// FunctionCall 函数调用
type FunctionCall struct {
Name string `json:"name"`
Arguments string `json:"arguments"`
}
// UnmarshalJSON 自定义反序列化:当上游返回 arguments 为 JSON object 而非 string 时,自动转为 JSON string
func (f *FunctionCall) UnmarshalJSON(data []byte) error {
type Alias FunctionCall
aux := &struct {
Arguments json.RawMessage `json:"arguments"`
*Alias
}{
Alias: (*Alias)(f),
}
if err := json.Unmarshal(data, aux); err != nil {
return err
}
if len(aux.Arguments) == 0 {
return nil
}
// 如果是 string 类型(标准格式:"arguments": "{...}"),去掉引号
if aux.Arguments[0] == '"' {
var s string
if err := json.Unmarshal(aux.Arguments, &s); err == nil {
f.Arguments = s
}
return nil
}
// 如果是 JSON object/array(非标准格式:"arguments": {...}),序列化为 string
f.Arguments = string(aux.Arguments)
return nil
}
// StreamOptions 流式选项
type StreamOptions struct {
IncludeUsage bool `json:"include_usage"`
IncludeObfuscation bool `json:"include_obfuscation,omitempty"`
}
// ResponseFormat 响应格式
type ResponseFormat struct {
Type string `json:"type"`
JSONSchema any `json:"json_schema,omitempty"`
}
// ChatCompletionResponse Chat Completions 非流式响应
type ChatCompletionResponse struct {
ID string `json:"id"`
Object string `json:"object"`
Created int64 `json:"created"`
Model string `json:"model"`
SystemFingerprint *string `json:"system_fingerprint,omitempty"`
Choices []Choice `json:"choices"`
Usage UsageWithDetails `json:"usage"`
ServiceTier *string `json:"service_tier,omitempty"`
}
// Choice 响应选择项
type Choice struct {
Index int `json:"index"`
Message Message `json:"message"`
FinishReason string `json:"finish_reason"`
LogProbs any `json:"logprobs,omitempty"`
}
// ChatCompletionStreamResponse Chat Completions 流式响应块
type ChatCompletionStreamResponse struct {
ID string `json:"id"`
Object string `json:"object"`
Created int64 `json:"created"`
Model string `json:"model"`
SystemFingerprint *string `json:"system_fingerprint,omitempty"`
Choices []StreamChoice `json:"choices"`
Usage *UsageWithDetails `json:"usage"`
}
// StreamChoice 流式选择项
type StreamChoice struct {
Index int `json:"index"`
Delta Message `json:"delta"`
FinishReason *string `json:"finish_reason"`
LogProbs any `json:"logprobs,omitempty"`
}
// ModelsResponse /v1/models 响应
type ModelsResponse struct {
Object string `json:"object"`
Data []ModelDTO `json:"data"`
}
// ModelDTO 模型信息 DTO
type ModelDTO struct {
ID string `json:"id"`
Object string `json:"object"`
Created int64 `json:"created"`
OwnedBy string `json:"owned_by"`
ModelName string `json:"model_name,omitempty"`
Category string `json:"category,omitempty"`
ContextWindow int `json:"context_window,omitempty"`
MaxOutputTokens int `json:"max_output_tokens,omitempty"`
Capabilities map[string]bool `json:"capabilities,omitempty"`
Modalities *ModelModalities `json:"modalities,omitempty"`
}
// ModelDetailResponse /v1/models/{model_id} 响应
type ModelDetailResponse struct {
ID string `json:"id"`
Object string `json:"object"`
Created int64 `json:"created"`
OwnedBy string `json:"owned_by"`
ModelName string `json:"model_name,omitempty"`
Description string `json:"description,omitempty"`
Category string `json:"category,omitempty"`
Status string `json:"status,omitempty"`
ContextWindow int `json:"context_window,omitempty"`
MaxOutputTokens int `json:"max_output_tokens,omitempty"`
Capabilities map[string]bool `json:"capabilities,omitempty"`
Modalities *ModelModalities `json:"modalities,omitempty"`
Deprecated bool `json:"deprecated"`
}
// ModelModalities 模型输入输出模态
type ModelModalities struct {
Input []string `json:"input"`
Output []string `json:"output"`
}