feat: model configuration and embedding configuration optimization. (#2414)
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
This commit is contained in:
@ -132,13 +132,28 @@ func UpdateKnowledgeConfig(ctx context.Context, c *app.RequestContext) {
|
||||
return
|
||||
}
|
||||
|
||||
if req.KnowledgeConfig.EmbeddingConfig == nil {
|
||||
invalidParamRequestResponse(c, "EmbeddingConfig is nil")
|
||||
return
|
||||
}
|
||||
|
||||
if req.KnowledgeConfig.EmbeddingConfig.Connection == nil {
|
||||
invalidParamRequestResponse(c, "Connection is nil")
|
||||
return
|
||||
}
|
||||
|
||||
if req.KnowledgeConfig.EmbeddingConfig.Connection.EmbeddingInfo == nil {
|
||||
invalidParamRequestResponse(c, "EmbeddingInfo is nil")
|
||||
return
|
||||
}
|
||||
|
||||
embedding, err := impl.GetEmbedding(ctx, req.KnowledgeConfig.EmbeddingConfig)
|
||||
if err != nil {
|
||||
invalidParamRequestResponse(c, fmt.Sprintf("get embedding failed: %v", err))
|
||||
return
|
||||
}
|
||||
|
||||
if req.KnowledgeConfig.EmbeddingConfig.Connection.EmbeddingInfo.Dims == 0 {
|
||||
if req.KnowledgeConfig.EmbeddingConfig.Connection.EmbeddingInfo.Dims <= 0 {
|
||||
req.KnowledgeConfig.EmbeddingConfig.Connection.EmbeddingInfo.Dims = int32(embedding.Dimensions())
|
||||
|
||||
embedding, err = impl.GetEmbedding(ctx, req.KnowledgeConfig.EmbeddingConfig)
|
||||
|
||||
@ -59,6 +59,58 @@ func (p *ModelType) Value() (driver.Value, error) {
|
||||
return int64(*p), nil
|
||||
}
|
||||
|
||||
type ThinkingType int64
|
||||
|
||||
const (
|
||||
ThinkingType_Default ThinkingType = 0
|
||||
ThinkingType_Enable ThinkingType = 1
|
||||
ThinkingType_Disable ThinkingType = 2
|
||||
ThinkingType_Auto ThinkingType = 3
|
||||
)
|
||||
|
||||
func (p ThinkingType) String() string {
|
||||
switch p {
|
||||
case ThinkingType_Default:
|
||||
return "Default"
|
||||
case ThinkingType_Enable:
|
||||
return "Enable"
|
||||
case ThinkingType_Disable:
|
||||
return "Disable"
|
||||
case ThinkingType_Auto:
|
||||
return "Auto"
|
||||
}
|
||||
return "<UNSET>"
|
||||
}
|
||||
|
||||
func ThinkingTypeFromString(s string) (ThinkingType, error) {
|
||||
switch s {
|
||||
case "Default":
|
||||
return ThinkingType_Default, nil
|
||||
case "Enable":
|
||||
return ThinkingType_Enable, nil
|
||||
case "Disable":
|
||||
return ThinkingType_Disable, nil
|
||||
case "Auto":
|
||||
return ThinkingType_Auto, nil
|
||||
}
|
||||
return ThinkingType(0), fmt.Errorf("not a valid ThinkingType string")
|
||||
}
|
||||
|
||||
func ThinkingTypePtr(v ThinkingType) *ThinkingType { return &v }
|
||||
func (p *ThinkingType) Scan(value interface{}) (err error) {
|
||||
var result sql.NullInt64
|
||||
err = result.Scan(value)
|
||||
*p = ThinkingType(result.Int64)
|
||||
return
|
||||
}
|
||||
|
||||
func (p *ThinkingType) Value() (driver.Value, error) {
|
||||
if p == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return int64(*p), nil
|
||||
}
|
||||
|
||||
type ModelStatus int64
|
||||
|
||||
const (
|
||||
@ -2913,9 +2965,10 @@ func (p *Connection) String() string {
|
||||
}
|
||||
|
||||
type BaseConnectionInfo struct {
|
||||
BaseURL string `thrift:"base_url,1" form:"base_url" json:"base_url" query:"base_url"`
|
||||
APIKey string `thrift:"api_key,2" form:"api_key" json:"api_key" query:"api_key"`
|
||||
Model string `thrift:"model,3" form:"model" json:"model" query:"model"`
|
||||
BaseURL string `thrift:"base_url,1" form:"base_url" json:"base_url" query:"base_url"`
|
||||
APIKey string `thrift:"api_key,2" form:"api_key" json:"api_key" query:"api_key"`
|
||||
Model string `thrift:"model,3" form:"model" json:"model" query:"model"`
|
||||
ThinkingType ThinkingType `thrift:"thinking_type,4" form:"thinking_type" json:"thinking_type" query:"thinking_type"`
|
||||
}
|
||||
|
||||
func NewBaseConnectionInfo() *BaseConnectionInfo {
|
||||
@ -2937,10 +2990,15 @@ func (p *BaseConnectionInfo) GetModel() (v string) {
|
||||
return p.Model
|
||||
}
|
||||
|
||||
func (p *BaseConnectionInfo) GetThinkingType() (v ThinkingType) {
|
||||
return p.ThinkingType
|
||||
}
|
||||
|
||||
var fieldIDToName_BaseConnectionInfo = map[int16]string{
|
||||
1: "base_url",
|
||||
2: "api_key",
|
||||
3: "model",
|
||||
4: "thinking_type",
|
||||
}
|
||||
|
||||
func (p *BaseConnectionInfo) Read(iprot thrift.TProtocol) (err error) {
|
||||
@ -2985,6 +3043,14 @@ func (p *BaseConnectionInfo) Read(iprot thrift.TProtocol) (err error) {
|
||||
} else if err = iprot.Skip(fieldTypeId); err != nil {
|
||||
goto SkipFieldError
|
||||
}
|
||||
case 4:
|
||||
if fieldTypeId == thrift.I32 {
|
||||
if err = p.ReadField4(iprot); err != nil {
|
||||
goto ReadFieldError
|
||||
}
|
||||
} else if err = iprot.Skip(fieldTypeId); err != nil {
|
||||
goto SkipFieldError
|
||||
}
|
||||
default:
|
||||
if err = iprot.Skip(fieldTypeId); err != nil {
|
||||
goto SkipFieldError
|
||||
@ -3047,6 +3113,17 @@ func (p *BaseConnectionInfo) ReadField3(iprot thrift.TProtocol) error {
|
||||
p.Model = _field
|
||||
return nil
|
||||
}
|
||||
func (p *BaseConnectionInfo) ReadField4(iprot thrift.TProtocol) error {
|
||||
|
||||
var _field ThinkingType
|
||||
if v, err := iprot.ReadI32(); err != nil {
|
||||
return err
|
||||
} else {
|
||||
_field = ThinkingType(v)
|
||||
}
|
||||
p.ThinkingType = _field
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *BaseConnectionInfo) Write(oprot thrift.TProtocol) (err error) {
|
||||
var fieldId int16
|
||||
@ -3066,6 +3143,10 @@ func (p *BaseConnectionInfo) Write(oprot thrift.TProtocol) (err error) {
|
||||
fieldId = 3
|
||||
goto WriteFieldError
|
||||
}
|
||||
if err = p.writeField4(oprot); err != nil {
|
||||
fieldId = 4
|
||||
goto WriteFieldError
|
||||
}
|
||||
}
|
||||
if err = oprot.WriteFieldStop(); err != nil {
|
||||
goto WriteFieldStopError
|
||||
@ -3132,6 +3213,22 @@ WriteFieldBeginError:
|
||||
WriteFieldEndError:
|
||||
return thrift.PrependError(fmt.Sprintf("%T write field 3 end error: ", p), err)
|
||||
}
|
||||
func (p *BaseConnectionInfo) writeField4(oprot thrift.TProtocol) (err error) {
|
||||
if err = oprot.WriteFieldBegin("thinking_type", thrift.I32, 4); err != nil {
|
||||
goto WriteFieldBeginError
|
||||
}
|
||||
if err := oprot.WriteI32(int32(p.ThinkingType)); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = oprot.WriteFieldEnd(); err != nil {
|
||||
goto WriteFieldEndError
|
||||
}
|
||||
return nil
|
||||
WriteFieldBeginError:
|
||||
return thrift.PrependError(fmt.Sprintf("%T write field 4 begin error: ", p), err)
|
||||
WriteFieldEndError:
|
||||
return thrift.PrependError(fmt.Sprintf("%T write field 4 end error: ", p), err)
|
||||
}
|
||||
|
||||
func (p *BaseConnectionInfo) String() string {
|
||||
if p == nil {
|
||||
@ -3465,9 +3562,8 @@ func (p *ArkConnInfo) String() string {
|
||||
}
|
||||
|
||||
type OpenAIConnInfo struct {
|
||||
RequestDims int32 `thrift:"request_dims,5" form:"request_dims" json:"request_dims" query:"request_dims"`
|
||||
ByAzure bool `thrift:"by_azure,6" form:"by_azure" json:"by_azure" query:"by_azure"`
|
||||
APIVersion string `thrift:"api_version,7" form:"api_version" json:"api_version" query:"api_version"`
|
||||
ByAzure bool `thrift:"by_azure,6" form:"by_azure" json:"by_azure" query:"by_azure"`
|
||||
APIVersion string `thrift:"api_version,7" form:"api_version" json:"api_version" query:"api_version"`
|
||||
}
|
||||
|
||||
func NewOpenAIConnInfo() *OpenAIConnInfo {
|
||||
@ -3477,10 +3573,6 @@ func NewOpenAIConnInfo() *OpenAIConnInfo {
|
||||
func (p *OpenAIConnInfo) InitDefault() {
|
||||
}
|
||||
|
||||
func (p *OpenAIConnInfo) GetRequestDims() (v int32) {
|
||||
return p.RequestDims
|
||||
}
|
||||
|
||||
func (p *OpenAIConnInfo) GetByAzure() (v bool) {
|
||||
return p.ByAzure
|
||||
}
|
||||
@ -3490,7 +3582,6 @@ func (p *OpenAIConnInfo) GetAPIVersion() (v string) {
|
||||
}
|
||||
|
||||
var fieldIDToName_OpenAIConnInfo = map[int16]string{
|
||||
5: "request_dims",
|
||||
6: "by_azure",
|
||||
7: "api_version",
|
||||
}
|
||||
@ -3513,14 +3604,6 @@ func (p *OpenAIConnInfo) Read(iprot thrift.TProtocol) (err error) {
|
||||
}
|
||||
|
||||
switch fieldId {
|
||||
case 5:
|
||||
if fieldTypeId == thrift.I32 {
|
||||
if err = p.ReadField5(iprot); err != nil {
|
||||
goto ReadFieldError
|
||||
}
|
||||
} else if err = iprot.Skip(fieldTypeId); err != nil {
|
||||
goto SkipFieldError
|
||||
}
|
||||
case 6:
|
||||
if fieldTypeId == thrift.BOOL {
|
||||
if err = p.ReadField6(iprot); err != nil {
|
||||
@ -3566,17 +3649,6 @@ ReadStructEndError:
|
||||
return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err)
|
||||
}
|
||||
|
||||
func (p *OpenAIConnInfo) ReadField5(iprot thrift.TProtocol) error {
|
||||
|
||||
var _field int32
|
||||
if v, err := iprot.ReadI32(); err != nil {
|
||||
return err
|
||||
} else {
|
||||
_field = v
|
||||
}
|
||||
p.RequestDims = _field
|
||||
return nil
|
||||
}
|
||||
func (p *OpenAIConnInfo) ReadField6(iprot thrift.TProtocol) error {
|
||||
|
||||
var _field bool
|
||||
@ -3606,10 +3678,6 @@ func (p *OpenAIConnInfo) Write(oprot thrift.TProtocol) (err error) {
|
||||
goto WriteStructBeginError
|
||||
}
|
||||
if p != nil {
|
||||
if err = p.writeField5(oprot); err != nil {
|
||||
fieldId = 5
|
||||
goto WriteFieldError
|
||||
}
|
||||
if err = p.writeField6(oprot); err != nil {
|
||||
fieldId = 6
|
||||
goto WriteFieldError
|
||||
@ -3636,22 +3704,6 @@ WriteStructEndError:
|
||||
return thrift.PrependError(fmt.Sprintf("%T write struct end error: ", p), err)
|
||||
}
|
||||
|
||||
func (p *OpenAIConnInfo) writeField5(oprot thrift.TProtocol) (err error) {
|
||||
if err = oprot.WriteFieldBegin("request_dims", thrift.I32, 5); err != nil {
|
||||
goto WriteFieldBeginError
|
||||
}
|
||||
if err := oprot.WriteI32(p.RequestDims); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = oprot.WriteFieldEnd(); err != nil {
|
||||
goto WriteFieldEndError
|
||||
}
|
||||
return nil
|
||||
WriteFieldBeginError:
|
||||
return thrift.PrependError(fmt.Sprintf("%T write field 5 begin error: ", p), err)
|
||||
WriteFieldEndError:
|
||||
return thrift.PrependError(fmt.Sprintf("%T write field 5 end error: ", p), err)
|
||||
}
|
||||
func (p *OpenAIConnInfo) writeField6(oprot thrift.TProtocol) (err error) {
|
||||
if err = oprot.WriteFieldBegin("by_azure", thrift.BOOL, 6); err != nil {
|
||||
goto WriteFieldBeginError
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
// Code generated by thriftgo (0.4.1). DO NOT EDIT.
|
||||
// Code generated by thriftgo (0.4.2). DO NOT EDIT.
|
||||
|
||||
package conversation
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
// Code generated by thriftgo (0.4.1). DO NOT EDIT.
|
||||
// Code generated by thriftgo (0.4.2). DO NOT EDIT.
|
||||
|
||||
package conversation
|
||||
|
||||
|
||||
@ -82,9 +82,8 @@ func getKnowledgeConfigurationFromOldConfig() *config.KnowledgeConfig {
|
||||
APIType: envkey.GetStringD("ARK_EMBEDDING_API_TYPE", "text_api"),
|
||||
},
|
||||
Openai: &config.OpenAIConnInfo{
|
||||
ByAzure: envkey.GetBoolD("OPENAI_EMBEDDING_BY_AZURE", false),
|
||||
APIVersion: envkey.GetString("OPENAI_EMBEDDING_API_VERSION"),
|
||||
RequestDims: envkey.GetI32D("OPENAI_EMBEDDING_REQUEST_DIMS", 1024),
|
||||
ByAzure: envkey.GetBoolD("OPENAI_EMBEDDING_BY_AZURE", false),
|
||||
APIVersion: envkey.GetString("OPENAI_EMBEDDING_API_VERSION"),
|
||||
},
|
||||
|
||||
Gemini: &config.GeminiConnInfo{
|
||||
|
||||
@ -33,7 +33,7 @@ type arkModelBuilder struct {
|
||||
cfg *config.Model
|
||||
}
|
||||
|
||||
func newArkModelBuilder(cfg *config.Model) *arkModelBuilder {
|
||||
func newArkModelBuilder(cfg *config.Model) Service {
|
||||
return &arkModelBuilder{
|
||||
cfg: cfg,
|
||||
}
|
||||
@ -84,6 +84,21 @@ func (b *arkModelBuilder) Build(ctx context.Context, params *LLMParams) (ToolCal
|
||||
chatModelConf.BaseURL = base.BaseURL
|
||||
}
|
||||
|
||||
switch base.ThinkingType {
|
||||
case config.ThinkingType_Enable:
|
||||
chatModelConf.Thinking = &model.Thinking{
|
||||
Type: model.ThinkingTypeEnabled,
|
||||
}
|
||||
case config.ThinkingType_Disable:
|
||||
chatModelConf.Thinking = &model.Thinking{
|
||||
Type: model.ThinkingTypeDisabled,
|
||||
}
|
||||
case config.ThinkingType_Auto:
|
||||
chatModelConf.Thinking = &model.Thinking{
|
||||
Type: model.ThinkingTypeAuto,
|
||||
}
|
||||
}
|
||||
|
||||
arkConn := b.cfg.Connection.Ark
|
||||
if arkConn != nil {
|
||||
chatModelConf.Region = arkConn.Region
|
||||
|
||||
@ -28,7 +28,7 @@ type claudeModelBuilder struct {
|
||||
cfg *config.Model
|
||||
}
|
||||
|
||||
func newClaudeModelBuilder(cfg *config.Model) *claudeModelBuilder {
|
||||
func newClaudeModelBuilder(cfg *config.Model) Service {
|
||||
return &claudeModelBuilder{
|
||||
cfg: cfg,
|
||||
}
|
||||
@ -71,6 +71,17 @@ func (c *claudeModelBuilder) Build(ctx context.Context, params *LLMParams) (Tool
|
||||
conf.BaseURL = &base.BaseURL
|
||||
}
|
||||
|
||||
switch base.ThinkingType {
|
||||
case config.ThinkingType_Enable:
|
||||
conf.Thinking = &claude.Thinking{
|
||||
Enable: true,
|
||||
}
|
||||
case config.ThinkingType_Disable:
|
||||
conf.Thinking = &claude.Thinking{
|
||||
Enable: false,
|
||||
}
|
||||
}
|
||||
|
||||
c.applyParamsToChatModelConfig(conf, params)
|
||||
|
||||
return claude.NewChatModel(ctx, conf)
|
||||
|
||||
@ -29,7 +29,7 @@ type deepseekModelBuilder struct {
|
||||
cfg *config.Model
|
||||
}
|
||||
|
||||
func newDeepseekModelBuilder(cfg *config.Model) *deepseekModelBuilder {
|
||||
func newDeepseekModelBuilder(cfg *config.Model) Service {
|
||||
return &deepseekModelBuilder{
|
||||
cfg: cfg,
|
||||
}
|
||||
|
||||
@ -30,7 +30,7 @@ type geminiModelBuilder struct {
|
||||
cfg *config.Model
|
||||
}
|
||||
|
||||
func newGeminiModelBuilder(cfg *config.Model) *geminiModelBuilder {
|
||||
func newGeminiModelBuilder(cfg *config.Model) Service {
|
||||
return &geminiModelBuilder{
|
||||
cfg: cfg,
|
||||
}
|
||||
@ -67,7 +67,6 @@ func (g *geminiModelBuilder) applyParamsToGeminiConfig(conf *gemini.Config, para
|
||||
if params.EnableThinking != nil {
|
||||
conf.ThinkingConfig = &genai.ThinkingConfig{
|
||||
IncludeThoughts: *params.EnableThinking,
|
||||
ThinkingBudget: nil,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -96,6 +95,17 @@ func (g *geminiModelBuilder) Build(ctx context.Context, params *LLMParams) (Tool
|
||||
conf.Client = client
|
||||
conf.Model = base.Model
|
||||
|
||||
switch base.ThinkingType {
|
||||
case config.ThinkingType_Enable:
|
||||
conf.ThinkingConfig = &genai.ThinkingConfig{
|
||||
IncludeThoughts: true,
|
||||
}
|
||||
case config.ThinkingType_Disable:
|
||||
conf.ThinkingConfig = &genai.ThinkingConfig{
|
||||
IncludeThoughts: false,
|
||||
}
|
||||
}
|
||||
|
||||
g.applyParamsToGeminiConfig(conf, params)
|
||||
|
||||
return gemini.NewChatModel(ctx, conf)
|
||||
|
||||
@ -39,6 +39,16 @@ type Service interface {
|
||||
Build(ctx context.Context, params *LLMParams) (ToolCallingChatModel, error)
|
||||
}
|
||||
|
||||
var modelClass2NewModelBuilder = map[developer_api.ModelClass]func(*config.Model) Service{
|
||||
developer_api.ModelClass_SEED: newArkModelBuilder,
|
||||
developer_api.ModelClass_GPT: newOpenaiModelBuilder,
|
||||
developer_api.ModelClass_Claude: newClaudeModelBuilder,
|
||||
developer_api.ModelClass_DeekSeek: newDeepseekModelBuilder,
|
||||
developer_api.ModelClass_Gemini: newGeminiModelBuilder,
|
||||
developer_api.ModelClass_Llama: newOllamaModelBuilder,
|
||||
developer_api.ModelClass_QWen: newQwenModelBuilder,
|
||||
}
|
||||
|
||||
func NewModelBuilder(modelClass developer_api.ModelClass, cfg *config.Model) (Service, error) {
|
||||
if cfg == nil {
|
||||
return nil, fmt.Errorf("model config is nil")
|
||||
@ -52,37 +62,18 @@ func NewModelBuilder(modelClass developer_api.ModelClass, cfg *config.Model) (Se
|
||||
return nil, fmt.Errorf("model base connection is nil")
|
||||
}
|
||||
|
||||
switch modelClass {
|
||||
case developer_api.ModelClass_SEED:
|
||||
return newArkModelBuilder(cfg), nil
|
||||
case developer_api.ModelClass_GPT:
|
||||
return newOpenaiModelBuilder(cfg), nil
|
||||
case developer_api.ModelClass_Claude:
|
||||
return newClaudeModelBuilder(cfg), nil
|
||||
case developer_api.ModelClass_DeekSeek:
|
||||
return newDeepseekModelBuilder(cfg), nil
|
||||
case developer_api.ModelClass_Gemini:
|
||||
return newGeminiModelBuilder(cfg), nil
|
||||
case developer_api.ModelClass_Llama:
|
||||
return newOllamaModelBuilder(cfg), nil
|
||||
case developer_api.ModelClass_QWen:
|
||||
return newQwenModelBuilder(cfg), nil
|
||||
default:
|
||||
buildFn, ok := modelClass2NewModelBuilder[modelClass]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("model class %v not supported", modelClass)
|
||||
}
|
||||
|
||||
return buildFn(cfg), nil
|
||||
}
|
||||
|
||||
func SupportProtocol(modelClass developer_api.ModelClass) bool {
|
||||
if modelClass == developer_api.ModelClass_GPT ||
|
||||
modelClass == developer_api.ModelClass_Claude ||
|
||||
modelClass == developer_api.ModelClass_DeekSeek ||
|
||||
modelClass == developer_api.ModelClass_SEED ||
|
||||
modelClass == developer_api.ModelClass_Gemini ||
|
||||
modelClass == developer_api.ModelClass_Llama ||
|
||||
modelClass == developer_api.ModelClass_QWen {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
_, ok := modelClass2NewModelBuilder[modelClass]
|
||||
|
||||
return ok
|
||||
}
|
||||
|
||||
// BuildModelWithConf for create model scene, params is nil
|
||||
|
||||
@ -30,7 +30,7 @@ type ollamaModelBuilder struct {
|
||||
cfg *config.Model
|
||||
}
|
||||
|
||||
func newOllamaModelBuilder(cfg *config.Model) *ollamaModelBuilder {
|
||||
func newOllamaModelBuilder(cfg *config.Model) Service {
|
||||
return &ollamaModelBuilder{
|
||||
cfg: cfg,
|
||||
}
|
||||
@ -84,6 +84,17 @@ func (o *ollamaModelBuilder) Build(ctx context.Context, params *LLMParams) (Tool
|
||||
}
|
||||
conf.Model = base.Model
|
||||
|
||||
switch base.ThinkingType {
|
||||
case config.ThinkingType_Enable:
|
||||
conf.Thinking = &api.ThinkValue{
|
||||
Value: ptr.Of(true),
|
||||
}
|
||||
case config.ThinkingType_Disable:
|
||||
conf.Thinking = &api.ThinkValue{
|
||||
Value: ptr.Of(false),
|
||||
}
|
||||
}
|
||||
|
||||
o.applyParamsToOllamaConfig(conf, params)
|
||||
|
||||
return ollama.NewChatModel(ctx, conf)
|
||||
|
||||
@ -30,7 +30,7 @@ type openaiModelBuilder struct {
|
||||
cfg *config.Model
|
||||
}
|
||||
|
||||
func newOpenaiModelBuilder(cfg *config.Model) *openaiModelBuilder {
|
||||
func newOpenaiModelBuilder(cfg *config.Model) Service {
|
||||
return &openaiModelBuilder{
|
||||
cfg: cfg,
|
||||
}
|
||||
|
||||
@ -30,7 +30,7 @@ type qwenModelBuilder struct {
|
||||
cfg *config.Model
|
||||
}
|
||||
|
||||
func newQwenModelBuilder(cfg *config.Model) *qwenModelBuilder {
|
||||
func newQwenModelBuilder(cfg *config.Model) Service {
|
||||
return &qwenModelBuilder{
|
||||
cfg: cfg,
|
||||
}
|
||||
@ -82,6 +82,13 @@ func (q *qwenModelBuilder) Build(ctx context.Context, params *LLMParams) (ToolCa
|
||||
conf.BaseURL = base.BaseURL
|
||||
conf.Model = base.Model
|
||||
|
||||
switch base.ThinkingType {
|
||||
case config.ThinkingType_Enable:
|
||||
conf.EnableThinking = ptr.Of(true)
|
||||
case config.ThinkingType_Disable:
|
||||
conf.EnableThinking = ptr.Of(false)
|
||||
}
|
||||
|
||||
q.applyParamsToQwenConfig(conf, params)
|
||||
|
||||
return qwen.NewChatModel(ctx, conf)
|
||||
|
||||
@ -653,6 +653,11 @@
|
||||
'model.field.azure': 'By Azure',
|
||||
'model.field.api_version': 'API Version',
|
||||
'model.field.endpoint': '接口地址',
|
||||
'model.field.thinking_type': 'Thinking Type',
|
||||
'model.thinking_type.default': 'Default',
|
||||
'model.thinking_type.enable': 'Enable',
|
||||
'model.thinking_type.disable': 'Disable',
|
||||
'model.thinking_type.auto': 'Auto',
|
||||
|
||||
'model.error.load_list_failed': '加载模型列表失败',
|
||||
'model.error.render_page_failed': '渲染模型页面失败',
|
||||
@ -694,6 +699,10 @@
|
||||
'model.modal.gemini_project.placeholder': '选填,例如:my-project',
|
||||
'model.modal.gemini_location.label': 'Location',
|
||||
'model.modal.gemini_location.placeholder': '选填,例如:us-central1',
|
||||
'model.modal.thinking_type.label': 'Thinking Type',
|
||||
'model.modal.thinking_type.enable': 'Enable',
|
||||
'model.modal.thinking_type.disable': 'Disable',
|
||||
'model.modal.thinking_type.auto': 'Auto',
|
||||
|
||||
// 知识库配置
|
||||
'knowledge.error.load_failed_json': '加载知识库配置失败: 返回结果不是有效 JSON',
|
||||
@ -868,6 +877,11 @@
|
||||
'model.field.azure': 'By Azure',
|
||||
'model.field.api_version': 'API Version',
|
||||
'model.field.endpoint': 'Endpoint',
|
||||
'model.field.thinking_type': 'Thinking Type',
|
||||
'model.thinking_type.default': 'Default',
|
||||
'model.thinking_type.enable': 'Enable',
|
||||
'model.thinking_type.disable': 'Disable',
|
||||
'model.thinking_type.auto': 'Auto',
|
||||
|
||||
'model.error.load_list_failed': 'Failed to load model list',
|
||||
'model.error.render_page_failed': 'Failed to render model page',
|
||||
@ -909,6 +923,10 @@
|
||||
'model.modal.gemini_project.placeholder': 'Optional, e.g., my-project',
|
||||
'model.modal.gemini_location.label': 'Location',
|
||||
'model.modal.gemini_location.placeholder': 'Optional, e.g., us-central1',
|
||||
'model.modal.thinking_type.label': 'Thinking Type',
|
||||
'model.modal.thinking_type.enable': 'Enable',
|
||||
'model.modal.thinking_type.disable': 'Disable',
|
||||
'model.modal.thinking_type.auto': 'Auto',
|
||||
|
||||
// Knowledge Config
|
||||
'knowledge.error.load_failed_json': 'Load knowledge config failed: invalid JSON response',
|
||||
@ -2014,6 +2032,17 @@
|
||||
return s.slice(0, 6) + '***' + s.slice(-4);
|
||||
}
|
||||
|
||||
function getThinkingTypeText(thinkingTypeValue) {
|
||||
const thinkingType = Number(thinkingTypeValue);
|
||||
switch (thinkingType) {
|
||||
case 0: return t('model.thinking_type.default');
|
||||
case 1: return t('model.thinking_type.enable');
|
||||
case 2: return t('model.thinking_type.disable');
|
||||
case 3: return t('model.thinking_type.auto');
|
||||
default: return '-';
|
||||
}
|
||||
}
|
||||
|
||||
function renderModelManagement(payload) {
|
||||
try {
|
||||
const providers = Array.isArray(payload?.provider_model_list) ? payload.provider_model_list : [];
|
||||
@ -2070,6 +2099,12 @@
|
||||
<input id="newModelGeminiProject" type="text" style="padding:8px;border:1px solid #e1e8ed;border-radius:8px;width:100%;display:none;" placeholder="${t('model.modal.gemini_project.placeholder')}">
|
||||
<label id="newModelGeminiLocationLabel" style="font-size:12px;color:#374151;display:none;">${t('model.modal.gemini_location.label')}</label>
|
||||
<input id="newModelGeminiLocation" type="text" style="padding:8px;border:1px solid #e1e8ed;border-radius:8px;width:100%;display:none;" placeholder="${t('model.modal.gemini_location.placeholder')}">
|
||||
<label id="newModelThinkingTypeLabel" style="font-size:12px;color:#374151;display:none;">${t('model.modal.thinking_type.label')}</label>
|
||||
<select id="newModelThinkingType" style="padding:8px;border:1px solid #e1e8ed;border-radius:8px;width:100%;display:none;">
|
||||
<option value="2" selected>${t('model.modal.thinking_type.disable')}</option>
|
||||
<option value="1">${t('model.modal.thinking_type.enable')}</option>
|
||||
<option id="thinkingTypeAutoOption" value="3" style="display:none;">${t('model.modal.thinking_type.auto')}</option>
|
||||
</select>
|
||||
</div>
|
||||
<div style="padding:12px 20px;display:flex;justify-content:flex-end;gap:8px;border-top:1px solid #f1f3f4;">
|
||||
<button onclick="closeAddModelModal()" style="background:#ecf0f1;color:#2c3e50;border:none;padding:8px 12px;border-radius:6px;cursor:pointer;">${t('common.cancel')}</button>
|
||||
@ -2124,6 +2159,7 @@
|
||||
<div>${t('model.field.model')}:${conn.model || '-'}</div>
|
||||
${p?.model_class === 20 ? '' : `<div>${t('model.field.api_key')}:${apiKeyMasked}</div>`}
|
||||
<div>${t('model.field.base64_url')}:${m.enable_base64_url ? t('common.on') : t('common.off')}</div>
|
||||
${[2, 3, 11, 15, 20].includes(p?.model_class) ? `<div>${t('model.field.thinking_type')}:${getThinkingTypeText(conn.thinking_type ?? 0)}</div>` : ''}
|
||||
${p?.model_class === 2 ? `<div>${t('model.field.region')}:${m?.connection?.ark?.region || ''}</div>` : ''}
|
||||
${p?.model_class === 11 ? `<div>${t('model.field.backend')}:${m?.connection?.gemini?.backend ?? ''}</div><div>${t('model.field.project')}:${m?.connection?.gemini?.project || ''}</div><div>${t('model.field.location')}:${m?.connection?.gemini?.location || ''}</div>` : ''}
|
||||
${p?.model_class === 1 ? `<div>${t('model.field.azure')}:${(m?.connection?.openai?.by_azure === undefined) ? '' : (m?.connection?.openai?.by_azure ? 'true' : 'false')}</div><div>${t('model.field.api_version')}:${m?.connection?.openai?.api_version || ''}</div>` : ''}
|
||||
@ -2241,6 +2277,20 @@
|
||||
if (geminiProjectInput) geminiProjectInput.style.display = isGemini ? '' : 'none';
|
||||
if (geminiLocationLabel) geminiLocationLabel.style.display = isGemini ? '' : 'none';
|
||||
if (geminiLocationInput) geminiLocationInput.style.display = isGemini ? '' : 'none';
|
||||
|
||||
// Show/hide ThinkingType dropdown
|
||||
const thinkingTypeLabel = document.getElementById('newModelThinkingTypeLabel');
|
||||
const thinkingTypeSelect = document.getElementById('newModelThinkingType');
|
||||
const thinkingTypeAutoOption = document.getElementById('thinkingTypeAutoOption');
|
||||
const hasThinkingType = [2, 3, 11, 15, 20].includes(providerClass); // Ark, Claude, Gemini, Qwen, Ollama
|
||||
const isArkProvider = providerClass === 2;
|
||||
if (thinkingTypeLabel) thinkingTypeLabel.style.display = hasThinkingType ? '' : 'none';
|
||||
if (thinkingTypeSelect) {
|
||||
thinkingTypeSelect.style.display = hasThinkingType ? '' : 'none';
|
||||
thinkingTypeSelect.value = '2'; // Reset to Disable
|
||||
}
|
||||
if (thinkingTypeAutoOption) thinkingTypeAutoOption.style.display = isArkProvider ? '' : 'none';
|
||||
|
||||
modal.style.display = 'flex';
|
||||
}
|
||||
function closeAddModelModal() {
|
||||
@ -2286,6 +2336,16 @@
|
||||
const baseConn = { model: model };
|
||||
if (baseUrl) baseConn.base_url = baseUrl;
|
||||
if (requireApiKey && apiKey) baseConn.api_key = apiKey;
|
||||
|
||||
// 读取 ThinkingType(仅 Ark, Claude, Gemini, Qwen, Ollama)
|
||||
const thinkingTypeSelect = document.getElementById('newModelThinkingType');
|
||||
const hasThinkingType = [2, 3, 11, 15, 20].includes(providerClass);
|
||||
if (hasThinkingType && thinkingTypeSelect) {
|
||||
const thinkingTypeValue = parseInt(thinkingTypeSelect.value, 10);
|
||||
if (!Number.isNaN(thinkingTypeValue)) {
|
||||
baseConn.thinking_type = thinkingTypeValue;
|
||||
}
|
||||
}
|
||||
// 读取“启用 Base64 URL”复选框,默认 false
|
||||
const enableBase64UrlEl = document.getElementById('newModelEnableBase64Url');
|
||||
const enableBase64Url = !!(enableBase64UrlEl && enableBase64UrlEl.checked);
|
||||
@ -2463,7 +2523,6 @@
|
||||
openai_api_key: baseConn?.api_key || '',
|
||||
openai_model: baseConn?.model || '',
|
||||
openai_embedding_dims: embeddingInfo?.dims ?? '0',
|
||||
openai_embedding_request_dims: conn?.openai?.embedding_request_dims ?? conn?.openai?.request_dims ?? '',
|
||||
openai_embedding_by_azure: Boolean(conn?.openai?.embedding_by_azure ?? conn?.openai?.by_azure),
|
||||
openai_embedding_api_version: conn?.openai?.embedding_api_version ?? conn?.openai?.api_version ?? '',
|
||||
ollama_base_url: baseConn?.base_url || '',
|
||||
@ -2623,7 +2682,7 @@
|
||||
</div>
|
||||
<div>
|
||||
<div style="${labelStyle}">Dims</div>
|
||||
<input id="kb_ark_embedding_dims" type="number" style="${inputStyle}" value="${initial.ark_embedding_dims}" />
|
||||
<input id="kb_ark_embedding_dims" type="number" min="0" style="${inputStyle}" value="${initial.ark_embedding_dims}" />
|
||||
</div>
|
||||
<div>
|
||||
<div style="${labelStyle}">API Type</div>
|
||||
@ -2653,7 +2712,7 @@
|
||||
</div>
|
||||
<div>
|
||||
<div style="${labelStyle}">Dims</div>
|
||||
<input id="kb_openai_embedding_dims" type="number" style="${inputStyle}" value="${initial.openai_embedding_dims}" />
|
||||
<input id="kb_openai_embedding_dims" type="number" min="0" style="${inputStyle}" value="${initial.openai_embedding_dims}" />
|
||||
</div>
|
||||
<!-- 选填字段靠后显示:By Azure、API Version、Request Dims -->
|
||||
<div>
|
||||
@ -2664,10 +2723,6 @@
|
||||
<div style="${labelStyle}">Embedding API Version</div>
|
||||
<input id="kb_openai_embedding_api_version" type="text" style="${inputStyle}" value="${initial.openai_embedding_api_version}" />
|
||||
</div>
|
||||
<div>
|
||||
<div style="${labelStyle}">Embedding Request Dims</div>
|
||||
<input id="kb_openai_embedding_request_dims" type="number" style="${inputStyle}" value="${initial.openai_embedding_request_dims}" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -2684,7 +2739,7 @@
|
||||
</div>
|
||||
<div>
|
||||
<div style="${labelStyle}">Dims</div>
|
||||
<input id="kb_ollama_embedding_dims" type="number" style="${inputStyle}" value="${initial.ollama_embedding_dims}" />
|
||||
<input id="kb_ollama_embedding_dims" type="number" min="0" style="${inputStyle}" value="${initial.ollama_embedding_dims}" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -2711,7 +2766,7 @@
|
||||
</div>
|
||||
<div>
|
||||
<div style="${labelStyle}">Dims</div>
|
||||
<input id="kb_gemini_embedding_dims" type="number" style="${inputStyle}" value="${initial.gemini_embedding_dims}" />
|
||||
<input id="kb_gemini_embedding_dims" type="number" min="0" style="${inputStyle}" value="${initial.gemini_embedding_dims}" />
|
||||
</div>
|
||||
<div>
|
||||
<div style="${labelStyle}">Project</div>
|
||||
@ -2733,7 +2788,7 @@
|
||||
</div>
|
||||
<div>
|
||||
<div style="${labelStyle}">Dims</div>
|
||||
<input id="kb_http_dims" type="number" style="${inputStyle}" value="${initial.http_dims}" />
|
||||
<input id="kb_http_dims" type="number" min="0" style="${inputStyle}" value="${initial.http_dims}" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -3065,7 +3120,6 @@
|
||||
api_type: val('kb_ark_embedding_api_type')
|
||||
},
|
||||
openai: {
|
||||
request_dims: toNum(val('kb_openai_embedding_request_dims')),
|
||||
by_azure: checked('kb_openai_embedding_by_azure'),
|
||||
api_version: val('kb_openai_embedding_api_version')
|
||||
},
|
||||
@ -3113,13 +3167,22 @@
|
||||
// Embedding 必填项校验(不同类型不同必填要求)
|
||||
const typeVal = Number(document.getElementById('kb_embedding_type')?.value);
|
||||
const get = (id) => (document.getElementById(id)?.value || '').trim();
|
||||
const getDims = (id) => {
|
||||
const el = document.getElementById(id);
|
||||
return el ? Number(el.value) : 0;
|
||||
};
|
||||
|
||||
if (typeVal === 0) {
|
||||
// Ark: Base URL、API Key、Model、Dims 必填,API Type 可选
|
||||
const dimsVal = Number(document.getElementById('kb_ark_embedding_dims')?.value);
|
||||
const dimsVal = getDims('kb_ark_embedding_dims');
|
||||
const missing = [];
|
||||
if (!get('kb_ark_base_url')) missing.push('Base URL');
|
||||
if (!get('kb_ark_api_key')) missing.push('API Key');
|
||||
if (!get('kb_ark_model')) missing.push('Model');
|
||||
if (dimsVal < 0) {
|
||||
showError('Dims must be >= 0');
|
||||
return;
|
||||
}
|
||||
|
||||
if (missing.length > 0) {
|
||||
showError(t('error.missing_required', { list: missing.join(', ') }));
|
||||
@ -3127,43 +3190,59 @@
|
||||
}
|
||||
} else if (typeVal === 1) {
|
||||
// OpenAI: Base URL、Model、API Key、Dims 必填
|
||||
const dimsVal = Number(document.getElementById('kb_openai_embedding_dims')?.value);
|
||||
const dimsVal = getDims('kb_openai_embedding_dims');
|
||||
const missing = [];
|
||||
if (!get('kb_openai_base_url')) missing.push('Base URL');
|
||||
if (!get('kb_openai_model')) missing.push('Model');
|
||||
if (!get('kb_openai_api_key')) missing.push('API Key');
|
||||
if (dimsVal < 0) {
|
||||
showError('Dims must be >= 0');
|
||||
return;
|
||||
}
|
||||
if (missing.length > 0) {
|
||||
showError(t('error.missing_required', { list: missing.join(', ') }));
|
||||
return;
|
||||
}
|
||||
} else if (typeVal === 2) {
|
||||
// Ollama: Base URL、Model、Dims 必填
|
||||
const dimsVal = Number(document.getElementById('kb_ollama_embedding_dims')?.value);
|
||||
const dimsVal = getDims('kb_ollama_embedding_dims');
|
||||
const missing = [];
|
||||
if (!get('kb_ollama_base_url')) missing.push('Base URL');
|
||||
if (!get('kb_ollama_model')) missing.push('Model');
|
||||
if (dimsVal < 0) {
|
||||
showError('Dims must be >= 0');
|
||||
return;
|
||||
}
|
||||
if (missing.length > 0) {
|
||||
showError(t('error.missing_required', { list: missing.join(', ') }));
|
||||
return;
|
||||
}
|
||||
} else if (typeVal === 3) {
|
||||
// Gemini: Base URL、API Key、Model、Dims、Backend 必填;Project、Location 选填
|
||||
const dimsVal = Number(document.getElementById('kb_gemini_embedding_dims')?.value);
|
||||
const dimsVal = getDims('kb_gemini_embedding_dims');
|
||||
const backendStr = (document.getElementById('kb_gemini_embedding_backend')?.value || '').trim();
|
||||
const missing = [];
|
||||
if (!get('kb_gemini_base_url')) missing.push('Base URL');
|
||||
if (!get('kb_gemini_api_key')) missing.push('API Key');
|
||||
if (!get('kb_gemini_model')) missing.push('Model');
|
||||
if (!backendStr) missing.push('Backend');
|
||||
if (dimsVal < 0) {
|
||||
showError('Dims must be >= 0');
|
||||
return;
|
||||
}
|
||||
if (missing.length > 0) {
|
||||
showError(t('error.missing_required', { list: missing.join(', ') }));
|
||||
return;
|
||||
}
|
||||
} else if (typeVal === 4) {
|
||||
// HTTP: Address、Dims 必填
|
||||
const dimsVal = Number(document.getElementById('kb_http_dims')?.value);
|
||||
const dimsVal = getDims('kb_http_dims');
|
||||
const missing = [];
|
||||
if (!get('kb_http_address')) missing.push('Address');
|
||||
if (dimsVal < 0) {
|
||||
showError('Dims must be >= 0');
|
||||
return;
|
||||
}
|
||||
if (missing.length > 0) {
|
||||
showError(t('error.missing_required', { list: missing.join(', ') }));
|
||||
return;
|
||||
|
||||
@ -92,7 +92,7 @@ func (d *embWrap) EmbedStringsHybrid(ctx context.Context, texts []string, opts .
|
||||
}
|
||||
|
||||
func (d *embWrap) Dimensions() int64 {
|
||||
if d.dims == 0 {
|
||||
if d.dims <= 0 {
|
||||
embeddings, err := d.Embedder.EmbedStrings(context.Background(), []string{"test"})
|
||||
if err != nil {
|
||||
return 0
|
||||
|
||||
@ -195,7 +195,7 @@ func (e *embedder) do(req *http.Request) (*embedResp, error) {
|
||||
}
|
||||
|
||||
func (e *embedder) Dimensions() int64 {
|
||||
if e.dim == 0 {
|
||||
if e.dim <= 0 {
|
||||
embeddings, err := e.EmbedStrings(context.Background(), []string{"test"})
|
||||
if err != nil {
|
||||
return 0
|
||||
|
||||
@ -52,9 +52,9 @@ func GetEmbedding(ctx context.Context, cfg *config.EmbeddingConfig) (embedding.E
|
||||
APIVersion: openaiConnCfg.APIVersion,
|
||||
}
|
||||
|
||||
if openaiConnCfg.RequestDims > 0 {
|
||||
if embeddingInfo.Dims > 0 {
|
||||
// some openai model not support request dims
|
||||
openAICfg.Dimensions = ptr.Of(int(openaiConnCfg.RequestDims))
|
||||
openAICfg.Dimensions = ptr.Of(int(embeddingInfo.Dims))
|
||||
}
|
||||
|
||||
emb, err = wrap.NewOpenAIEmbedder(ctx, openAICfg, int64(embeddingInfo.Dims), int(cfg.MaxBatchSize))
|
||||
|
||||
@ -49,7 +49,7 @@ func (d *denseOnlyWrap) EmbedStringsHybrid(ctx context.Context, texts []string,
|
||||
}
|
||||
|
||||
func (d *denseOnlyWrap) Dimensions() int64 {
|
||||
if d.dims == 0 {
|
||||
if d.dims <= 0 {
|
||||
embeddings, err := d.Embedder.EmbedStrings(context.Background(), []string{"test"})
|
||||
if err != nil {
|
||||
return 0
|
||||
|
||||
Reference in New Issue
Block a user