feat: refactor model manager

* chore: mv model icon
* fix: model icon
* fix: model icon
* feat: refactor model manager
* fix: model icon
* fix: model icon
* feat: refactor model manager

See merge request: !905
This commit is contained in:
徐兆楠
2025-07-24 13:12:44 +00:00
parent 12f7762797
commit 9b3814e2c5
114 changed files with 2888 additions and 4982 deletions

View File

@@ -25,9 +25,9 @@ import (
)
type Config struct {
BaseURL string `json:"base_url,omitempty" yaml:"base_url,omitempty"`
APIKey string `json:"api_key,omitempty" yaml:"api_key,omitempty"`
Timeout time.Duration `json:"timeout,omitempty" yaml:"timeout,omitempty"`
BaseURL string `json:"base_url,omitempty" yaml:"base_url"`
APIKey string `json:"api_key,omitempty" yaml:"api_key"`
Timeout time.Duration `json:"timeout,omitempty" yaml:"timeout"`
Model string `json:"model" yaml:"model"`
Temperature *float32 `json:"temperature,omitempty" yaml:"temperature,omitempty"`

View File

@@ -0,0 +1,60 @@
package modelmgr
type ParameterName string
const (
Temperature ParameterName = "temperature"
TopP ParameterName = "top_p"
TopK ParameterName = "top_k"
MaxTokens ParameterName = "max_tokens"
RespFormat ParameterName = "response_format"
FrequencyPenalty ParameterName = "frequency_penalty"
PresencePenalty ParameterName = "presence_penalty"
)
type ValueType string
const (
ValueTypeInt ValueType = "int"
ValueTypeFloat ValueType = "float"
ValueTypeBoolean ValueType = "boolean"
ValueTypeString ValueType = "string"
)
type DefaultType string
const (
DefaultTypeDefault DefaultType = "default_val"
DefaultTypeCreative DefaultType = "creative"
DefaultTypeBalance DefaultType = "balance"
DefaultTypePrecise DefaultType = "precise"
)
// Deprecated
type Scenario int64 // 模型实体使用场景
type Modal string
const (
ModalText Modal = "text"
ModalImage Modal = "image"
ModalFile Modal = "file"
ModalAudio Modal = "audio"
ModalVideo Modal = "video"
)
type ModelStatus int64
const (
StatusDefault ModelStatus = 0 // 未配置时的默认状态,表现等同 StatusInUse
StatusInUse ModelStatus = 1 // 应用中,可使用可新建
StatusPending ModelStatus = 5 // 待下线,可使用不可新建
StatusDeleted ModelStatus = 10 // 已下线,不可使用不可新建
)
type Widget string
const (
WidgetSlider Widget = "slider"
WidgetRadioButtons Widget = "radio_buttons"
)

View File

@@ -0,0 +1,169 @@
package modelmgr
import (
"fmt"
"strconv"
"github.com/coze-dev/coze-studio/backend/infra/contract/chatmodel"
"github.com/coze-dev/coze-studio/backend/pkg/i18n"
)
type Model struct {
ID int64 `yaml:"id"`
Name string `yaml:"name"`
IconURI string `yaml:"icon_uri"`
IconURL string `yaml:"icon_url"`
Description *MultilingualText `yaml:"description"`
DefaultParameters []*Parameter `yaml:"default_parameters"`
Meta ModelMeta `yaml:"meta"`
}
func (m *Model) FindParameter(name ParameterName) (*Parameter, bool) {
if len(m.DefaultParameters) == 0 {
return nil, false
}
for _, param := range m.DefaultParameters {
if param.Name == name {
return param, true
}
}
return nil, false
}
type Parameter struct {
Name ParameterName `json:"name" yaml:"name"`
Label *MultilingualText `json:"label,omitempty" yaml:"label,omitempty"`
Desc *MultilingualText `json:"desc" yaml:"desc"`
Type ValueType `json:"type" yaml:"type"`
Min string `json:"min" yaml:"min"`
Max string `json:"max" yaml:"max"`
DefaultVal DefaultValue `json:"default_val" yaml:"default_val"`
Precision int `json:"precision,omitempty" yaml:"precision,omitempty"` // float precision, default 2
Options []*ParamOption `json:"options" yaml:"options"` // enum options
Style DisplayStyle `json:"param_class" yaml:"style"`
}
func (p *Parameter) GetFloat(tp DefaultType) (float64, error) {
if p.Type != ValueTypeFloat {
return 0, fmt.Errorf("unexpected paramerter type, name=%v, expect=%v, given=%v",
p.Name, ValueTypeFloat, p.Type)
}
if tp != DefaultTypeDefault && p.DefaultVal[tp] == "" {
tp = DefaultTypeDefault
}
val, ok := p.DefaultVal[tp]
if !ok {
return 0, fmt.Errorf("unexpected default type, name=%v, type=%v", p.Name, tp)
}
return strconv.ParseFloat(val, 64)
}
func (p *Parameter) GetInt(tp DefaultType) (int64, error) {
if p.Type != ValueTypeInt {
return 0, fmt.Errorf("unexpected paramerter type, name=%v, expect=%v, given=%v",
p.Name, ValueTypeInt, p.Type)
}
if tp != DefaultTypeDefault && p.DefaultVal[tp] == "" {
tp = DefaultTypeDefault
}
val, ok := p.DefaultVal[tp]
if !ok {
return 0, fmt.Errorf("unexpected default type, name=%v, type=%v", p.Name, tp)
}
return strconv.ParseInt(val, 10, 64)
}
func (p *Parameter) GetBool(tp DefaultType) (bool, error) {
if p.Type != ValueTypeBoolean {
return false, fmt.Errorf("unexpected paramerter type, name=%v, expect=%v, given=%v",
p.Name, ValueTypeBoolean, p.Type)
}
if tp != DefaultTypeDefault && p.DefaultVal[tp] == "" {
tp = DefaultTypeDefault
}
val, ok := p.DefaultVal[tp]
if !ok {
return false, fmt.Errorf("unexpected default type, name=%v, type=%v", p.Name, tp)
}
return strconv.ParseBool(val)
}
func (p *Parameter) GetString(tp DefaultType) (string, error) {
if tp != DefaultTypeDefault && p.DefaultVal[tp] == "" {
tp = DefaultTypeDefault
}
val, ok := p.DefaultVal[tp]
if !ok {
return "", fmt.Errorf("unexpected default type, name=%v, type=%v", p.Name, tp)
}
return val, nil
}
type ModelMeta struct {
Name string `yaml:"name"`
Protocol chatmodel.Protocol `yaml:"protocol"` // 模型通信协议
Capability *Capability `yaml:"capability"` // 模型能力
ConnConfig *chatmodel.Config `yaml:"conn_config"` // 模型连接配置
Status ModelStatus `yaml:"status"` // 模型状态
}
type DefaultValue map[DefaultType]string
type DisplayStyle struct {
Widget Widget `json:"class_id" yaml:"widget"`
Label *MultilingualText `json:"label" yaml:"label"`
}
type ParamOption struct {
Label string `json:"label"`
Value string `json:"value"`
}
type Capability struct {
// Model supports function calling
FunctionCall bool `json:"function_call" yaml:"function_call" mapstructure:"function_call"`
// Input modals
InputModal []Modal `json:"input_modal,omitempty" yaml:"input_modal,omitempty" mapstructure:"input_modal,omitempty"`
// Input tokens
InputTokens int `json:"input_tokens" yaml:"input_tokens" mapstructure:"input_tokens"`
// Model supports json mode
JSONMode bool `json:"json_mode" yaml:"json_mode" mapstructure:"json_mode"`
// Max tokens
MaxTokens int `json:"max_tokens" yaml:"max_tokens" mapstructure:"max_tokens"`
// Output modals
OutputModal []Modal `json:"output_modal,omitempty" yaml:"output_modal,omitempty" mapstructure:"output_modal,omitempty"`
// Output tokens
OutputTokens int `json:"output_tokens" yaml:"output_tokens" mapstructure:"output_tokens"`
// Model supports prefix caching
PrefixCaching bool `json:"prefix_caching" yaml:"prefix_caching" mapstructure:"prefix_caching"`
// Model supports reasoning
Reasoning bool `json:"reasoning" yaml:"reasoning" mapstructure:"reasoning"`
// Model supports prefill response
PrefillResponse bool `json:"prefill_response" yaml:"prefill_response" mapstructure:"prefill_response"`
}
type MultilingualText struct {
ZH string `json:"zh,omitempty" yaml:"zh,omitempty"`
EN string `json:"en,omitempty" yaml:"en,omitempty"`
}
func (m *MultilingualText) Read(locale i18n.Locale) string {
if m == nil {
return ""
}
switch locale {
case i18n.LocaleZH:
return m.ZH
case i18n.LocaleEN:
return m.EN
default:
return m.EN
}
}

View File

@@ -0,0 +1,27 @@
package modelmgr
import (
"context"
)
type Manager interface {
ListModel(ctx context.Context, req *ListModelRequest) (*ListModelResponse, error)
MGetModelByID(ctx context.Context, req *MGetModelRequest) ([]*Model, error)
}
type ListModelRequest struct {
FuzzyModelName *string
Status []ModelStatus // default is default and in_use status
Limit int
Cursor *string
}
type ListModelResponse struct {
ModelList []*Model
HasMore bool
NextCursor *string
}
type MGetModelRequest struct {
IDs []int64
}