Files
model-gateway/model/entity/model_manage.go
T
19904408334 9d9bd71468 fix: 优化模型网关请求重试与业务字段前置写入
- 流式调用增加可重试错误码检测与指数退避重试
- 业务字段写入改为前置追加,不覆盖已有值
- 请求体按模板元数据递归合并,补充数组/对象字段处理
- 异步任务查询支持请求体映射与占位符替换
- 升级 common 与 gmq 依赖版本,移除本地 replace
2026-08-21 09:47:21 +08:00

167 lines
11 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package entity
import (
"model-gateway/consts/model"
"gitea.redpowerfuture.com/red-future/common/beans"
)
type modelManageCol struct {
beans.SQLBaseCol
ModelSupplier string
ModelName string
ModelType string
BaseURL string
SystemModel string
HttpMethod string
ChatModel string
ResponseType string
ApiKey string
Enabled string
RequestHeadMapping string
RequestBodyMapping string
RequestBusinessFieldMapping string
ResponseMapping string
ResponseBodyMapping string
ResponseBusinessFieldMapping string
MaxConcurrency string
TokenPredictPrice string
TokenPredictPriceUnit string
PriceConfig string
MaxTokens string
MinDuration string
MaxDuration string
LastFrame string
}
var ModelManageCol = modelManageCol{
SQLBaseCol: beans.DefSQLBaseCol,
ModelSupplier: "model_supplier",
ModelName: "model_name",
ModelType: "model_type",
BaseURL: "base_url",
SystemModel: "system_model",
HttpMethod: "http_method",
ChatModel: "chat_model",
ResponseType: "response_type",
ApiKey: "api_key",
Enabled: "enabled",
RequestHeadMapping: "request_head_mapping",
RequestBodyMapping: "request_body_mapping",
RequestBusinessFieldMapping: "request_business_field_mapping",
ResponseMapping: "response_mapping",
ResponseBodyMapping: "response_body_mapping",
ResponseBusinessFieldMapping: "response_business_field_mapping",
MaxConcurrency: "max_concurrency",
TokenPredictPrice: "token_predict_price",
TokenPredictPriceUnit: "token_predict_price_unit",
PriceConfig: "price_config",
MaxTokens: "max_tokens",
MinDuration: "min_duration",
MaxDuration: "max_duration",
LastFrame: "last_frame",
}
type ModelManage struct {
beans.SQLBaseDO `orm:",inline"`
ModelSupplier model.SupplierType `orm:"model_supplier" json:"modelSupplier" description:"模型供应商"`
ModelName string `orm:"model_name" json:"modelName" description:"模型名称"`
ModelType model.ModelType `orm:"model_type" json:"modelType" description:"模型类型"`
BaseURL string `orm:"base_url" json:"baseUrl" description:"模型地址"`
SystemModel *bool `orm:"system_model" json:"systemModel" description:"系统模型"`
HttpMethod string `orm:"http_method" json:"httpMethod" description:"http方法"`
ChatModel *bool `orm:"chat_model" json:"chatModel" description:"是否聊天模型"`
ResponseType model.ResponseType `orm:"response_type" json:"responseType" description:"返回类型:1同步,2异步,3流"`
ApiKey string `orm:"api_key" json:"apiKey" description:"api key"`
Enabled *bool `orm:"enabled" json:"enabled" description:"是否启用"`
RequestHeadMapping map[string]string `orm:"request_head_mapping" json:"requestHeadMapping" description:"请求头映射"`
RequestBodyMapping map[string]any `orm:"request_body_mapping" json:"requestBodyMapping" description:"请求体映射"`
RequestBusinessFieldMapping map[string]string `orm:"request_business_field_mapping" json:"requestBusinessFieldMapping" description:"请求业务字段映射"`
ResponseMapping map[string]any `orm:"response_mapping" json:"responseMapping" description:"响应映射"`
ResponseBodyMapping map[string]string `orm:"response_body_mapping" json:"responseBodyMapping" description:"响应主体映射"`
ResponseBusinessFieldMapping map[string]string `orm:"response_business_field_mapping" json:"responseBusinessFieldMapping" description:"响应业务字段映射"`
MaxConcurrency int `orm:"max_concurrency" json:"maxConcurrency" description:"最大并发数"`
TokenMapping *TokenMapping `orm:"token_mapping" json:"tokenMapping" description:"token映射"`
AsyncTaskMapping *AsyncTaskMapping `orm:"async_task_mapping" json:"asyncTaskMapping" description:"异步任务映射"`
TokenPredictPrice float64 `orm:"token_predict_price" json:"tokenPredictPrice" description:"模型Token预估价格"`
TokenPredictPriceUnit string `orm:"token_predict_price_unit" json:"tokenPredictPriceUnit" description:"模型token预估价格单位(秒,百万Token,千Token,字数)"`
PriceConfig *PriceConfig `orm:"price_config" json:"priceConfig" description:"计费规则"`
MaxTokens int `orm:"max_tokens" json:"maxTokens" description:"最大token数"`
MinDuration int `orm:"min_duration" json:"minDuration" description:"最小时长(秒)"`
MaxDuration int `orm:"max_duration" json:"maxDuration" description:"最大时长(秒)"`
LastFrame string `orm:"last_frame" json:"lastFrame" description:"视频的尾帧图像"`
ErrorMessageMapping map[string]any `orm:"error_message_mapping" json:"errorMessageMapping" description:"错误消息映射"`
}
type TokenMapping struct {
PromptTokens string `json:"promptTokens" dc:"输入token"`
CompletionTokens string `json:"completionTokens" dc:"输出token"`
TotalTokens string `json:"totalTokens" dc:"总token"`
}
type AsyncTaskMapping struct {
Url string `json:"url" dc:"url"`
HttpMethod string `json:"httpMethod" dc:"http方法" d:"POST"`
RequestBodyMapping map[string]any `json:"requestBodyMapping" description:"请求体映射"`
RequestHeadMapping map[string]string `json:"requestHeadMapping" description:"请求头映射"`
ResponseMapping map[string]any `json:"responseMapping" description:"响应映射"`
TaskId string `json:"taskId" dc:"任务id"`
TaskStatus string `json:"taskStatus" dc:"任务状态"`
TaskStatusPending string `json:"taskStatusPending" dc:"任务状态-待处理"`
TaskStatusRunning string `json:"taskStatusRunning" dc:"任务状态-运行中"`
TaskStatusSuccess string `json:"taskStatusSuccess" dc:"任务状态-成功"`
TaskStatusFailed string `json:"taskStatusFailed" dc:"任务状态-失败"`
TaskStatusCancel string `json:"taskStatusCancel" dc:"任务状态-取消"`
TaskStatusUnknown string `json:"taskStatusUnknown" dc:"任务状态-未知"`
}
// PriceConfig 模型计费规则(price_config 列,JSONB)。
// 命中条件为固定字段结构(PriceMatch):token 档位从调用用量读取,媒体类型由请求体参考媒体字段推导,
// 全部字段缺省表示无条件命中。
type PriceConfig struct {
Currency string `json:"currency" dc:"币种,默认CNY"`
Unit string `json:"unit" dc:"单价基准:per_1K-千token/per_1M-百万token/per_1-单个"`
Rules []PriceRule `json:"rules" dc:"定价规则数组,按序首条命中生效"`
Discount *PriceDiscount `json:"discount" dc:"模型级限时折扣,规则级可覆盖"`
// 单规则便捷字段:Rules 为空时的兜底价(等价于一条空 match 规则),全部为 0 时不参与计费
InputPrice float64 `json:"inputPrice,omitempty" dc:"输入单价"`
OutputPrice float64 `json:"outputPrice,omitempty" dc:"输出单价"`
CacheHitPrice float64 `json:"cacheHitPrice,omitempty" dc:"缓存命中单价"`
CacheStorageHourPrice float64 `json:"cacheStorageHourPrice,omitempty" dc:"缓存存储单价(元/小时)"`
}
// PriceRule 定价规则:match 条件命中后按价格项计价,缺省项视为 0
type PriceRule struct {
Name string `json:"name"`
Match *PriceMatch `json:"match,omitempty" dc:"命中条件(固定字段,见 PriceMatch);空表示任意调用"`
Input float64 `json:"input" dc:"输入单价(非音频)"`
InputAudio float64 `json:"inputAudio,omitempty" dc:"输入单价(音频),请求体 reference_audio 参考媒体字段命中时生效(见 DetectMediaType"`
Output float64 `json:"output" dc:"输出单价"`
CacheHit float64 `json:"cacheHit" dc:"缓存命中单价(非音频)"`
CacheHitAudio float64 `json:"cacheHitAudio,omitempty" dc:"缓存命中单价(音频),请求体 reference_audio 参考媒体字段命中时生效(见 DetectMediaType"`
CacheStorageHour float64 `json:"cacheStorageHour" dc:"缓存存储单价(元/小时)"`
Discount *PriceDiscount `json:"discount" dc:"规则级折扣,覆盖模型级折扣"`
}
// PriceMatch 命中条件:字段对应调用上下文固定路径,全部缺省(空值)表示无条件命中任意调用。
// token 档位(InputLength/OutputLength/TotalLength/CachedTokens)从调用用量读取,
// MediaType 由请求体参考媒体字段推导(见 DetectMediaType)。
type PriceMatch struct {
MediaType string `json:"mediaType,omitempty" dc:"输入媒体类型精确值(audio/no_video/has_video,由请求体参考媒体字段推导)"`
InputLengthMax int64 `json:"inputLengthMax,omitempty" dc:"输入token上限(<=usage.prompt_tokens"`
InputLengthMin int64 `json:"inputLengthMin,omitempty" dc:"输入token下限(>=usage.prompt_tokens"`
OutputLengthMax int64 `json:"outputLengthMax,omitempty" dc:"输出token上限(<=usage.completion_tokens"`
OutputLengthMin int64 `json:"outputLengthMin,omitempty" dc:"输出token下限(>=usage.completion_tokens"`
TotalLengthMax int64 `json:"totalLengthMax,omitempty" dc:"总token上限(<=usage.total_tokens"`
TotalLengthMin int64 `json:"totalLengthMin,omitempty" dc:"总token下限(>=usage.total_tokens"`
CachedTokensMax int64 `json:"cachedTokensMax,omitempty" dc:"缓存命中token上限(<=usage.cached_tokens"`
CachedTokensMin int64 `json:"cachedTokensMin,omitempty" dc:"缓存命中token下限(>=usage.cached_tokens"`
}
// PriceDiscount 限时折扣:rate 为折扣率(0.4=4折),effective 为空数组表示长期有效
type PriceDiscount struct {
Rate float64 `json:"rate" dc:"折扣率"`
Effective [2]string `json:"effective" dc:"有效期[起始,截止],格式YYYY-MM-DD,缺省长期有效"`
}