diff --git a/backend/api/model/admin/config/config.go b/backend/api/model/admin/config/config.go index 02734288ba..70f16632d2 100644 --- a/backend/api/model/admin/config/config.go +++ b/backend/api/model/admin/config/config.go @@ -2457,6 +2457,7 @@ type Connection struct { Qwen *QwenConnInfo `thrift:"qwen,6,optional" form:"qwen" json:"qwen,omitempty" query:"qwen"` Ollama *OllamaConnInfo `thrift:"ollama,7,optional" form:"ollama" json:"ollama,omitempty" query:"ollama"` Claude *ClaudeConnInfo `thrift:"claude,8,optional" form:"claude" json:"claude,omitempty" query:"claude"` + Avian *AvianConnInfo `thrift:"avian,9,optional" form:"avian" json:"avian,omitempty" query:"avian"` } func NewConnection() *Connection { @@ -2538,6 +2539,15 @@ func (p *Connection) GetClaude() (v *ClaudeConnInfo) { return p.Claude } +var Connection_Avian_DEFAULT *AvianConnInfo + +func (p *Connection) GetAvian() (v *AvianConnInfo) { + if !p.IsSetAvian() { + return Connection_Avian_DEFAULT + } + return p.Avian +} + var fieldIDToName_Connection = map[int16]string{ 1: "base_conn_info", 2: "ark", @@ -2581,6 +2591,10 @@ func (p *Connection) IsSetClaude() bool { return p.Claude != nil } +func (p *Connection) IsSetAvian() bool { + return p.Avian != nil +} + func (p *Connection) Read(iprot thrift.TProtocol) (err error) { var fieldTypeId thrift.TType var fieldId int16 @@ -4303,6 +4317,88 @@ func (p *ClaudeConnInfo) String() string { } +type AvianConnInfo struct { +} + +func NewAvianConnInfo() *AvianConnInfo { + return &AvianConnInfo{} +} + +func (p *AvianConnInfo) InitDefault() { +} + +var fieldIDToName_AvianConnInfo = map[int16]string{} + +func (p *AvianConnInfo) Read(iprot thrift.TProtocol) (err error) { + var fieldTypeId thrift.TType + var fieldId int16 + + if _, err = iprot.ReadStructBegin(); err != nil { + goto ReadStructBeginError + } + + for { + _, fieldTypeId, fieldId, err = iprot.ReadFieldBegin() + if err != nil { + goto ReadFieldBeginError + } + if fieldTypeId == thrift.STOP { + break + } + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldTypeError + } + if err = iprot.ReadFieldEnd(); err != nil { + goto ReadFieldEndError + } + } + if err = iprot.ReadStructEnd(); err != nil { + goto ReadStructEndError + } + + return nil +ReadStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T read struct begin error: ", p), err) +ReadFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T read field %d begin error: ", p, fieldId), err) +SkipFieldTypeError: + return thrift.PrependError(fmt.Sprintf("%T skip field type %d error", p, fieldTypeId), err) + +ReadFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T read field end error", p), err) +ReadStructEndError: + return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err) +} + +func (p *AvianConnInfo) Write(oprot thrift.TProtocol) (err error) { + if err = oprot.WriteStructBegin("AvianConnInfo"); err != nil { + goto WriteStructBeginError + } + if p != nil { + } + if err = oprot.WriteFieldStop(); err != nil { + goto WriteFieldStopError + } + if err = oprot.WriteStructEnd(); err != nil { + goto WriteStructEndError + } + return nil +WriteStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err) +WriteFieldStopError: + return thrift.PrependError(fmt.Sprintf("%T write field stop error: ", p), err) +WriteStructEndError: + return thrift.PrependError(fmt.Sprintf("%T write struct end error: ", p), err) +} + +func (p *AvianConnInfo) String() string { + if p == nil { + return "" + } + return fmt.Sprintf("AvianConnInfo(%+v)", *p) + +} + type CreateModelReq struct { ModelClass developer_api.ModelClass `thrift:"model_class,1" form:"model_class" json:"model_class" query:"model_class"` ModelName string `thrift:"model_name,2" form:"model_name" json:"model_name" query:"model_name"` diff --git a/backend/api/model/app/developer_api/developer_api.go b/backend/api/model/app/developer_api/developer_api.go index 7319d9d278..d6979aed25 100644 --- a/backend/api/model/app/developer_api/developer_api.go +++ b/backend/api/model/app/developer_api/developer_api.go @@ -935,6 +935,7 @@ const ( // name: Llama ModelClass_Llama ModelClass = 20 ModelClass_StepFun ModelClass = 23 + ModelClass_Avian ModelClass = 24 ModelClass_Other ModelClass = 999 ) @@ -980,6 +981,8 @@ func (p ModelClass) String() string { return "Llama" case ModelClass_StepFun: return "StepFun" + case ModelClass_Avian: + return "Avian" case ModelClass_Other: return "Other" } @@ -1028,6 +1031,8 @@ func ModelClassFromString(s string) (ModelClass, error) { return ModelClass_Llama, nil case "StepFun": return ModelClass_StepFun, nil + case "Avian": + return ModelClass_Avian, nil case "Other": return ModelClass_Other, nil } diff --git a/backend/bizpkg/config/modelmgr/builtin_conf.go b/backend/bizpkg/config/modelmgr/builtin_conf.go index 89e39fdda5..41b7d780c1 100644 --- a/backend/bizpkg/config/modelmgr/builtin_conf.go +++ b/backend/bizpkg/config/modelmgr/builtin_conf.go @@ -93,6 +93,8 @@ func getKnowledgeBuiltinModelClass() developer_api.ModelClass { return developer_api.ModelClass_QWen case "gemini": return developer_api.ModelClass_Gemini + case "avian": + return developer_api.ModelClass_Avian default: return developer_api.ModelClass_SEED } diff --git a/backend/bizpkg/config/modelmgr/mode_provider.go b/backend/bizpkg/config/modelmgr/mode_provider.go index e3bdb3a79c..79407e5103 100644 --- a/backend/bizpkg/config/modelmgr/mode_provider.go +++ b/backend/bizpkg/config/modelmgr/mode_provider.go @@ -107,6 +107,18 @@ func getModelProviderList() []*config.ModelProvider { }, ModelClass: developer_api.ModelClass_QWen, }, + { + Name: &config.I18nText{ + ZhCn: "Avian 模型", + EnUs: "Avian Model", + }, + IconURI: "default_icon/avian.png", + Description: &config.I18nText{ + ZhCn: "Avian 模型家族", + EnUs: "avian model family", + }, + ModelClass: developer_api.ModelClass_Avian, + }, } } diff --git a/backend/bizpkg/config/modelmgr/model_save.go b/backend/bizpkg/config/modelmgr/model_save.go index a5b26e3273..adff42a7c4 100644 --- a/backend/bizpkg/config/modelmgr/model_save.go +++ b/backend/bizpkg/config/modelmgr/model_save.go @@ -74,6 +74,7 @@ func (c *ModelConfig) createModel(ctx context.Context, id *int64, modelClass dev conn.Qwen = modelMeta.Connection.Qwen conn.Ollama = modelMeta.Connection.Ollama conn.Claude = modelMeta.Connection.Claude + conn.Avian = modelMeta.Connection.Avian } extraStr := "{}" diff --git a/backend/bizpkg/llm/modelbuilder/avian.go b/backend/bizpkg/llm/modelbuilder/avian.go new file mode 100644 index 0000000000..f58a516caf --- /dev/null +++ b/backend/bizpkg/llm/modelbuilder/avian.go @@ -0,0 +1,100 @@ +/* + * 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 modelbuilder + +import ( + "context" + + "github.com/cloudwego/eino-ext/components/model/openai" + + "github.com/coze-dev/coze-studio/backend/api/model/admin/config" + "github.com/coze-dev/coze-studio/backend/api/model/app/bot_common" + "github.com/coze-dev/coze-studio/backend/pkg/lang/ptr" +) + +const avianDefaultBaseURL = "https://api.avian.io/v1" + +type avianModelBuilder struct { + cfg *config.Model +} + +func newAvianModelBuilder(cfg *config.Model) Service { + return &avianModelBuilder{ + cfg: cfg, + } +} + +func (a *avianModelBuilder) getDefaultConfig() *openai.ChatModelConfig { + return &openai.ChatModelConfig{ + BaseURL: avianDefaultBaseURL, + MaxCompletionTokens: ptr.Of(4096), + ResponseFormat: &openai.ChatCompletionResponseFormat{ + Type: "text", + JSONSchema: nil, + }, + } +} + +func (a *avianModelBuilder) applyParamsToConfig(conf *openai.ChatModelConfig, params *LLMParams) { + if params == nil { + return + } + + if params.Temperature != nil { + conf.Temperature = ptr.Of(*params.Temperature) + } + + if params.MaxTokens != 0 { + conf.MaxCompletionTokens = ptr.Of(params.MaxTokens) + } + + if params.FrequencyPenalty != 0 { + conf.FrequencyPenalty = ptr.Of(params.FrequencyPenalty) + } + + if params.PresencePenalty != 0 { + conf.PresencePenalty = ptr.Of(params.PresencePenalty) + } + + conf.TopP = params.TopP + + if params.ResponseFormat == bot_common.ModelResponseFormat_JSON { + conf.ResponseFormat = &openai.ChatCompletionResponseFormat{ + Type: openai.ChatCompletionResponseFormatTypeJSONObject, + } + } else { + conf.ResponseFormat = &openai.ChatCompletionResponseFormat{ + Type: openai.ChatCompletionResponseFormatTypeText, + } + } +} + +func (a *avianModelBuilder) Build(ctx context.Context, params *LLMParams) (ToolCallingChatModel, error) { + base := a.cfg.Connection.BaseConnInfo + + conf := a.getDefaultConfig() + conf.APIKey = base.APIKey + conf.Model = base.Model + + if base.BaseURL != "" { + conf.BaseURL = base.BaseURL + } + + a.applyParamsToConfig(conf, params) + + return openai.NewChatModel(ctx, conf) +} diff --git a/backend/bizpkg/llm/modelbuilder/model_builder.go b/backend/bizpkg/llm/modelbuilder/model_builder.go index 7b74ff41a0..537ef881b0 100644 --- a/backend/bizpkg/llm/modelbuilder/model_builder.go +++ b/backend/bizpkg/llm/modelbuilder/model_builder.go @@ -47,6 +47,7 @@ var modelClass2NewModelBuilder = map[developer_api.ModelClass]func(*config.Model developer_api.ModelClass_Gemini: newGeminiModelBuilder, developer_api.ModelClass_Llama: newOllamaModelBuilder, developer_api.ModelClass_QWen: newQwenModelBuilder, + developer_api.ModelClass_Avian: newAvianModelBuilder, } func NewModelBuilder(modelClass developer_api.ModelClass, cfg *config.Model) (Service, error) { diff --git a/backend/conf/model/model_meta.json b/backend/conf/model/model_meta.json index 7d83301a72..e024d85a98 100644 --- a/backend/conf/model/model_meta.json +++ b/backend/conf/model/model_meta.json @@ -5496,6 +5496,111 @@ } ] } + }, + "Avian": { + "default": { + "display_info": { + "output_tokens": 65536, + "max_tokens": 163840 + }, + "capability": { + "function_call": true, + "image_understanding": false, + "video_understanding": false, + "audio_understanding": false, + "support_multi_modal": false + }, + "parameters": [ + { + "name": "temperature", + "label": "Temperature", + "desc": "**Temperature**:\n\n- When you increase this value, the model outputs more diverse and innovative content; when you decrease it, the model outputs less diverse content that strictly follows the given instructions.\n- It is recommended not to adjust this value with \"Top p\" at the same time.", + "type": 1, + "min": "0", + "max": "2", + "precision": 2, + "default_val": { + "default_val": "0.7", + "creative": "1.0", + "balance": "0.7", + "precise": "0.1" + }, + "options": [], + "param_class": { + "class_id": 1, + "label": "Generation diversity" + } + }, + { + "name": "max_tokens", + "label": "Response max length", + "desc": "You can specify the maximum length of the tokens output through this value. Typically, 100 tokens are approximately equal to 150 Chinese characters.", + "type": 2, + "min": "1", + "max": "65536", + "precision": 0, + "default_val": { + "default_val": "4096" + }, + "options": [], + "param_class": { + "class_id": 2, + "label": "Input and output settings" + } + }, + { + "name": "top_p", + "label": "Top P", + "desc": "**Top p**:\n\n- Similar to temperature, but do not adjust both at the same time.", + "type": 1, + "min": "0", + "max": "1", + "precision": 2, + "default_val": { + "default_val": "0.9" + }, + "options": [], + "param_class": { + "class_id": 1, + "label": "Generation diversity" + } + }, + { + "name": "frequency_penalty", + "label": "Frequency penalty", + "desc": "**Frequency penalty**:\n\n- A positive value will penalize new tokens based on their existing frequency in the generated text so far, decreasing the model's likelihood to repeat the same line verbatim.", + "type": 1, + "min": "-2", + "max": "2", + "precision": 2, + "default_val": { + "default_val": "0" + }, + "options": [], + "param_class": { + "class_id": 1, + "label": "Generation diversity" + } + }, + { + "name": "presence_penalty", + "label": "Presence penalty", + "desc": "**Presence penalty**:\n\n- A positive value will penalize new tokens based on whether they appear in the generated text so far, increasing the model's likelihood to talk about new topics.", + "type": 1, + "min": "-2", + "max": "2", + "precision": 2, + "default_val": { + "default_val": "0" + }, + "options": [], + "param_class": { + "class_id": 1, + "label": "Generation diversity" + } + } + ] + } } } } \ No newline at end of file diff --git a/docker/volumes/minio/default_icon/avian.png b/docker/volumes/minio/default_icon/avian.png new file mode 100644 index 0000000000..43e011dd7a Binary files /dev/null and b/docker/volumes/minio/default_icon/avian.png differ diff --git a/frontend/packages/arch/idl/src/auto-generated/developer_api/namespaces/developer_api.ts b/frontend/packages/arch/idl/src/auto-generated/developer_api/namespaces/developer_api.ts index 6cad6fa905..a9618bdf20 100644 --- a/frontend/packages/arch/idl/src/auto-generated/developer_api/namespaces/developer_api.ts +++ b/frontend/packages/arch/idl/src/auto-generated/developer_api/namespaces/developer_api.ts @@ -686,6 +686,8 @@ export enum ModelClass { /** name: Llama */ Llama = 20, StepFun = 23, + /** name: Avian */ + Avian = 24, Other = 999, } diff --git a/frontend/packages/arch/idl/src/auto-generated/intelligence_api/namespaces/domain_model.ts b/frontend/packages/arch/idl/src/auto-generated/intelligence_api/namespaces/domain_model.ts index 7e82a85289..f51ca44f9f 100644 --- a/frontend/packages/arch/idl/src/auto-generated/intelligence_api/namespaces/domain_model.ts +++ b/frontend/packages/arch/idl/src/auto-generated/intelligence_api/namespaces/domain_model.ts @@ -54,6 +54,8 @@ export enum DomainModelClass { /** name: Llama */ Llama = 20, StepFun = 23, + /** name: Avian */ + Avian = 24, Other = 999, } diff --git a/frontend/packages/arch/idl/src/auto-generated/intelligence_api/namespaces/model.ts b/frontend/packages/arch/idl/src/auto-generated/intelligence_api/namespaces/model.ts index 4b64fc6f5d..90dc8b097f 100644 --- a/frontend/packages/arch/idl/src/auto-generated/intelligence_api/namespaces/model.ts +++ b/frontend/packages/arch/idl/src/auto-generated/intelligence_api/namespaces/model.ts @@ -62,6 +62,8 @@ export enum ModelClass { /** name: Llama */ Llama = 20, StepFun = 23, + /** name: Avian */ + Avian = 24, Other = 999, } diff --git a/helm/charts/opencoze/files/conf/model/model_meta.json b/helm/charts/opencoze/files/conf/model/model_meta.json index 9419ed9d50..8ef61b8c0d 100644 --- a/helm/charts/opencoze/files/conf/model/model_meta.json +++ b/helm/charts/opencoze/files/conf/model/model_meta.json @@ -722,6 +722,111 @@ } ] } + }, + "Avian": { + "default": { + "display_info": { + "output_tokens": 65536, + "max_tokens": 163840 + }, + "capability": { + "function_call": true, + "image_understanding": false, + "video_understanding": false, + "audio_understanding": false, + "support_multi_modal": false + }, + "parameters": [ + { + "name": "temperature", + "label": "Temperature", + "desc": "**Temperature**:\n\n- When you increase this value, the model outputs more diverse and innovative content; when you decrease it, the model outputs less diverse content that strictly follows the given instructions.\n- It is recommended not to adjust this value with \"Top p\" at the same time.", + "type": 1, + "min": "0", + "max": "2", + "precision": 2, + "default_val": { + "default_val": "0.7", + "creative": "1.0", + "balance": "0.7", + "precise": "0.1" + }, + "options": [], + "param_class": { + "class_id": 1, + "label": "Generation diversity" + } + }, + { + "name": "max_tokens", + "label": "Response max length", + "desc": "You can specify the maximum length of the tokens output through this value. Typically, 100 tokens are approximately equal to 150 Chinese characters.", + "type": 2, + "min": "1", + "max": "65536", + "precision": 0, + "default_val": { + "default_val": "4096" + }, + "options": [], + "param_class": { + "class_id": 2, + "label": "Input and output settings" + } + }, + { + "name": "top_p", + "label": "Top P", + "desc": "**Top p**:\n\n- Similar to temperature, but do not adjust both at the same time.", + "type": 1, + "min": "0", + "max": "1", + "precision": 2, + "default_val": { + "default_val": "0.9" + }, + "options": [], + "param_class": { + "class_id": 1, + "label": "Generation diversity" + } + }, + { + "name": "frequency_penalty", + "label": "Frequency penalty", + "desc": "**Frequency penalty**:\n\n- A positive value will penalize new tokens based on their existing frequency in the generated text so far, decreasing the model's likelihood to repeat the same line verbatim.", + "type": 1, + "min": "-2", + "max": "2", + "precision": 2, + "default_val": { + "default_val": "0" + }, + "options": [], + "param_class": { + "class_id": 1, + "label": "Generation diversity" + } + }, + { + "name": "presence_penalty", + "label": "Presence penalty", + "desc": "**Presence penalty**:\n\n- A positive value will penalize new tokens based on whether they appear in the generated text so far, increasing the model's likelihood to talk about new topics.", + "type": 1, + "min": "-2", + "max": "2", + "precision": 2, + "default_val": { + "default_val": "0" + }, + "options": [], + "param_class": { + "class_id": 1, + "label": "Generation diversity" + } + } + ] + } } } } \ No newline at end of file diff --git a/idl/admin/config.thrift b/idl/admin/config.thrift index e7b265c71a..a79c83711f 100644 --- a/idl/admin/config.thrift +++ b/idl/admin/config.thrift @@ -85,6 +85,7 @@ struct Connection { 6: optional QwenConnInfo qwen 7: optional OllamaConnInfo ollama 8: optional ClaudeConnInfo claude + 9: optional AvianConnInfo avian } struct BaseConnectionInfo { @@ -124,6 +125,8 @@ struct OllamaConnInfo {} struct ClaudeConnInfo {} +struct AvianConnInfo {} + struct CreateModelReq { 1: developer_api.ModelClass model_class 2: string model_name diff --git a/idl/app/developer_api.thrift b/idl/app/developer_api.thrift index af7c29595f..97b8c0e441 100644 --- a/idl/app/developer_api.thrift +++ b/idl/app/developer_api.thrift @@ -538,6 +538,7 @@ enum ModelClass { DeekSeek = 19 // Name: Magic Square Llama = 20 // name: Llama StepFun = 23 + Avian = 24 // Name: Avian Other = 999 }