186 lines
		
	
	
		
			5.9 KiB
		
	
	
	
		
			Go
		
	
	
	
			
		
		
	
	
			186 lines
		
	
	
		
			5.9 KiB
		
	
	
	
		
			Go
		
	
	
	
| /*
 | |
|  * Copyright 2025 coze-dev Authors
 | |
|  *
 | |
|  * Licensed under the Apache License, Version 2.0 (the "License");
 | |
|  * you may not use this file except in compliance with the License.
 | |
|  * You may obtain a copy of the License at
 | |
|  *
 | |
|  *     http://www.apache.org/licenses/LICENSE-2.0
 | |
|  *
 | |
|  * Unless required by applicable law or agreed to in writing, software
 | |
|  * distributed under the License is distributed on an "AS IS" BASIS,
 | |
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | |
|  * See the License for the specific language governing permissions and
 | |
|  * limitations under the License.
 | |
|  */
 | |
| 
 | |
| 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
 | |
| 	}
 | |
| }
 |