diff --git a/backend/consts/model.go b/backend/consts/model.go index a2bb46f..ce02282 100644 --- a/backend/consts/model.go +++ b/backend/consts/model.go @@ -16,3 +16,18 @@ const ( ModelTypeAudio ModelType = "audio" ModelTypeReranker ModelType = "reranker" ) + +type ModelProvider string + +const ( + ModelProviderSiliconFlow ModelProvider = "SiliconFlow" + ModelProviderOpenAI ModelProvider = "OpenAI" + ModelProviderOllama ModelProvider = "Ollama" + ModelProviderDeepSeek ModelProvider = "DeepSeek" + ModelProviderMoonshot ModelProvider = "Moonshot" + ModelProviderAzureOpenAI ModelProvider = "AzureOpenAI" + ModelProviderBaiZhiCloud ModelProvider = "BaiZhiCloud" + ModelProviderHunyuan ModelProvider = "Hunyuan" + ModelProviderBaiLian ModelProvider = "BaiLian" + ModelProviderVolcengine ModelProvider = "Volcengine" +) diff --git a/backend/db/migrate/schema.go b/backend/db/migrate/schema.go index 27350a4..eb2d595 100644 --- a/backend/db/migrate/schema.go +++ b/backend/db/migrate/schema.go @@ -175,9 +175,11 @@ var ( {Name: "id", Type: field.TypeUUID}, {Name: "model_name", Type: field.TypeString}, {Name: "model_type", Type: field.TypeString}, + {Name: "show_name", Type: field.TypeString, Nullable: true}, {Name: "api_base", Type: field.TypeString}, {Name: "api_key", Type: field.TypeString}, {Name: "api_version", Type: field.TypeString, Nullable: true}, + {Name: "api_header", Type: field.TypeString, Nullable: true}, {Name: "description", Type: field.TypeString, Nullable: true}, {Name: "provider", Type: field.TypeString}, {Name: "status", Type: field.TypeString, Default: "active"}, @@ -194,7 +196,7 @@ var ( ForeignKeys: []*schema.ForeignKey{ { Symbol: "models_users_models", - Columns: []*schema.Column{ModelsColumns[12]}, + Columns: []*schema.Column{ModelsColumns[14]}, RefColumns: []*schema.Column{UsersColumns[0]}, OnDelete: schema.SetNull, }, diff --git a/backend/db/model.go b/backend/db/model.go index a63a297..e196ed4 100644 --- a/backend/db/model.go +++ b/backend/db/model.go @@ -26,16 +26,20 @@ type Model struct { ModelName string `json:"model_name,omitempty"` // ModelType holds the value of the "model_type" field. ModelType consts.ModelType `json:"model_type,omitempty"` + // ShowName holds the value of the "show_name" field. + ShowName string `json:"show_name,omitempty"` // APIBase holds the value of the "api_base" field. APIBase string `json:"api_base,omitempty"` // APIKey holds the value of the "api_key" field. APIKey string `json:"api_key,omitempty"` // APIVersion holds the value of the "api_version" field. APIVersion string `json:"api_version,omitempty"` + // APIHeader holds the value of the "api_header" field. + APIHeader string `json:"api_header,omitempty"` // Description holds the value of the "description" field. Description string `json:"description,omitempty"` // Provider holds the value of the "provider" field. - Provider string `json:"provider,omitempty"` + Provider consts.ModelProvider `json:"provider,omitempty"` // Status holds the value of the "status" field. Status consts.ModelStatus `json:"status,omitempty"` // ContextLength holds the value of the "context_length" field. @@ -88,7 +92,7 @@ func (*Model) scanValues(columns []string) ([]any, error) { switch columns[i] { case model.FieldContextLength: values[i] = new(sql.NullInt64) - case model.FieldModelName, model.FieldModelType, model.FieldAPIBase, model.FieldAPIKey, model.FieldAPIVersion, model.FieldDescription, model.FieldProvider, model.FieldStatus: + case model.FieldModelName, model.FieldModelType, model.FieldShowName, model.FieldAPIBase, model.FieldAPIKey, model.FieldAPIVersion, model.FieldAPIHeader, model.FieldDescription, model.FieldProvider, model.FieldStatus: values[i] = new(sql.NullString) case model.FieldCreatedAt, model.FieldUpdatedAt: values[i] = new(sql.NullTime) @@ -133,6 +137,12 @@ func (m *Model) assignValues(columns []string, values []any) error { } else if value.Valid { m.ModelType = consts.ModelType(value.String) } + case model.FieldShowName: + if value, ok := values[i].(*sql.NullString); !ok { + return fmt.Errorf("unexpected type %T for field show_name", values[i]) + } else if value.Valid { + m.ShowName = value.String + } case model.FieldAPIBase: if value, ok := values[i].(*sql.NullString); !ok { return fmt.Errorf("unexpected type %T for field api_base", values[i]) @@ -151,6 +161,12 @@ func (m *Model) assignValues(columns []string, values []any) error { } else if value.Valid { m.APIVersion = value.String } + case model.FieldAPIHeader: + if value, ok := values[i].(*sql.NullString); !ok { + return fmt.Errorf("unexpected type %T for field api_header", values[i]) + } else if value.Valid { + m.APIHeader = value.String + } case model.FieldDescription: if value, ok := values[i].(*sql.NullString); !ok { return fmt.Errorf("unexpected type %T for field description", values[i]) @@ -161,7 +177,7 @@ func (m *Model) assignValues(columns []string, values []any) error { if value, ok := values[i].(*sql.NullString); !ok { return fmt.Errorf("unexpected type %T for field provider", values[i]) } else if value.Valid { - m.Provider = value.String + m.Provider = consts.ModelProvider(value.String) } case model.FieldStatus: if value, ok := values[i].(*sql.NullString); !ok { @@ -242,6 +258,9 @@ func (m *Model) String() string { builder.WriteString("model_type=") builder.WriteString(fmt.Sprintf("%v", m.ModelType)) builder.WriteString(", ") + builder.WriteString("show_name=") + builder.WriteString(m.ShowName) + builder.WriteString(", ") builder.WriteString("api_base=") builder.WriteString(m.APIBase) builder.WriteString(", ") @@ -251,11 +270,14 @@ func (m *Model) String() string { builder.WriteString("api_version=") builder.WriteString(m.APIVersion) builder.WriteString(", ") + builder.WriteString("api_header=") + builder.WriteString(m.APIHeader) + builder.WriteString(", ") builder.WriteString("description=") builder.WriteString(m.Description) builder.WriteString(", ") builder.WriteString("provider=") - builder.WriteString(m.Provider) + builder.WriteString(fmt.Sprintf("%v", m.Provider)) builder.WriteString(", ") builder.WriteString("status=") builder.WriteString(fmt.Sprintf("%v", m.Status)) diff --git a/backend/db/model/model.go b/backend/db/model/model.go index c1b6957..d8e6d86 100644 --- a/backend/db/model/model.go +++ b/backend/db/model/model.go @@ -21,12 +21,16 @@ const ( FieldModelName = "model_name" // FieldModelType holds the string denoting the model_type field in the database. FieldModelType = "model_type" + // FieldShowName holds the string denoting the show_name field in the database. + FieldShowName = "show_name" // FieldAPIBase holds the string denoting the api_base field in the database. FieldAPIBase = "api_base" // FieldAPIKey holds the string denoting the api_key field in the database. FieldAPIKey = "api_key" // FieldAPIVersion holds the string denoting the api_version field in the database. FieldAPIVersion = "api_version" + // FieldAPIHeader holds the string denoting the api_header field in the database. + FieldAPIHeader = "api_header" // FieldDescription holds the string denoting the description field in the database. FieldDescription = "description" // FieldProvider holds the string denoting the provider field in the database. @@ -67,9 +71,11 @@ var Columns = []string{ FieldUserID, FieldModelName, FieldModelType, + FieldShowName, FieldAPIBase, FieldAPIKey, FieldAPIVersion, + FieldAPIHeader, FieldDescription, FieldProvider, FieldStatus, @@ -122,6 +128,11 @@ func ByModelType(opts ...sql.OrderTermOption) OrderOption { return sql.OrderByField(FieldModelType, opts...).ToFunc() } +// ByShowName orders the results by the show_name field. +func ByShowName(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldShowName, opts...).ToFunc() +} + // ByAPIBase orders the results by the api_base field. func ByAPIBase(opts ...sql.OrderTermOption) OrderOption { return sql.OrderByField(FieldAPIBase, opts...).ToFunc() @@ -137,6 +148,11 @@ func ByAPIVersion(opts ...sql.OrderTermOption) OrderOption { return sql.OrderByField(FieldAPIVersion, opts...).ToFunc() } +// ByAPIHeader orders the results by the api_header field. +func ByAPIHeader(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldAPIHeader, opts...).ToFunc() +} + // ByDescription orders the results by the description field. func ByDescription(opts ...sql.OrderTermOption) OrderOption { return sql.OrderByField(FieldDescription, opts...).ToFunc() diff --git a/backend/db/model/where.go b/backend/db/model/where.go index ca7d76a..13bb876 100644 --- a/backend/db/model/where.go +++ b/backend/db/model/where.go @@ -73,6 +73,11 @@ func ModelType(v consts.ModelType) predicate.Model { return predicate.Model(sql.FieldEQ(FieldModelType, vc)) } +// ShowName applies equality check predicate on the "show_name" field. It's identical to ShowNameEQ. +func ShowName(v string) predicate.Model { + return predicate.Model(sql.FieldEQ(FieldShowName, v)) +} + // APIBase applies equality check predicate on the "api_base" field. It's identical to APIBaseEQ. func APIBase(v string) predicate.Model { return predicate.Model(sql.FieldEQ(FieldAPIBase, v)) @@ -88,14 +93,20 @@ func APIVersion(v string) predicate.Model { return predicate.Model(sql.FieldEQ(FieldAPIVersion, v)) } +// APIHeader applies equality check predicate on the "api_header" field. It's identical to APIHeaderEQ. +func APIHeader(v string) predicate.Model { + return predicate.Model(sql.FieldEQ(FieldAPIHeader, v)) +} + // Description applies equality check predicate on the "description" field. It's identical to DescriptionEQ. func Description(v string) predicate.Model { return predicate.Model(sql.FieldEQ(FieldDescription, v)) } // Provider applies equality check predicate on the "provider" field. It's identical to ProviderEQ. -func Provider(v string) predicate.Model { - return predicate.Model(sql.FieldEQ(FieldProvider, v)) +func Provider(v consts.ModelProvider) predicate.Model { + vc := string(v) + return predicate.Model(sql.FieldEQ(FieldProvider, vc)) } // Status applies equality check predicate on the "status" field. It's identical to StatusEQ. @@ -298,6 +309,81 @@ func ModelTypeContainsFold(v consts.ModelType) predicate.Model { return predicate.Model(sql.FieldContainsFold(FieldModelType, vc)) } +// ShowNameEQ applies the EQ predicate on the "show_name" field. +func ShowNameEQ(v string) predicate.Model { + return predicate.Model(sql.FieldEQ(FieldShowName, v)) +} + +// ShowNameNEQ applies the NEQ predicate on the "show_name" field. +func ShowNameNEQ(v string) predicate.Model { + return predicate.Model(sql.FieldNEQ(FieldShowName, v)) +} + +// ShowNameIn applies the In predicate on the "show_name" field. +func ShowNameIn(vs ...string) predicate.Model { + return predicate.Model(sql.FieldIn(FieldShowName, vs...)) +} + +// ShowNameNotIn applies the NotIn predicate on the "show_name" field. +func ShowNameNotIn(vs ...string) predicate.Model { + return predicate.Model(sql.FieldNotIn(FieldShowName, vs...)) +} + +// ShowNameGT applies the GT predicate on the "show_name" field. +func ShowNameGT(v string) predicate.Model { + return predicate.Model(sql.FieldGT(FieldShowName, v)) +} + +// ShowNameGTE applies the GTE predicate on the "show_name" field. +func ShowNameGTE(v string) predicate.Model { + return predicate.Model(sql.FieldGTE(FieldShowName, v)) +} + +// ShowNameLT applies the LT predicate on the "show_name" field. +func ShowNameLT(v string) predicate.Model { + return predicate.Model(sql.FieldLT(FieldShowName, v)) +} + +// ShowNameLTE applies the LTE predicate on the "show_name" field. +func ShowNameLTE(v string) predicate.Model { + return predicate.Model(sql.FieldLTE(FieldShowName, v)) +} + +// ShowNameContains applies the Contains predicate on the "show_name" field. +func ShowNameContains(v string) predicate.Model { + return predicate.Model(sql.FieldContains(FieldShowName, v)) +} + +// ShowNameHasPrefix applies the HasPrefix predicate on the "show_name" field. +func ShowNameHasPrefix(v string) predicate.Model { + return predicate.Model(sql.FieldHasPrefix(FieldShowName, v)) +} + +// ShowNameHasSuffix applies the HasSuffix predicate on the "show_name" field. +func ShowNameHasSuffix(v string) predicate.Model { + return predicate.Model(sql.FieldHasSuffix(FieldShowName, v)) +} + +// ShowNameIsNil applies the IsNil predicate on the "show_name" field. +func ShowNameIsNil() predicate.Model { + return predicate.Model(sql.FieldIsNull(FieldShowName)) +} + +// ShowNameNotNil applies the NotNil predicate on the "show_name" field. +func ShowNameNotNil() predicate.Model { + return predicate.Model(sql.FieldNotNull(FieldShowName)) +} + +// ShowNameEqualFold applies the EqualFold predicate on the "show_name" field. +func ShowNameEqualFold(v string) predicate.Model { + return predicate.Model(sql.FieldEqualFold(FieldShowName, v)) +} + +// ShowNameContainsFold applies the ContainsFold predicate on the "show_name" field. +func ShowNameContainsFold(v string) predicate.Model { + return predicate.Model(sql.FieldContainsFold(FieldShowName, v)) +} + // APIBaseEQ applies the EQ predicate on the "api_base" field. func APIBaseEQ(v string) predicate.Model { return predicate.Model(sql.FieldEQ(FieldAPIBase, v)) @@ -503,6 +589,81 @@ func APIVersionContainsFold(v string) predicate.Model { return predicate.Model(sql.FieldContainsFold(FieldAPIVersion, v)) } +// APIHeaderEQ applies the EQ predicate on the "api_header" field. +func APIHeaderEQ(v string) predicate.Model { + return predicate.Model(sql.FieldEQ(FieldAPIHeader, v)) +} + +// APIHeaderNEQ applies the NEQ predicate on the "api_header" field. +func APIHeaderNEQ(v string) predicate.Model { + return predicate.Model(sql.FieldNEQ(FieldAPIHeader, v)) +} + +// APIHeaderIn applies the In predicate on the "api_header" field. +func APIHeaderIn(vs ...string) predicate.Model { + return predicate.Model(sql.FieldIn(FieldAPIHeader, vs...)) +} + +// APIHeaderNotIn applies the NotIn predicate on the "api_header" field. +func APIHeaderNotIn(vs ...string) predicate.Model { + return predicate.Model(sql.FieldNotIn(FieldAPIHeader, vs...)) +} + +// APIHeaderGT applies the GT predicate on the "api_header" field. +func APIHeaderGT(v string) predicate.Model { + return predicate.Model(sql.FieldGT(FieldAPIHeader, v)) +} + +// APIHeaderGTE applies the GTE predicate on the "api_header" field. +func APIHeaderGTE(v string) predicate.Model { + return predicate.Model(sql.FieldGTE(FieldAPIHeader, v)) +} + +// APIHeaderLT applies the LT predicate on the "api_header" field. +func APIHeaderLT(v string) predicate.Model { + return predicate.Model(sql.FieldLT(FieldAPIHeader, v)) +} + +// APIHeaderLTE applies the LTE predicate on the "api_header" field. +func APIHeaderLTE(v string) predicate.Model { + return predicate.Model(sql.FieldLTE(FieldAPIHeader, v)) +} + +// APIHeaderContains applies the Contains predicate on the "api_header" field. +func APIHeaderContains(v string) predicate.Model { + return predicate.Model(sql.FieldContains(FieldAPIHeader, v)) +} + +// APIHeaderHasPrefix applies the HasPrefix predicate on the "api_header" field. +func APIHeaderHasPrefix(v string) predicate.Model { + return predicate.Model(sql.FieldHasPrefix(FieldAPIHeader, v)) +} + +// APIHeaderHasSuffix applies the HasSuffix predicate on the "api_header" field. +func APIHeaderHasSuffix(v string) predicate.Model { + return predicate.Model(sql.FieldHasSuffix(FieldAPIHeader, v)) +} + +// APIHeaderIsNil applies the IsNil predicate on the "api_header" field. +func APIHeaderIsNil() predicate.Model { + return predicate.Model(sql.FieldIsNull(FieldAPIHeader)) +} + +// APIHeaderNotNil applies the NotNil predicate on the "api_header" field. +func APIHeaderNotNil() predicate.Model { + return predicate.Model(sql.FieldNotNull(FieldAPIHeader)) +} + +// APIHeaderEqualFold applies the EqualFold predicate on the "api_header" field. +func APIHeaderEqualFold(v string) predicate.Model { + return predicate.Model(sql.FieldEqualFold(FieldAPIHeader, v)) +} + +// APIHeaderContainsFold applies the ContainsFold predicate on the "api_header" field. +func APIHeaderContainsFold(v string) predicate.Model { + return predicate.Model(sql.FieldContainsFold(FieldAPIHeader, v)) +} + // DescriptionEQ applies the EQ predicate on the "description" field. func DescriptionEQ(v string) predicate.Model { return predicate.Model(sql.FieldEQ(FieldDescription, v)) @@ -579,68 +740,87 @@ func DescriptionContainsFold(v string) predicate.Model { } // ProviderEQ applies the EQ predicate on the "provider" field. -func ProviderEQ(v string) predicate.Model { - return predicate.Model(sql.FieldEQ(FieldProvider, v)) +func ProviderEQ(v consts.ModelProvider) predicate.Model { + vc := string(v) + return predicate.Model(sql.FieldEQ(FieldProvider, vc)) } // ProviderNEQ applies the NEQ predicate on the "provider" field. -func ProviderNEQ(v string) predicate.Model { - return predicate.Model(sql.FieldNEQ(FieldProvider, v)) +func ProviderNEQ(v consts.ModelProvider) predicate.Model { + vc := string(v) + return predicate.Model(sql.FieldNEQ(FieldProvider, vc)) } // ProviderIn applies the In predicate on the "provider" field. -func ProviderIn(vs ...string) predicate.Model { - return predicate.Model(sql.FieldIn(FieldProvider, vs...)) +func ProviderIn(vs ...consts.ModelProvider) predicate.Model { + v := make([]any, len(vs)) + for i := range v { + v[i] = string(vs[i]) + } + return predicate.Model(sql.FieldIn(FieldProvider, v...)) } // ProviderNotIn applies the NotIn predicate on the "provider" field. -func ProviderNotIn(vs ...string) predicate.Model { - return predicate.Model(sql.FieldNotIn(FieldProvider, vs...)) +func ProviderNotIn(vs ...consts.ModelProvider) predicate.Model { + v := make([]any, len(vs)) + for i := range v { + v[i] = string(vs[i]) + } + return predicate.Model(sql.FieldNotIn(FieldProvider, v...)) } // ProviderGT applies the GT predicate on the "provider" field. -func ProviderGT(v string) predicate.Model { - return predicate.Model(sql.FieldGT(FieldProvider, v)) +func ProviderGT(v consts.ModelProvider) predicate.Model { + vc := string(v) + return predicate.Model(sql.FieldGT(FieldProvider, vc)) } // ProviderGTE applies the GTE predicate on the "provider" field. -func ProviderGTE(v string) predicate.Model { - return predicate.Model(sql.FieldGTE(FieldProvider, v)) +func ProviderGTE(v consts.ModelProvider) predicate.Model { + vc := string(v) + return predicate.Model(sql.FieldGTE(FieldProvider, vc)) } // ProviderLT applies the LT predicate on the "provider" field. -func ProviderLT(v string) predicate.Model { - return predicate.Model(sql.FieldLT(FieldProvider, v)) +func ProviderLT(v consts.ModelProvider) predicate.Model { + vc := string(v) + return predicate.Model(sql.FieldLT(FieldProvider, vc)) } // ProviderLTE applies the LTE predicate on the "provider" field. -func ProviderLTE(v string) predicate.Model { - return predicate.Model(sql.FieldLTE(FieldProvider, v)) +func ProviderLTE(v consts.ModelProvider) predicate.Model { + vc := string(v) + return predicate.Model(sql.FieldLTE(FieldProvider, vc)) } // ProviderContains applies the Contains predicate on the "provider" field. -func ProviderContains(v string) predicate.Model { - return predicate.Model(sql.FieldContains(FieldProvider, v)) +func ProviderContains(v consts.ModelProvider) predicate.Model { + vc := string(v) + return predicate.Model(sql.FieldContains(FieldProvider, vc)) } // ProviderHasPrefix applies the HasPrefix predicate on the "provider" field. -func ProviderHasPrefix(v string) predicate.Model { - return predicate.Model(sql.FieldHasPrefix(FieldProvider, v)) +func ProviderHasPrefix(v consts.ModelProvider) predicate.Model { + vc := string(v) + return predicate.Model(sql.FieldHasPrefix(FieldProvider, vc)) } // ProviderHasSuffix applies the HasSuffix predicate on the "provider" field. -func ProviderHasSuffix(v string) predicate.Model { - return predicate.Model(sql.FieldHasSuffix(FieldProvider, v)) +func ProviderHasSuffix(v consts.ModelProvider) predicate.Model { + vc := string(v) + return predicate.Model(sql.FieldHasSuffix(FieldProvider, vc)) } // ProviderEqualFold applies the EqualFold predicate on the "provider" field. -func ProviderEqualFold(v string) predicate.Model { - return predicate.Model(sql.FieldEqualFold(FieldProvider, v)) +func ProviderEqualFold(v consts.ModelProvider) predicate.Model { + vc := string(v) + return predicate.Model(sql.FieldEqualFold(FieldProvider, vc)) } // ProviderContainsFold applies the ContainsFold predicate on the "provider" field. -func ProviderContainsFold(v string) predicate.Model { - return predicate.Model(sql.FieldContainsFold(FieldProvider, v)) +func ProviderContainsFold(v consts.ModelProvider) predicate.Model { + vc := string(v) + return predicate.Model(sql.FieldContainsFold(FieldProvider, vc)) } // StatusEQ applies the EQ predicate on the "status" field. diff --git a/backend/db/model_create.go b/backend/db/model_create.go index e36a0a5..c2af0fa 100644 --- a/backend/db/model_create.go +++ b/backend/db/model_create.go @@ -53,6 +53,20 @@ func (mc *ModelCreate) SetModelType(ct consts.ModelType) *ModelCreate { return mc } +// SetShowName sets the "show_name" field. +func (mc *ModelCreate) SetShowName(s string) *ModelCreate { + mc.mutation.SetShowName(s) + return mc +} + +// SetNillableShowName sets the "show_name" field if the given value is not nil. +func (mc *ModelCreate) SetNillableShowName(s *string) *ModelCreate { + if s != nil { + mc.SetShowName(*s) + } + return mc +} + // SetAPIBase sets the "api_base" field. func (mc *ModelCreate) SetAPIBase(s string) *ModelCreate { mc.mutation.SetAPIBase(s) @@ -79,6 +93,20 @@ func (mc *ModelCreate) SetNillableAPIVersion(s *string) *ModelCreate { return mc } +// SetAPIHeader sets the "api_header" field. +func (mc *ModelCreate) SetAPIHeader(s string) *ModelCreate { + mc.mutation.SetAPIHeader(s) + return mc +} + +// SetNillableAPIHeader sets the "api_header" field if the given value is not nil. +func (mc *ModelCreate) SetNillableAPIHeader(s *string) *ModelCreate { + if s != nil { + mc.SetAPIHeader(*s) + } + return mc +} + // SetDescription sets the "description" field. func (mc *ModelCreate) SetDescription(s string) *ModelCreate { mc.mutation.SetDescription(s) @@ -94,8 +122,8 @@ func (mc *ModelCreate) SetNillableDescription(s *string) *ModelCreate { } // SetProvider sets the "provider" field. -func (mc *ModelCreate) SetProvider(s string) *ModelCreate { - mc.mutation.SetProvider(s) +func (mc *ModelCreate) SetProvider(cp consts.ModelProvider) *ModelCreate { + mc.mutation.SetProvider(cp) return mc } @@ -300,6 +328,10 @@ func (mc *ModelCreate) createSpec() (*Model, *sqlgraph.CreateSpec) { _spec.SetField(model.FieldModelType, field.TypeString, value) _node.ModelType = value } + if value, ok := mc.mutation.ShowName(); ok { + _spec.SetField(model.FieldShowName, field.TypeString, value) + _node.ShowName = value + } if value, ok := mc.mutation.APIBase(); ok { _spec.SetField(model.FieldAPIBase, field.TypeString, value) _node.APIBase = value @@ -312,6 +344,10 @@ func (mc *ModelCreate) createSpec() (*Model, *sqlgraph.CreateSpec) { _spec.SetField(model.FieldAPIVersion, field.TypeString, value) _node.APIVersion = value } + if value, ok := mc.mutation.APIHeader(); ok { + _spec.SetField(model.FieldAPIHeader, field.TypeString, value) + _node.APIHeader = value + } if value, ok := mc.mutation.Description(); ok { _spec.SetField(model.FieldDescription, field.TypeString, value) _node.Description = value @@ -463,6 +499,24 @@ func (u *ModelUpsert) UpdateModelType() *ModelUpsert { return u } +// SetShowName sets the "show_name" field. +func (u *ModelUpsert) SetShowName(v string) *ModelUpsert { + u.Set(model.FieldShowName, v) + return u +} + +// UpdateShowName sets the "show_name" field to the value that was provided on create. +func (u *ModelUpsert) UpdateShowName() *ModelUpsert { + u.SetExcluded(model.FieldShowName) + return u +} + +// ClearShowName clears the value of the "show_name" field. +func (u *ModelUpsert) ClearShowName() *ModelUpsert { + u.SetNull(model.FieldShowName) + return u +} + // SetAPIBase sets the "api_base" field. func (u *ModelUpsert) SetAPIBase(v string) *ModelUpsert { u.Set(model.FieldAPIBase, v) @@ -505,6 +559,24 @@ func (u *ModelUpsert) ClearAPIVersion() *ModelUpsert { return u } +// SetAPIHeader sets the "api_header" field. +func (u *ModelUpsert) SetAPIHeader(v string) *ModelUpsert { + u.Set(model.FieldAPIHeader, v) + return u +} + +// UpdateAPIHeader sets the "api_header" field to the value that was provided on create. +func (u *ModelUpsert) UpdateAPIHeader() *ModelUpsert { + u.SetExcluded(model.FieldAPIHeader) + return u +} + +// ClearAPIHeader clears the value of the "api_header" field. +func (u *ModelUpsert) ClearAPIHeader() *ModelUpsert { + u.SetNull(model.FieldAPIHeader) + return u +} + // SetDescription sets the "description" field. func (u *ModelUpsert) SetDescription(v string) *ModelUpsert { u.Set(model.FieldDescription, v) @@ -524,7 +596,7 @@ func (u *ModelUpsert) ClearDescription() *ModelUpsert { } // SetProvider sets the "provider" field. -func (u *ModelUpsert) SetProvider(v string) *ModelUpsert { +func (u *ModelUpsert) SetProvider(v consts.ModelProvider) *ModelUpsert { u.Set(model.FieldProvider, v) return u } @@ -692,6 +764,27 @@ func (u *ModelUpsertOne) UpdateModelType() *ModelUpsertOne { }) } +// SetShowName sets the "show_name" field. +func (u *ModelUpsertOne) SetShowName(v string) *ModelUpsertOne { + return u.Update(func(s *ModelUpsert) { + s.SetShowName(v) + }) +} + +// UpdateShowName sets the "show_name" field to the value that was provided on create. +func (u *ModelUpsertOne) UpdateShowName() *ModelUpsertOne { + return u.Update(func(s *ModelUpsert) { + s.UpdateShowName() + }) +} + +// ClearShowName clears the value of the "show_name" field. +func (u *ModelUpsertOne) ClearShowName() *ModelUpsertOne { + return u.Update(func(s *ModelUpsert) { + s.ClearShowName() + }) +} + // SetAPIBase sets the "api_base" field. func (u *ModelUpsertOne) SetAPIBase(v string) *ModelUpsertOne { return u.Update(func(s *ModelUpsert) { @@ -741,6 +834,27 @@ func (u *ModelUpsertOne) ClearAPIVersion() *ModelUpsertOne { }) } +// SetAPIHeader sets the "api_header" field. +func (u *ModelUpsertOne) SetAPIHeader(v string) *ModelUpsertOne { + return u.Update(func(s *ModelUpsert) { + s.SetAPIHeader(v) + }) +} + +// UpdateAPIHeader sets the "api_header" field to the value that was provided on create. +func (u *ModelUpsertOne) UpdateAPIHeader() *ModelUpsertOne { + return u.Update(func(s *ModelUpsert) { + s.UpdateAPIHeader() + }) +} + +// ClearAPIHeader clears the value of the "api_header" field. +func (u *ModelUpsertOne) ClearAPIHeader() *ModelUpsertOne { + return u.Update(func(s *ModelUpsert) { + s.ClearAPIHeader() + }) +} + // SetDescription sets the "description" field. func (u *ModelUpsertOne) SetDescription(v string) *ModelUpsertOne { return u.Update(func(s *ModelUpsert) { @@ -763,7 +877,7 @@ func (u *ModelUpsertOne) ClearDescription() *ModelUpsertOne { } // SetProvider sets the "provider" field. -func (u *ModelUpsertOne) SetProvider(v string) *ModelUpsertOne { +func (u *ModelUpsertOne) SetProvider(v consts.ModelProvider) *ModelUpsertOne { return u.Update(func(s *ModelUpsert) { s.SetProvider(v) }) @@ -1110,6 +1224,27 @@ func (u *ModelUpsertBulk) UpdateModelType() *ModelUpsertBulk { }) } +// SetShowName sets the "show_name" field. +func (u *ModelUpsertBulk) SetShowName(v string) *ModelUpsertBulk { + return u.Update(func(s *ModelUpsert) { + s.SetShowName(v) + }) +} + +// UpdateShowName sets the "show_name" field to the value that was provided on create. +func (u *ModelUpsertBulk) UpdateShowName() *ModelUpsertBulk { + return u.Update(func(s *ModelUpsert) { + s.UpdateShowName() + }) +} + +// ClearShowName clears the value of the "show_name" field. +func (u *ModelUpsertBulk) ClearShowName() *ModelUpsertBulk { + return u.Update(func(s *ModelUpsert) { + s.ClearShowName() + }) +} + // SetAPIBase sets the "api_base" field. func (u *ModelUpsertBulk) SetAPIBase(v string) *ModelUpsertBulk { return u.Update(func(s *ModelUpsert) { @@ -1159,6 +1294,27 @@ func (u *ModelUpsertBulk) ClearAPIVersion() *ModelUpsertBulk { }) } +// SetAPIHeader sets the "api_header" field. +func (u *ModelUpsertBulk) SetAPIHeader(v string) *ModelUpsertBulk { + return u.Update(func(s *ModelUpsert) { + s.SetAPIHeader(v) + }) +} + +// UpdateAPIHeader sets the "api_header" field to the value that was provided on create. +func (u *ModelUpsertBulk) UpdateAPIHeader() *ModelUpsertBulk { + return u.Update(func(s *ModelUpsert) { + s.UpdateAPIHeader() + }) +} + +// ClearAPIHeader clears the value of the "api_header" field. +func (u *ModelUpsertBulk) ClearAPIHeader() *ModelUpsertBulk { + return u.Update(func(s *ModelUpsert) { + s.ClearAPIHeader() + }) +} + // SetDescription sets the "description" field. func (u *ModelUpsertBulk) SetDescription(v string) *ModelUpsertBulk { return u.Update(func(s *ModelUpsert) { @@ -1181,7 +1337,7 @@ func (u *ModelUpsertBulk) ClearDescription() *ModelUpsertBulk { } // SetProvider sets the "provider" field. -func (u *ModelUpsertBulk) SetProvider(v string) *ModelUpsertBulk { +func (u *ModelUpsertBulk) SetProvider(v consts.ModelProvider) *ModelUpsertBulk { return u.Update(func(s *ModelUpsert) { s.SetProvider(v) }) diff --git a/backend/db/model_update.go b/backend/db/model_update.go index ae211cd..7cfd4fc 100644 --- a/backend/db/model_update.go +++ b/backend/db/model_update.go @@ -81,6 +81,26 @@ func (mu *ModelUpdate) SetNillableModelType(ct *consts.ModelType) *ModelUpdate { return mu } +// SetShowName sets the "show_name" field. +func (mu *ModelUpdate) SetShowName(s string) *ModelUpdate { + mu.mutation.SetShowName(s) + return mu +} + +// SetNillableShowName sets the "show_name" field if the given value is not nil. +func (mu *ModelUpdate) SetNillableShowName(s *string) *ModelUpdate { + if s != nil { + mu.SetShowName(*s) + } + return mu +} + +// ClearShowName clears the value of the "show_name" field. +func (mu *ModelUpdate) ClearShowName() *ModelUpdate { + mu.mutation.ClearShowName() + return mu +} + // SetAPIBase sets the "api_base" field. func (mu *ModelUpdate) SetAPIBase(s string) *ModelUpdate { mu.mutation.SetAPIBase(s) @@ -129,6 +149,26 @@ func (mu *ModelUpdate) ClearAPIVersion() *ModelUpdate { return mu } +// SetAPIHeader sets the "api_header" field. +func (mu *ModelUpdate) SetAPIHeader(s string) *ModelUpdate { + mu.mutation.SetAPIHeader(s) + return mu +} + +// SetNillableAPIHeader sets the "api_header" field if the given value is not nil. +func (mu *ModelUpdate) SetNillableAPIHeader(s *string) *ModelUpdate { + if s != nil { + mu.SetAPIHeader(*s) + } + return mu +} + +// ClearAPIHeader clears the value of the "api_header" field. +func (mu *ModelUpdate) ClearAPIHeader() *ModelUpdate { + mu.mutation.ClearAPIHeader() + return mu +} + // SetDescription sets the "description" field. func (mu *ModelUpdate) SetDescription(s string) *ModelUpdate { mu.mutation.SetDescription(s) @@ -150,15 +190,15 @@ func (mu *ModelUpdate) ClearDescription() *ModelUpdate { } // SetProvider sets the "provider" field. -func (mu *ModelUpdate) SetProvider(s string) *ModelUpdate { - mu.mutation.SetProvider(s) +func (mu *ModelUpdate) SetProvider(cp consts.ModelProvider) *ModelUpdate { + mu.mutation.SetProvider(cp) return mu } // SetNillableProvider sets the "provider" field if the given value is not nil. -func (mu *ModelUpdate) SetNillableProvider(s *string) *ModelUpdate { - if s != nil { - mu.SetProvider(*s) +func (mu *ModelUpdate) SetNillableProvider(cp *consts.ModelProvider) *ModelUpdate { + if cp != nil { + mu.SetProvider(*cp) } return mu } @@ -333,6 +373,12 @@ func (mu *ModelUpdate) sqlSave(ctx context.Context) (n int, err error) { if value, ok := mu.mutation.ModelType(); ok { _spec.SetField(model.FieldModelType, field.TypeString, value) } + if value, ok := mu.mutation.ShowName(); ok { + _spec.SetField(model.FieldShowName, field.TypeString, value) + } + if mu.mutation.ShowNameCleared() { + _spec.ClearField(model.FieldShowName, field.TypeString) + } if value, ok := mu.mutation.APIBase(); ok { _spec.SetField(model.FieldAPIBase, field.TypeString, value) } @@ -345,6 +391,12 @@ func (mu *ModelUpdate) sqlSave(ctx context.Context) (n int, err error) { if mu.mutation.APIVersionCleared() { _spec.ClearField(model.FieldAPIVersion, field.TypeString) } + if value, ok := mu.mutation.APIHeader(); ok { + _spec.SetField(model.FieldAPIHeader, field.TypeString, value) + } + if mu.mutation.APIHeaderCleared() { + _spec.ClearField(model.FieldAPIHeader, field.TypeString) + } if value, ok := mu.mutation.Description(); ok { _spec.SetField(model.FieldDescription, field.TypeString, value) } @@ -516,6 +568,26 @@ func (muo *ModelUpdateOne) SetNillableModelType(ct *consts.ModelType) *ModelUpda return muo } +// SetShowName sets the "show_name" field. +func (muo *ModelUpdateOne) SetShowName(s string) *ModelUpdateOne { + muo.mutation.SetShowName(s) + return muo +} + +// SetNillableShowName sets the "show_name" field if the given value is not nil. +func (muo *ModelUpdateOne) SetNillableShowName(s *string) *ModelUpdateOne { + if s != nil { + muo.SetShowName(*s) + } + return muo +} + +// ClearShowName clears the value of the "show_name" field. +func (muo *ModelUpdateOne) ClearShowName() *ModelUpdateOne { + muo.mutation.ClearShowName() + return muo +} + // SetAPIBase sets the "api_base" field. func (muo *ModelUpdateOne) SetAPIBase(s string) *ModelUpdateOne { muo.mutation.SetAPIBase(s) @@ -564,6 +636,26 @@ func (muo *ModelUpdateOne) ClearAPIVersion() *ModelUpdateOne { return muo } +// SetAPIHeader sets the "api_header" field. +func (muo *ModelUpdateOne) SetAPIHeader(s string) *ModelUpdateOne { + muo.mutation.SetAPIHeader(s) + return muo +} + +// SetNillableAPIHeader sets the "api_header" field if the given value is not nil. +func (muo *ModelUpdateOne) SetNillableAPIHeader(s *string) *ModelUpdateOne { + if s != nil { + muo.SetAPIHeader(*s) + } + return muo +} + +// ClearAPIHeader clears the value of the "api_header" field. +func (muo *ModelUpdateOne) ClearAPIHeader() *ModelUpdateOne { + muo.mutation.ClearAPIHeader() + return muo +} + // SetDescription sets the "description" field. func (muo *ModelUpdateOne) SetDescription(s string) *ModelUpdateOne { muo.mutation.SetDescription(s) @@ -585,15 +677,15 @@ func (muo *ModelUpdateOne) ClearDescription() *ModelUpdateOne { } // SetProvider sets the "provider" field. -func (muo *ModelUpdateOne) SetProvider(s string) *ModelUpdateOne { - muo.mutation.SetProvider(s) +func (muo *ModelUpdateOne) SetProvider(cp consts.ModelProvider) *ModelUpdateOne { + muo.mutation.SetProvider(cp) return muo } // SetNillableProvider sets the "provider" field if the given value is not nil. -func (muo *ModelUpdateOne) SetNillableProvider(s *string) *ModelUpdateOne { - if s != nil { - muo.SetProvider(*s) +func (muo *ModelUpdateOne) SetNillableProvider(cp *consts.ModelProvider) *ModelUpdateOne { + if cp != nil { + muo.SetProvider(*cp) } return muo } @@ -798,6 +890,12 @@ func (muo *ModelUpdateOne) sqlSave(ctx context.Context) (_node *Model, err error if value, ok := muo.mutation.ModelType(); ok { _spec.SetField(model.FieldModelType, field.TypeString, value) } + if value, ok := muo.mutation.ShowName(); ok { + _spec.SetField(model.FieldShowName, field.TypeString, value) + } + if muo.mutation.ShowNameCleared() { + _spec.ClearField(model.FieldShowName, field.TypeString) + } if value, ok := muo.mutation.APIBase(); ok { _spec.SetField(model.FieldAPIBase, field.TypeString, value) } @@ -810,6 +908,12 @@ func (muo *ModelUpdateOne) sqlSave(ctx context.Context) (_node *Model, err error if muo.mutation.APIVersionCleared() { _spec.ClearField(model.FieldAPIVersion, field.TypeString) } + if value, ok := muo.mutation.APIHeader(); ok { + _spec.SetField(model.FieldAPIHeader, field.TypeString, value) + } + if muo.mutation.APIHeaderCleared() { + _spec.ClearField(model.FieldAPIHeader, field.TypeString) + } if value, ok := muo.mutation.Description(); ok { _spec.SetField(model.FieldDescription, field.TypeString, value) } diff --git a/backend/db/mutation.go b/backend/db/mutation.go index 3340766..f5c3423 100644 --- a/backend/db/mutation.go +++ b/backend/db/mutation.go @@ -6388,11 +6388,13 @@ type ModelMutation struct { id *uuid.UUID model_name *string model_type *consts.ModelType + show_name *string api_base *string api_key *string api_version *string + api_header *string description *string - provider *string + provider *consts.ModelProvider status *consts.ModelStatus context_length *int addcontext_length *int @@ -6634,6 +6636,55 @@ func (m *ModelMutation) ResetModelType() { m.model_type = nil } +// SetShowName sets the "show_name" field. +func (m *ModelMutation) SetShowName(s string) { + m.show_name = &s +} + +// ShowName returns the value of the "show_name" field in the mutation. +func (m *ModelMutation) ShowName() (r string, exists bool) { + v := m.show_name + if v == nil { + return + } + return *v, true +} + +// OldShowName returns the old "show_name" field's value of the Model entity. +// If the Model object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *ModelMutation) OldShowName(ctx context.Context) (v string, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldShowName is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldShowName requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldShowName: %w", err) + } + return oldValue.ShowName, nil +} + +// ClearShowName clears the value of the "show_name" field. +func (m *ModelMutation) ClearShowName() { + m.show_name = nil + m.clearedFields[model.FieldShowName] = struct{}{} +} + +// ShowNameCleared returns if the "show_name" field was cleared in this mutation. +func (m *ModelMutation) ShowNameCleared() bool { + _, ok := m.clearedFields[model.FieldShowName] + return ok +} + +// ResetShowName resets all changes to the "show_name" field. +func (m *ModelMutation) ResetShowName() { + m.show_name = nil + delete(m.clearedFields, model.FieldShowName) +} + // SetAPIBase sets the "api_base" field. func (m *ModelMutation) SetAPIBase(s string) { m.api_base = &s @@ -6755,6 +6806,55 @@ func (m *ModelMutation) ResetAPIVersion() { delete(m.clearedFields, model.FieldAPIVersion) } +// SetAPIHeader sets the "api_header" field. +func (m *ModelMutation) SetAPIHeader(s string) { + m.api_header = &s +} + +// APIHeader returns the value of the "api_header" field in the mutation. +func (m *ModelMutation) APIHeader() (r string, exists bool) { + v := m.api_header + if v == nil { + return + } + return *v, true +} + +// OldAPIHeader returns the old "api_header" field's value of the Model entity. +// If the Model object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *ModelMutation) OldAPIHeader(ctx context.Context) (v string, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldAPIHeader is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldAPIHeader requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldAPIHeader: %w", err) + } + return oldValue.APIHeader, nil +} + +// ClearAPIHeader clears the value of the "api_header" field. +func (m *ModelMutation) ClearAPIHeader() { + m.api_header = nil + m.clearedFields[model.FieldAPIHeader] = struct{}{} +} + +// APIHeaderCleared returns if the "api_header" field was cleared in this mutation. +func (m *ModelMutation) APIHeaderCleared() bool { + _, ok := m.clearedFields[model.FieldAPIHeader] + return ok +} + +// ResetAPIHeader resets all changes to the "api_header" field. +func (m *ModelMutation) ResetAPIHeader() { + m.api_header = nil + delete(m.clearedFields, model.FieldAPIHeader) +} + // SetDescription sets the "description" field. func (m *ModelMutation) SetDescription(s string) { m.description = &s @@ -6805,12 +6905,12 @@ func (m *ModelMutation) ResetDescription() { } // SetProvider sets the "provider" field. -func (m *ModelMutation) SetProvider(s string) { - m.provider = &s +func (m *ModelMutation) SetProvider(cp consts.ModelProvider) { + m.provider = &cp } // Provider returns the value of the "provider" field in the mutation. -func (m *ModelMutation) Provider() (r string, exists bool) { +func (m *ModelMutation) Provider() (r consts.ModelProvider, exists bool) { v := m.provider if v == nil { return @@ -6821,7 +6921,7 @@ func (m *ModelMutation) Provider() (r string, exists bool) { // OldProvider returns the old "provider" field's value of the Model entity. // If the Model object wasn't provided to the builder, the object is fetched from the database. // An error is returned if the mutation operation is not UpdateOne, or the database query fails. -func (m *ModelMutation) OldProvider(ctx context.Context) (v string, err error) { +func (m *ModelMutation) OldProvider(ctx context.Context) (v consts.ModelProvider, err error) { if !m.op.Is(OpUpdateOne) { return v, errors.New("OldProvider is only allowed on UpdateOne operations") } @@ -7133,7 +7233,7 @@ func (m *ModelMutation) Type() string { // order to get all numeric fields that were incremented/decremented, call // AddedFields(). func (m *ModelMutation) Fields() []string { - fields := make([]string, 0, 12) + fields := make([]string, 0, 14) if m.user != nil { fields = append(fields, model.FieldUserID) } @@ -7143,6 +7243,9 @@ func (m *ModelMutation) Fields() []string { if m.model_type != nil { fields = append(fields, model.FieldModelType) } + if m.show_name != nil { + fields = append(fields, model.FieldShowName) + } if m.api_base != nil { fields = append(fields, model.FieldAPIBase) } @@ -7152,6 +7255,9 @@ func (m *ModelMutation) Fields() []string { if m.api_version != nil { fields = append(fields, model.FieldAPIVersion) } + if m.api_header != nil { + fields = append(fields, model.FieldAPIHeader) + } if m.description != nil { fields = append(fields, model.FieldDescription) } @@ -7184,12 +7290,16 @@ func (m *ModelMutation) Field(name string) (ent.Value, bool) { return m.ModelName() case model.FieldModelType: return m.ModelType() + case model.FieldShowName: + return m.ShowName() case model.FieldAPIBase: return m.APIBase() case model.FieldAPIKey: return m.APIKey() case model.FieldAPIVersion: return m.APIVersion() + case model.FieldAPIHeader: + return m.APIHeader() case model.FieldDescription: return m.Description() case model.FieldProvider: @@ -7217,12 +7327,16 @@ func (m *ModelMutation) OldField(ctx context.Context, name string) (ent.Value, e return m.OldModelName(ctx) case model.FieldModelType: return m.OldModelType(ctx) + case model.FieldShowName: + return m.OldShowName(ctx) case model.FieldAPIBase: return m.OldAPIBase(ctx) case model.FieldAPIKey: return m.OldAPIKey(ctx) case model.FieldAPIVersion: return m.OldAPIVersion(ctx) + case model.FieldAPIHeader: + return m.OldAPIHeader(ctx) case model.FieldDescription: return m.OldDescription(ctx) case model.FieldProvider: @@ -7265,6 +7379,13 @@ func (m *ModelMutation) SetField(name string, value ent.Value) error { } m.SetModelType(v) return nil + case model.FieldShowName: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetShowName(v) + return nil case model.FieldAPIBase: v, ok := value.(string) if !ok { @@ -7286,6 +7407,13 @@ func (m *ModelMutation) SetField(name string, value ent.Value) error { } m.SetAPIVersion(v) return nil + case model.FieldAPIHeader: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetAPIHeader(v) + return nil case model.FieldDescription: v, ok := value.(string) if !ok { @@ -7294,7 +7422,7 @@ func (m *ModelMutation) SetField(name string, value ent.Value) error { m.SetDescription(v) return nil case model.FieldProvider: - v, ok := value.(string) + v, ok := value.(consts.ModelProvider) if !ok { return fmt.Errorf("unexpected type %T for field %s", value, name) } @@ -7376,9 +7504,15 @@ func (m *ModelMutation) ClearedFields() []string { if m.FieldCleared(model.FieldUserID) { fields = append(fields, model.FieldUserID) } + if m.FieldCleared(model.FieldShowName) { + fields = append(fields, model.FieldShowName) + } if m.FieldCleared(model.FieldAPIVersion) { fields = append(fields, model.FieldAPIVersion) } + if m.FieldCleared(model.FieldAPIHeader) { + fields = append(fields, model.FieldAPIHeader) + } if m.FieldCleared(model.FieldDescription) { fields = append(fields, model.FieldDescription) } @@ -7402,9 +7536,15 @@ func (m *ModelMutation) ClearField(name string) error { case model.FieldUserID: m.ClearUserID() return nil + case model.FieldShowName: + m.ClearShowName() + return nil case model.FieldAPIVersion: m.ClearAPIVersion() return nil + case model.FieldAPIHeader: + m.ClearAPIHeader() + return nil case model.FieldDescription: m.ClearDescription() return nil @@ -7428,6 +7568,9 @@ func (m *ModelMutation) ResetField(name string) error { case model.FieldModelType: m.ResetModelType() return nil + case model.FieldShowName: + m.ResetShowName() + return nil case model.FieldAPIBase: m.ResetAPIBase() return nil @@ -7437,6 +7580,9 @@ func (m *ModelMutation) ResetField(name string) error { case model.FieldAPIVersion: m.ResetAPIVersion() return nil + case model.FieldAPIHeader: + m.ResetAPIHeader() + return nil case model.FieldDescription: m.ResetDescription() return nil diff --git a/backend/db/runtime/runtime.go b/backend/db/runtime/runtime.go index ad4cdb4..624da66 100644 --- a/backend/db/runtime/runtime.go +++ b/backend/db/runtime/runtime.go @@ -157,15 +157,15 @@ func init() { modelFields := schema.Model{}.Fields() _ = modelFields // modelDescStatus is the schema descriptor for status field. - modelDescStatus := modelFields[9].Descriptor() + modelDescStatus := modelFields[11].Descriptor() // model.DefaultStatus holds the default value on creation for the status field. model.DefaultStatus = consts.ModelStatus(modelDescStatus.Default.(string)) // modelDescCreatedAt is the schema descriptor for created_at field. - modelDescCreatedAt := modelFields[11].Descriptor() + modelDescCreatedAt := modelFields[13].Descriptor() // model.DefaultCreatedAt holds the default value on creation for the created_at field. model.DefaultCreatedAt = modelDescCreatedAt.Default.(func() time.Time) // modelDescUpdatedAt is the schema descriptor for updated_at field. - modelDescUpdatedAt := modelFields[12].Descriptor() + modelDescUpdatedAt := modelFields[14].Descriptor() // model.DefaultUpdatedAt holds the default value on creation for the updated_at field. model.DefaultUpdatedAt = modelDescUpdatedAt.Default.(func() time.Time) // model.UpdateDefaultUpdatedAt holds the default value on update for the updated_at field. diff --git a/backend/docs/swagger.json b/backend/docs/swagger.json index 581474e..a396efa 100644 --- a/backend/docs/swagger.json +++ b/backend/docs/swagger.json @@ -1223,6 +1223,110 @@ } } }, + "/api/v1/model/provider/supported": { + "get": { + "description": "获取供应商支持的模型列表", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Model" + ], + "summary": "获取供应商支持的模型列表", + "operationId": "get-provider-model-list", + "parameters": [ + { + "type": "string", + "name": "api_header", + "in": "query" + }, + { + "type": "string", + "name": "api_key", + "in": "query" + }, + { + "type": "string", + "name": "base_url", + "in": "query", + "required": true + }, + { + "enum": [ + "SiliconFlow", + "OpenAI", + "Ollama", + "DeepSeek", + "Moonshot", + "AzureOpenAI", + "BaiZhiCloud", + "Hunyuan", + "BaiLian", + "Volcengine" + ], + "type": "string", + "x-enum-varnames": [ + "ModelProviderSiliconFlow", + "ModelProviderOpenAI", + "ModelProviderOllama", + "ModelProviderDeepSeek", + "ModelProviderMoonshot", + "ModelProviderAzureOpenAI", + "ModelProviderBaiZhiCloud", + "ModelProviderHunyuan", + "ModelProviderBaiLian", + "ModelProviderVolcengine" + ], + "name": "provider", + "in": "query", + "required": true + }, + { + "enum": [ + "llm", + "coder", + "embedding", + "audio", + "reranker" + ], + "type": "string", + "x-enum-varnames": [ + "ModelTypeLLM", + "ModelTypeCoder", + "ModelTypeEmbedding", + "ModelTypeAudio", + "ModelTypeReranker" + ], + "name": "type", + "in": "query", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/web.Resp" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/domain.GetProviderModelListResp" + } + } + } + ] + } + } + } + } + }, "/api/v1/model/token-usage": { "get": { "description": "获取模型token使用情况", @@ -1923,6 +2027,33 @@ "ChatRoleAssistant" ] }, + "consts.ModelProvider": { + "type": "string", + "enum": [ + "SiliconFlow", + "OpenAI", + "Ollama", + "DeepSeek", + "Moonshot", + "AzureOpenAI", + "BaiZhiCloud", + "Hunyuan", + "BaiLian", + "Volcengine" + ], + "x-enum-varnames": [ + "ModelProviderSiliconFlow", + "ModelProviderOpenAI", + "ModelProviderOllama", + "ModelProviderDeepSeek", + "ModelProviderMoonshot", + "ModelProviderAzureOpenAI", + "ModelProviderBaiZhiCloud", + "ModelProviderHunyuan", + "ModelProviderBaiLian", + "ModelProviderVolcengine" + ] + }, "consts.ModelStatus": { "type": "string", "enum": [ @@ -2182,24 +2313,48 @@ "api_base", "api_key", "model_name", - "provider" + "provider", + "type" ], "properties": { "api_base": { "description": "接口地址", "type": "string" }, + "api_header": { + "type": "string" + }, "api_key": { "description": "接口密钥", "type": "string" }, + "api_version": { + "type": "string" + }, "model_name": { "description": "模型名称", "type": "string" }, "provider": { "description": "提供商", - "type": "string" + "allOf": [ + { + "$ref": "#/definitions/consts.ModelProvider" + } + ] + }, + "type": { + "enum": [ + "llm", + "coder", + "embedding", + "rerank" + ], + "allOf": [ + { + "$ref": "#/definitions/consts.ModelType" + } + ] } } }, @@ -2272,15 +2427,26 @@ }, "domain.CreateModelReq": { "type": "object", + "required": [ + "api_base", + "model_name", + "provider" + ], "properties": { "api_base": { "description": "接口地址 如:https://api.qwen.com", "type": "string" }, + "api_header": { + "type": "string" + }, "api_key": { "description": "接口密钥 如:sk-xxxx", "type": "string" }, + "api_version": { + "type": "string" + }, "model_name": { "description": "模型名称 如: deepseek-v3", "type": "string" @@ -2295,6 +2461,26 @@ }, "provider": { "description": "提供商", + "enum": [ + "SiliconFlow", + "OpenAI", + "Ollama", + "DeepSeek", + "Moonshot", + "AzureOpenAI", + "BaiZhiCloud", + "Hunyuan", + "BaiLian", + "Volcengine" + ], + "allOf": [ + { + "$ref": "#/definitions/consts.ModelProvider" + } + ] + }, + "show_name": { + "description": "模型显示名称", "type": "string" } } @@ -2437,6 +2623,17 @@ } } }, + "domain.GetProviderModelListResp": { + "type": "object", + "properties": { + "models": { + "type": "array", + "items": { + "$ref": "#/definitions/domain.ProviderModelListItem" + } + } + } + }, "domain.IPInfo": { "type": "object", "properties": { @@ -2628,10 +2825,18 @@ "description": "接口地址 如:https://api.qwen.com", "type": "string" }, + "api_header": { + "description": "接口头 如:Authorization: Bearer sk-xxxx", + "type": "string" + }, "api_key": { "description": "接口密钥 如:sk-xxxx", "type": "string" }, + "api_version": { + "description": "接口版本 如:2023-05-15", + "type": "string" + }, "created_at": { "description": "创建时间", "type": "integer" @@ -2666,6 +2871,14 @@ }, "provider": { "description": "提供商", + "allOf": [ + { + "$ref": "#/definitions/consts.ModelProvider" + } + ] + }, + "show_name": { + "description": "模型显示名称", "type": "string" }, "status": { @@ -2684,6 +2897,9 @@ }, "domain.ModelBasic": { "type": "object", + "required": [ + "provider" + ], "properties": { "api_base": { "description": "接口地址 如:https://api.qwen.com", @@ -2695,7 +2911,23 @@ }, "provider": { "description": "提供商", - "type": "string" + "enum": [ + "SiliconFlow", + "OpenAI", + "Ollama", + "DeepSeek", + "Moonshot", + "AzureOpenAI", + "BaiZhiCloud", + "Hunyuan", + "BaiLian", + "Volcengine" + ], + "allOf": [ + { + "$ref": "#/definitions/consts.ModelProvider" + } + ] } } }, @@ -2809,6 +3041,14 @@ } } }, + "domain.ProviderModelListItem": { + "type": "object", + "properties": { + "model": { + "type": "string" + } + } + }, "domain.RegisterReq": { "type": "object", "required": [ @@ -3023,15 +3263,24 @@ }, "domain.UpdateModelReq": { "type": "object", + "required": [ + "provider" + ], "properties": { "api_base": { "description": "接口地址 如:https://api.qwen.com", "type": "string" }, + "api_header": { + "type": "string" + }, "api_key": { "description": "接口密钥 如:sk-xxxx", "type": "string" }, + "api_version": { + "type": "string" + }, "id": { "description": "模型ID", "type": "string" @@ -3042,6 +3291,26 @@ }, "provider": { "description": "提供商", + "enum": [ + "SiliconFlow", + "OpenAI", + "Ollama", + "DeepSeek", + "Moonshot", + "AzureOpenAI", + "BaiZhiCloud", + "Hunyuan", + "BaiLian", + "Volcengine" + ], + "allOf": [ + { + "$ref": "#/definitions/consts.ModelProvider" + } + ] + }, + "show_name": { + "description": "模型显示名称", "type": "string" }, "status": { diff --git a/backend/domain/model.go b/backend/domain/model.go index a64e778..36d2896 100644 --- a/backend/domain/model.go +++ b/backend/domain/model.go @@ -17,6 +17,7 @@ type ModelUsecase interface { Check(ctx context.Context, req *CheckModelReq) (*Model, error) GetTokenUsage(ctx context.Context, modelType consts.ModelType) (*ModelTokenUsageResp, error) InitModel(ctx context.Context) error + GetProviderModelList(ctx context.Context, req *GetProviderModelListReq) (*GetProviderModelListResp, error) } type ModelRepo interface { @@ -30,16 +31,72 @@ type ModelRepo interface { InitModel(ctx context.Context, modelName, modelKey, modelURL string) error } +var ModelProviderBrandModelsList = map[consts.ModelProvider][]ProviderModelListItem{ + consts.ModelProviderOpenAI: { + {Model: "gpt-4o"}, + }, + consts.ModelProviderDeepSeek: { + {Model: "deepseek-reasoner"}, + {Model: "deepseek-chat"}, + }, + consts.ModelProviderMoonshot: { + {Model: "moonshot-v1-auto"}, + {Model: "moonshot-v1-8k"}, + {Model: "moonshot-v1-32k"}, + {Model: "moonshot-v1-128k"}, + }, + consts.ModelProviderAzureOpenAI: { + {Model: "gpt-4"}, + {Model: "gpt-4o"}, + {Model: "gpt-4o-mini"}, + {Model: "gpt-4o-nano"}, + {Model: "gpt-4.1"}, + {Model: "gpt-4.1-mini"}, + {Model: "gpt-4.1-nano"}, + {Model: "o1"}, + {Model: "o1-mini"}, + {Model: "o3"}, + {Model: "o3-mini"}, + {Model: "o4-mini"}, + }, + consts.ModelProviderVolcengine: { + {Model: "doubao-seed-1.6-250615"}, + {Model: "doubao-seed-1.6-flash-250615"}, + {Model: "doubao-seed-1.6-thinking-250615"}, + {Model: "doubao-1.5-thinking-vision-pro-250428"}, + {Model: "deepseek-r1-250528"}, + }, +} + type MyModelListReq struct { UserID string `json:"-"` ModelType consts.ModelType `json:"model_type" query:"model_type"` // 模型类型 llm:对话模型 coder:代码模型 } type CheckModelReq struct { - Provider string `json:"provider" validate:"required"` // 提供商 - ModelName string `json:"model_name" validate:"required"` // 模型名称 - APIBase string `json:"api_base" validate:"required"` // 接口地址 - APIKey string `json:"api_key" validate:"required"` // 接口密钥 + Type consts.ModelType `json:"type" validate:"required,oneof=llm coder embedding rerank"` + Provider consts.ModelProvider `json:"provider" validate:"required"` // 提供商 + ModelName string `json:"model_name" validate:"required"` // 模型名称 + APIBase string `json:"api_base" validate:"required"` // 接口地址 + APIKey string `json:"api_key" validate:"required"` // 接口密钥 + APIVersion string `json:"api_version"` + APIHeader string `json:"api_header"` +} + +type GetProviderModelListReq struct { + Provider consts.ModelProvider `json:"provider" query:"provider" validate:"required,oneof=SiliconFlow OpenAI Ollama DeepSeek Moonshot AzureOpenAI BaiZhiCloud Hunyuan BaiLian Volcengine"` + BaseURL string `json:"base_url" query:"base_url" validate:"required"` + APIKey string `json:"api_key" query:"api_key"` + APIHeader string `json:"api_header" query:"api_header"` + Type consts.ModelType `json:"type" query:"type" validate:"required,oneof=llm coder embedding rerank"` +} + +type GetProviderModelListResp struct { + Models []ProviderModelListItem `json:"models"` +} + +type ProviderModelListItem struct { + Model string `json:"model"` } type AllModelResp struct { @@ -56,21 +113,27 @@ type GetTokenUsageReq struct { } type CreateModelReq struct { - UserID string `json:"-"` - ModelName string `json:"model_name"` // 模型名称 如: deepseek-v3 - Provider string `json:"provider"` // 提供商 - APIBase string `json:"api_base"` // 接口地址 如:https://api.qwen.com - APIKey string `json:"api_key"` // 接口密钥 如:sk-xxxx - ModelType consts.ModelType `json:"model_type"` // 模型类型 llm:对话模型 coder:代码模型 + UserID string `json:"-"` + ShowName string `json:"show_name"` // 模型显示名称 + ModelName string `json:"model_name" validate:"required"` // 模型名称 如: deepseek-v3 + Provider consts.ModelProvider `json:"provider" validate:"required,oneof=SiliconFlow OpenAI Ollama DeepSeek Moonshot AzureOpenAI BaiZhiCloud Hunyuan BaiLian Volcengine"` // 提供商 + APIBase string `json:"api_base" validate:"required"` // 接口地址 如:https://api.qwen.com + APIKey string `json:"api_key"` // 接口密钥 如:sk-xxxx + APIVersion string `json:"api_version"` + APIHeader string `json:"api_header"` + ModelType consts.ModelType `json:"model_type"` // 模型类型 llm:对话模型 coder:代码模型 } type UpdateModelReq struct { - ID string `json:"id"` // 模型ID - ModelName *string `json:"model_name"` // 模型名称 - Provider *string `json:"provider"` // 提供商 - APIBase *string `json:"api_base"` // 接口地址 如:https://api.qwen.com - APIKey *string `json:"api_key"` // 接口密钥 如:sk-xxxx - Status *consts.ModelStatus `json:"status"` // 状态 active:启用 inactive:禁用 + ID string `json:"id"` // 模型ID + ModelName *string `json:"model_name"` // 模型名称 + ShowName string `json:"show_name"` // 模型显示名称 + Provider *consts.ModelProvider `json:"provider" validate:"required,oneof=SiliconFlow OpenAI Ollama DeepSeek Moonshot AzureOpenAI BaiZhiCloud Hunyuan BaiLian Volcengine"` // 提供商 + APIBase *string `json:"api_base"` // 接口地址 如:https://api.qwen.com + APIKey *string `json:"api_key"` // 接口密钥 如:sk-xxxx + APIVersion *string `json:"api_version"` + APIHeader *string `json:"api_header"` + Status *consts.ModelStatus `json:"status"` // 状态 active:启用 inactive:禁用 } type ModelTokenUsageResp struct { @@ -86,9 +149,9 @@ type ModelTokenUsage struct { } type ModelBasic struct { - Name string `json:"name"` // 模型名称 - Provider string `json:"provider"` // 提供商 - APIBase string `json:"api_base"` // 接口地址 如:https://api.qwen.com + Name string `json:"name"` // 模型名称 + Provider consts.ModelProvider `json:"provider" validate:"required,oneof=SiliconFlow OpenAI Ollama DeepSeek Moonshot AzureOpenAI BaiZhiCloud Hunyuan BaiLian Volcengine"` // 提供商 + APIBase string `json:"api_base"` // 接口地址 如:https://api.qwen.com } type ModelUsage struct { @@ -98,18 +161,21 @@ type ModelUsage struct { } type Model struct { - ID string `json:"id"` // 模型ID - ModelName string `json:"model_name"` // 模型名称 如: deepseek-v3 - Provider string `json:"provider"` // 提供商 - APIBase string `json:"api_base"` // 接口地址 如:https://api.qwen.com - APIKey string `json:"api_key"` // 接口密钥 如:sk-xxxx - ModelType consts.ModelType `json:"model_type"` // 模型类型 llm:对话模型 coder:代码模型 - Status consts.ModelStatus `json:"status"` // 状态 active:启用 inactive:禁用 - IsActive bool `json:"is_active"` // 是否启用 - Input int64 `json:"input"` // 输入token数 - Output int64 `json:"output"` // 输出token数 - CreatedAt int64 `json:"created_at"` // 创建时间 - UpdatedAt int64 `json:"updated_at"` // 更新时间 + ID string `json:"id"` // 模型ID + ShowName string `json:"show_name"` // 模型显示名称 + ModelName string `json:"model_name"` // 模型名称 如: deepseek-v3 + Provider consts.ModelProvider `json:"provider"` // 提供商 + APIBase string `json:"api_base"` // 接口地址 如:https://api.qwen.com + APIKey string `json:"api_key"` // 接口密钥 如:sk-xxxx + APIVersion string `json:"api_version"` // 接口版本 如:2023-05-15 + APIHeader string `json:"api_header"` // 接口头 如:Authorization: Bearer sk-xxxx + ModelType consts.ModelType `json:"model_type"` // 模型类型 llm:对话模型 coder:代码模型 + Status consts.ModelStatus `json:"status"` // 状态 active:启用 inactive:禁用 + IsActive bool `json:"is_active"` // 是否启用 + Input int64 `json:"input"` // 输入token数 + Output int64 `json:"output"` // 输出token数 + CreatedAt int64 `json:"created_at"` // 创建时间 + UpdatedAt int64 `json:"updated_at"` // 更新时间 } func (m *Model) From(e *db.Model) *Model { @@ -118,10 +184,13 @@ func (m *Model) From(e *db.Model) *Model { } m.ID = e.ID.String() + m.ShowName = e.ShowName m.ModelName = e.ModelName m.Provider = e.Provider m.APIBase = e.APIBase m.APIKey = e.APIKey + m.APIVersion = e.APIVersion + m.APIHeader = e.APIHeader m.ModelType = e.ModelType m.Status = e.Status m.IsActive = e.Status == consts.ModelStatusActive @@ -130,3 +199,8 @@ func (m *Model) From(e *db.Model) *Model { return m } + +type CheckModelResp struct { + Error string `json:"error"` + Content string `json:"content"` +} diff --git a/backend/domain/openai.go b/backend/domain/openai.go index 0fec80d..0849bc8 100644 --- a/backend/domain/openai.go +++ b/backend/domain/openai.go @@ -70,3 +70,11 @@ type ConfigResp struct { Type consts.ConfigType `json:"type"` Content string `json:"content"` } +type OpenAIResp struct { + Object string `json:"object"` + Data []*OpenAIData `json:"data"` +} + +type OpenAIData struct { + ID string `json:"id"` +} diff --git a/backend/ent/schema/model.go b/backend/ent/schema/model.go index b8176ba..d9f21d1 100644 --- a/backend/ent/schema/model.go +++ b/backend/ent/schema/model.go @@ -33,11 +33,13 @@ func (Model) Fields() []ent.Field { field.UUID("user_id", uuid.UUID{}).Optional(), field.String("model_name"), field.String("model_type").GoType(consts.ModelType("")), + field.String("show_name").Optional(), field.String("api_base"), field.String("api_key"), field.String("api_version").Optional(), + field.String("api_header").Optional(), field.String("description").Optional(), - field.String("provider"), + field.String("provider").GoType(consts.ModelProvider("")), field.String("status").GoType(consts.ModelStatus("")).Default(string(consts.ModelStatusActive)), field.Int("context_length").Optional(), field.Time("created_at").Default(time.Now), diff --git a/backend/go.mod b/backend/go.mod index ec3b670..bec77b1 100644 --- a/backend/go.mod +++ b/backend/go.mod @@ -5,6 +5,8 @@ go 1.23.7 require ( entgo.io/ent v0.14.4 github.com/GoYoko/web v1.0.0 + github.com/cloudwego/eino v0.3.51 + github.com/cloudwego/eino-ext/components/model/openai v0.0.0-20250710065240-482d48888f25 github.com/golang-migrate/migrate/v4 v4.18.3 github.com/google/uuid v1.6.0 github.com/google/wire v0.6.0 @@ -25,43 +27,71 @@ require ( github.com/agext/levenshtein v1.2.3 // indirect github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect github.com/bmatcuk/doublestar v1.3.4 // indirect + github.com/bytedance/sonic v1.13.2 // indirect + github.com/bytedance/sonic/loader v0.2.4 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect + github.com/cloudwego/base64x v0.1.5 // indirect + github.com/cloudwego/eino-ext/libs/acl/openai v0.0.0-20250626133421-3c142631c961 // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect + github.com/dustin/go-humanize v1.0.1 // indirect + github.com/evanphx/json-patch v0.5.2 // indirect github.com/fsnotify/fsnotify v1.9.0 // indirect github.com/gabriel-vasile/mimetype v1.4.9 // indirect + github.com/getkin/kin-openapi v0.118.0 // indirect github.com/go-openapi/inflect v0.21.2 // indirect + github.com/go-openapi/jsonpointer v0.19.5 // indirect + github.com/go-openapi/swag v0.19.5 // indirect github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect github.com/go-playground/validator/v10 v10.27.0 // indirect github.com/go-viper/mapstructure/v2 v2.2.1 // indirect github.com/golang/protobuf v1.5.4 // indirect github.com/google/go-cmp v0.7.0 // indirect + github.com/goph/emperror v0.17.2 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/hcl/v2 v2.23.0 // indirect + github.com/invopop/yaml v0.1.0 // indirect + github.com/josharian/intern v1.0.0 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/klauspost/cpuid/v2 v2.0.9 // indirect github.com/labstack/gommon v0.4.2 // indirect github.com/leodido/go-urn v1.4.0 // indirect + github.com/mailru/easyjson v0.7.7 // indirect github.com/mattn/go-colorable v0.1.14 // indirect github.com/mattn/go-isatty v0.0.20 // indirect + github.com/meguminnnnnnnnn/go-openai v0.0.0-20250620092828-0d508a1dcdde // indirect github.com/mitchellh/go-wordwrap v1.0.1 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect github.com/nicksnyder/go-i18n/v2 v2.6.0 // indirect + github.com/nikolalohinski/gonja v1.5.3 // indirect github.com/pelletier/go-toml/v2 v2.2.4 // indirect + github.com/perimeterx/marshmallow v1.1.4 // indirect + github.com/pkg/errors v0.9.1 // indirect github.com/rogpeppe/go-internal v1.14.1 // indirect github.com/rs/xid v1.6.0 // indirect github.com/sagikazarmark/locafero v0.9.0 // indirect + github.com/sirupsen/logrus v1.9.3 // indirect + github.com/slongfield/pyfmt v0.0.0-20220222012616-ea85ff4c361f // indirect github.com/sourcegraph/conc v0.3.0 // indirect github.com/spf13/afero v1.14.0 // indirect github.com/spf13/cast v1.7.1 // indirect github.com/spf13/pflag v1.0.6 // indirect github.com/subosito/gotenv v1.6.0 // indirect + github.com/twitchyliquid64/golang-asm v0.15.1 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/fasttemplate v1.2.2 // indirect + github.com/yargevad/filepathx v1.0.0 // indirect github.com/zclconf/go-cty v1.16.2 // indirect github.com/zclconf/go-cty-yaml v1.1.0 // indirect go.opentelemetry.io/otel/metric v1.35.0 // indirect go.opentelemetry.io/otel/trace v1.35.0 // indirect go.uber.org/atomic v1.11.0 // indirect go.uber.org/multierr v1.11.0 // indirect + golang.org/x/arch v0.11.0 // indirect + golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1 // indirect golang.org/x/mod v0.25.0 // indirect golang.org/x/net v0.41.0 // indirect golang.org/x/sync v0.15.0 // indirect @@ -70,5 +100,6 @@ require ( golang.org/x/tools v0.33.0 // indirect google.golang.org/appengine v1.6.8 // indirect google.golang.org/protobuf v1.34.2 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/backend/go.sum b/backend/go.sum index d95c4b7..df38f4f 100644 --- a/backend/go.sum +++ b/backend/go.sum @@ -14,16 +14,39 @@ github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERo github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7lmo= github.com/agext/levenshtein v1.2.3/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= +github.com/airbrake/gobrake v3.6.1+incompatible/go.mod h1:wM4gu3Cn0W0K7GUuVWnlXZU11AGBXMILnrdOU8Kn00o= github.com/apparentlymart/go-textseg/v15 v15.0.0 h1:uYvfpb3DyLSCGWnctWKGj857c6ew1u1fNQOlOtuGxQY= github.com/apparentlymart/go-textseg/v15 v15.0.0/go.mod h1:K8XmNZdhEBkdlyDdvbmmsvpAG721bKi0joRfFdHIWJ4= +github.com/bitly/go-simplejson v0.5.0/go.mod h1:cXHtHw4XUPsvGaxgjIAn8PhEWG9NfngEKAMDJEczWVA= github.com/bmatcuk/doublestar v1.3.4 h1:gPypJ5xD31uhX6Tf54sDPUOBXTqKH4c9aPY66CyQrS0= github.com/bmatcuk/doublestar v1.3.4/go.mod h1:wiQtGV+rzVYxB7WIlirSN++5HPtPlXEo9MEoZQC/PmE= +github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs= github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c= github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA= github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0= +github.com/bugsnag/bugsnag-go v1.4.0/go.mod h1:2oa8nejYd4cQ/b0hMIopN0lCRxU0bueqREvZLWFrtK8= +github.com/bugsnag/panicwrap v1.2.0/go.mod h1:D/8v3kj0zr8ZAKg1AQ6crr+5VwKN5eIywRkfhyM/+dE= +github.com/bytedance/mockey v1.2.13 h1:jokWZAm/pUEbD939Rhznz615MKUCZNuvCFQlJ2+ntoo= +github.com/bytedance/mockey v1.2.13/go.mod h1:1BPHF9sol5R1ud/+0VEHGQq/+i2lN+GTsr3O2Q9IENY= +github.com/bytedance/sonic v1.13.2 h1:8/H1FempDZqC4VqjptGo14QQlJx8VdZJegxs6wwfqpQ= +github.com/bytedance/sonic v1.13.2/go.mod h1:o68xyaF9u2gvVBuGHPlUVCy+ZfmNNO5ETf1+KgkJhz4= +github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= +github.com/bytedance/sonic/loader v0.2.4 h1:ZWCw4stuXUsn1/+zQDqeE7JKP+QO47tz7QCNan80NzY= +github.com/bytedance/sonic/loader v0.2.4/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFosQU6FxH2JmUe6VI= +github.com/certifi/gocertifi v0.0.0-20190105021004-abcd57078448/go.mod h1:GJKEexRPVJrBSOjoqN5VNOIKJ5Q3RViH6eu3puDRwx4= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cloudwego/base64x v0.1.5 h1:XPciSp1xaq2VCSt6lF0phncD4koWyULpl5bUxbfCyP4= +github.com/cloudwego/base64x v0.1.5/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w= +github.com/cloudwego/eino v0.3.51 h1:emSaDu49v9EEJYOusL42Li/VL5QBSyBvhxO9ZcKPZvs= +github.com/cloudwego/eino v0.3.51/go.mod h1:wUjz990apdsaOraOXdh6CdhVXq8DJsOvLsVlxNTcNfY= +github.com/cloudwego/eino-ext/components/model/openai v0.0.0-20250710065240-482d48888f25 h1:VpyaCtZLktcYVC4vY0+D9e6TD35VAHteI+Zv6JUHFfQ= +github.com/cloudwego/eino-ext/components/model/openai v0.0.0-20250710065240-482d48888f25/go.mod h1:2mFQQnlhJrNgbW6YX1MOUUfXkGSbTz9Ylx37fbR0xBo= +github.com/cloudwego/eino-ext/libs/acl/openai v0.0.0-20250626133421-3c142631c961 h1:fGE3RFHaAsrLjA+2fkE0YMsPrkFI6pEKKZmbhD42L7E= +github.com/cloudwego/eino-ext/libs/acl/openai v0.0.0-20250626133421-3c142631c961/go.mod h1:iB0W8l+OqKNL5LtJQ9JaGYXekhsxVxrDMfnfD9L+5gc= +github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= @@ -38,20 +61,34 @@ github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= +github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= +github.com/evanphx/json-patch v0.5.2 h1:xVCHIVMUu1wtM/VkR9jVZ45N3FhZfYMMYGorLCR8P3k= +github.com/evanphx/json-patch v0.5.2/go.mod h1:ZWS5hhDbVDyob71nXKNL0+PWn6ToqBHMikGIFbs31qQ= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= github.com/gabriel-vasile/mimetype v1.4.9 h1:5k+WDwEsD9eTLL8Tz3L0VnmVh9QxGjRmjBvAG7U/oYY= github.com/gabriel-vasile/mimetype v1.4.9/go.mod h1:WnSQhFKJuBlRyLiKohA/2DtIlPFAbguNaG7QCHcyGok= +github.com/getkin/kin-openapi v0.118.0 h1:z43njxPmJ7TaPpMSCQb7PN0dEYno4tyBPQcrFdHoLuM= +github.com/getkin/kin-openapi v0.118.0/go.mod h1:l5e9PaFUo9fyLJCPGQeXI2ML8c3P8BHOEV2VaAVf/pc= +github.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ= +github.com/go-check/check v0.0.0-20180628173108-788fd7840127 h1:0gkP6mzaMqkmpcJYCFOLkIBwI7xFExG03bbkOkCvUPI= +github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-openapi/inflect v0.21.2 h1:0gClGlGcxifcJR56zwvhaOulnNgnhc4qTAkob5ObnSM= github.com/go-openapi/inflect v0.21.2/go.mod h1:INezMuUu7SJQc2AyR3WO0DqqYUJSj8Kb4hBd7WtjlAw= +github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY= +github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/swag v0.19.5 h1:lTz6Ys4CmqqCQmZPBlbQENR1/GucA2bzYTE12Pw4tFY= +github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= @@ -60,14 +97,16 @@ github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJn github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= github.com/go-playground/validator/v10 v10.27.0 h1:w8+XrWVMhGkxOaaowyKH35gFydVHOvC0/uWoy2Fzwn4= github.com/go-playground/validator/v10 v10.27.0/go.mod h1:I5QpIEbmr8On7W0TktmJAumgzX4CA1XNl4ZmDuVHKKo= -github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68= -github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= +github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM= +github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= github.com/go-viper/mapstructure/v2 v2.2.1 h1:ZAaOCxANMuZx5RCeg0mBdEZk7DZasvvZIxtHqx8aGss= github.com/go-viper/mapstructure/v2 v2.2.1/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= +github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang-migrate/migrate/v4 v4.18.3 h1:EYGkoOsvgHHfm5U/naS1RP/6PL/Xv3S4B/swMiAmDLs= github.com/golang-migrate/migrate/v4 v4.18.3/go.mod h1:99BKpIi6ruaaXRM1A77eqZ+FWPQ3cfRa+ZVy5bmWMaY= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= @@ -76,11 +115,17 @@ github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5a github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/wire v0.6.0 h1:HBkoIh4BdSxoyo9PveV8giw7ZsaBOvzWKfcg/6MrVwI= github.com/google/wire v0.6.0/go.mod h1:F4QhpQ9EDIdJ1Mbop/NZBRB+5yrR6qg3BnctaoUk6NA= +github.com/goph/emperror v0.17.2 h1:yLapQcmEsO0ipe9p5TaN22djm3OFV/TfM/fcYP0/J18= +github.com/goph/emperror v0.17.2/go.mod h1:+ZbQ+fUNO/6FNiUo0ujtMjhgad9Xa6fQL9KhH4LNHic= +github.com/gopherjs/gopherjs v1.17.2 h1:fQnZVsXk8uxXIStYb0N4bGk7jeyTalG/wsZjQ25dO0g= +github.com/gopherjs/gopherjs v1.17.2/go.mod h1:pRRIvn/QzFLrKfvEz3qUuEhtE/zLCWfreZ6J5gM2i+k= +github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -88,8 +133,26 @@ github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+l github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= github.com/hashicorp/hcl/v2 v2.23.0 h1:Fphj1/gCylPxHutVSEOf2fBOh1VE4AuLV7+kbJf3qos= github.com/hashicorp/hcl/v2 v2.23.0/go.mod h1:62ZYHrXgPoX8xBnzl8QzbWq4dyDsDtfCRgIq1rbJEvA= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/invopop/yaml v0.1.0 h1:YW3WGUoJEXYfzWBjn00zIlrw7brGVD0fUKRYDPAPhrc= +github.com/invopop/yaml v0.1.0/go.mod h1:2XuRLgs/ouIrW3XNzuNj7J3Nvu/Dig5MXvbCEdiBN3Q= +github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= +github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0/go.mod h1:1NbS8ALrpOvjt0rHPNLyCIeMtbizbir8U//inJ+zuB8= +github.com/klauspost/cpuid/v2 v2.0.9 h1:lgaqFMSdTdQYdZ04uHyN2d/eKdOMyi2YLSvlQIBFYa4= +github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= +github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/labstack/echo/v4 v4.13.4 h1:oTZZW+T3s9gAu5L8vmzihV7/lkXGZuITzTQkTEhcXEA= @@ -100,22 +163,42 @@ github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE= github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU= github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= +github.com/meguminnnnnnnnn/go-openai v0.0.0-20250620092828-0d508a1dcdde h1:pq2I0uxUR4lfr4OmqvE8QdHj9UML9b1jZu8L3dI2eu8= +github.com/meguminnnnnnnnn/go-openai v0.0.0-20250620092828-0d508a1dcdde/go.mod h1:CqSFsV6AkkL2fixd25WYjRAolns+gQrY1x/Cz9c30v8= +github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b h1:j7+1HpAFS1zy5+Q4qx1fWh90gTKwiN4QCGoY9TWyyO4= +github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0= github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0= github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0= github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo= github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0= github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= +github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= github.com/nicksnyder/go-i18n/v2 v2.6.0 h1:C/m2NNWNiTB6SK4Ao8df5EWm3JETSTIGNXBpMJTxzxQ= github.com/nicksnyder/go-i18n/v2 v2.6.0/go.mod h1:88sRqr0C6OPyJn0/KRNaEz1uWorjxIKP7rUUcvycecE= +github.com/nikolalohinski/gonja v1.5.3 h1:GsA+EEaZDZPGJ8JtpeGN78jidhOlxeJROpqMT9fTj9c= +github.com/nikolalohinski/gonja v1.5.3/go.mod h1:RmjwxNiXAEqcq1HeK5SSMmqFJvKOfTfXhkJv6YBtPa4= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug= @@ -124,6 +207,9 @@ github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaR github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ= github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4= github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY= +github.com/perimeterx/marshmallow v1.1.4 h1:pZLDH9RjlLGGorbXhcaQLhfuV0pFMNfPO55FuFkxqLw= +github.com/perimeterx/marshmallow v1.1.4/go.mod h1:dsXbUu8CRzfYP5a87xpp0xq9S3u0Vchtcl8we9tYaXw= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= @@ -134,10 +220,20 @@ github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0t github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= github.com/rokku-c/go-openai v1.35.7-fix2 h1:EfRf9p3TeEKc4J9Z9XjWkOYR6rb4dJGZtV05yJFArFI= github.com/rokku-c/go-openai v1.35.7-fix2/go.mod h1:cfP+tvFhvqlhYJHmkPz0PBbth2bSBratH6n0kQ4xKgQ= +github.com/rollbar/rollbar-go v1.0.2/go.mod h1:AcFs5f0I+c71bpHlXNNDbOWJiKwjFDtISeXco0L5PKQ= github.com/rs/xid v1.6.0 h1:fV591PaemRlL6JfRxGDEPl69wICngIQ3shQtzfy2gxU= github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0= github.com/sagikazarmark/locafero v0.9.0 h1:GbgQGNtTrEmddYDSAH9QLRyfAHY12md+8YFTqyMTC9k= github.com/sagikazarmark/locafero v0.9.0/go.mod h1:UBUyz37V+EdMS3hDF3QWIiVr/2dPrx49OMO0Bn0hJqk= +github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= +github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/slongfield/pyfmt v0.0.0-20220222012616-ea85ff4c361f h1:Z2cODYsUxQPofhpYRMQVwWz4yUVpHF+vPi+eUdruUYI= +github.com/slongfield/pyfmt v0.0.0-20220222012616-ea85ff4c361f/go.mod h1:JqzWyvTuI2X4+9wOHmKSQCYxybB/8j6Ko43qVmXDuZg= +github.com/smarty/assertions v1.15.0 h1:cR//PqUBUiQRakZWqBiFFQ9wb8emQGDb0HeGdqGByCY= +github.com/smarty/assertions v1.15.0/go.mod h1:yABtdzeQs6l1brC900WlRNwj6ZR55d7B+E8C6HtKdec= +github.com/smartystreets/goconvey v1.8.1 h1:qGjIddxOk4grTu9JPOU31tVfq3cNdBlNa5sSznIX1xY= +github.com/smartystreets/goconvey v1.8.1/go.mod h1:+/u4qLyY6x1jReYOp7GOM2FSt8aP9CzCZL03bI28W60= github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= github.com/spf13/afero v1.14.0 h1:9tH6MapGnn/j0eb0yIXiLjERO8RB6xIVZRDCX7PtqWA= @@ -148,14 +244,34 @@ github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o= github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.20.1 h1:ZMi+z/lvLyPSCoNtFCpqjy0S4kPbirhpTMwl8BkW9X4= github.com/spf13/viper v1.20.1/go.mod h1:P9Mdzt1zoHIG8m2eZQinpiBjo6kCmZSKBClNNqjJvu4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= +github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= +github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= +github.com/ugorji/go v1.2.7 h1:qYhyWUUd6WbiM+C6JZAUkIJt/1WrjzNHY9+KCIjVqTo= +github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M= +github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0= +github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo= github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= +github.com/x-cray/logrus-prefixed-formatter v0.5.2 h1:00txxvfBM9muc0jiLIEAkAcIMJzfthRT6usrui8uGmg= +github.com/x-cray/logrus-prefixed-formatter v0.5.2/go.mod h1:2duySbKsL6M18s5GU7VPsoEPHyzalCE06qoARUCeBBE= +github.com/yargevad/filepathx v1.0.0 h1:SYcT+N3tYGi+NvazubCNlvgIPbzAk7i7y2dwg3I5FYc= +github.com/yargevad/filepathx v1.0.0/go.mod h1:BprfX/gpYNJHJfc35GjRRpVcwWXS89gGulUIU5tK3tA= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/zclconf/go-cty v1.16.2 h1:LAJSwc3v81IRBZyUVQDUdZ7hs3SYs9jv0eZJDWHD/70= github.com/zclconf/go-cty v1.16.2/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE= @@ -177,18 +293,24 @@ go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +golang.org/x/arch v0.11.0 h1:KXV8WWKCXm6tRpLirl2szsO5j/oOODwZf4hATmGVNs4= +golang.org/x/arch v0.11.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= golang.org/x/crypto v0.39.0 h1:SHs+kF4LP+f+p14esP5jAoDpHU8Gu/v9lFRK6IT5imM= golang.org/x/crypto v0.39.0/go.mod h1:L+Xg3Wf6HoL4Bn4238Z6ft6KfEpN0tJGo53AAPC632U= +golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1 h1:MGwJjxBy0HJshjDNfLsYO8xppfqWlA5ZT9OhtUUhTNw= +golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/mod v0.25.0 h1:n7a+ZbQKQA/Ysbyb0/6IbB1H/X41mKgbhfv7AfG/44w= golang.org/x/mod v0.25.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= @@ -200,6 +322,7 @@ golang.org/x/net v0.41.0 h1:vBTly1HeNPEn3wtREYfy4GZ/NECgw2Cnl+nK6Nz3uvw= golang.org/x/net v0.41.0/go.mod h1:B/K4NNqkfmg07DQYrbwvSluqCJOOXwUjeb/5lOisjbA= golang.org/x/oauth2 v0.18.0 h1:09qnuIAgzdx1XplqJvW6CQqMCtGZykZWcXzPMPUusvI= golang.org/x/oauth2 v0.18.0/go.mod h1:Wf7knwG0MPoWIMMBgFlEaSUDaKskp0dCfrlJRJXbBi8= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -207,10 +330,13 @@ golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.15.0 h1:KWH3jNZsfyT6xfAfKiz6MRNmd46ByHDYaZ7KSkCtdW8= golang.org/x/sync v0.15.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -225,6 +351,8 @@ golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY= +golang.org/x/term v0.32.0 h1:DR4lr0TjUs3epypdhTOkMmuF5CDFJ/8pOnbzMZPQ7bg= +golang.org/x/term v0.32.0/go.mod h1:uZG1FhGx848Sqfsq4/DlJr3xGGsYMu/L5GW4abiaEPQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= @@ -254,7 +382,17 @@ google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQ google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50= diff --git a/backend/internal/model/handler/http/v1/model.go b/backend/internal/model/handler/http/v1/model.go index cfd929a..fb10a3b 100644 --- a/backend/internal/model/handler/http/v1/model.go +++ b/backend/internal/model/handler/http/v1/model.go @@ -30,6 +30,7 @@ func NewModelHandler( g.GET("", web.BaseHandler(m.List)) g.POST("", web.BindHandler(m.Create)) g.PUT("", web.BindHandler(m.Update)) + g.GET("/provider/supported", web.BindHandler(m.GetProviderModelList)) g.GET("/token-usage", web.BindHandler(m.GetTokenUsage)) g.GET("/my", web.BindHandler(m.MyModelList)) @@ -153,6 +154,25 @@ func (h *ModelHandler) GetTokenUsage(c *web.Context, req domain.GetTokenUsageReq return c.Success(resp) } +// GetProviderModelList 获取供应商支持的模型列表 +// +// @Tags Model +// @Summary 获取供应商支持的模型列表 +// @Description 获取供应商支持的模型列表 +// @ID get-provider-model-list +// @Accept json +// @Produce json +// @Param param query domain.GetProviderModelListReq true "模型类型" +// @Success 200 {object} web.Resp{data=domain.GetProviderModelListResp} +// @Router /api/v1/model/provider/supported [get] +func (h *ModelHandler) GetProviderModelList(c *web.Context, req domain.GetProviderModelListReq) error { + resp, err := h.usecase.GetProviderModelList(c.Request().Context(), &req) + if err != nil { + return err + } + return c.Success(resp) +} + func (h *ModelHandler) InitModel() error { return h.usecase.InitModel(context.Background()) } diff --git a/backend/internal/model/repo/model.go b/backend/internal/model/repo/model.go index faac2c9..7a5fee7 100644 --- a/backend/internal/model/repo/model.go +++ b/backend/internal/model/repo/model.go @@ -63,10 +63,13 @@ func (r *ModelRepo) Create(ctx context.Context, m *domain.CreateModelReq) (*db.M r.cache.Delete(string(m.ModelType)) return r.db.Model.Create(). SetUserID(uid). + SetShowName(m.ShowName). SetModelName(m.ModelName). SetProvider(m.Provider). SetAPIBase(m.APIBase). SetAPIKey(m.APIKey). + SetAPIVersion(m.APIVersion). + SetAPIHeader(m.APIHeader). SetModelType(m.ModelType). SetStatus(status). Save(ctx) @@ -201,7 +204,7 @@ func (r *ModelRepo) List(ctx context.Context) (*domain.AllModelResp, error) { Models: cvt.Iter(p.Edges.Models, func(_ int, m *db.ModelProviderModel) domain.ModelBasic { return domain.ModelBasic{ Name: m.Name, - Provider: p.Name, + Provider: consts.ModelProvider(p.Name), APIBase: p.APIBase, } }), @@ -214,7 +217,7 @@ func (r *ModelRepo) List(ctx context.Context) (*domain.AllModelResp, error) { func (r *ModelRepo) InitModel(ctx context.Context, modelName, modelKey, modelURL string) error { n, err := r.db.Model.Query(). Where(model.ModelName(modelName)). - Where(model.Provider("百智云")). + Where(model.Provider(consts.ModelProviderBaiZhiCloud)). Count(ctx) if err != nil { return err @@ -233,7 +236,7 @@ func (r *ModelRepo) InitModel(ctx context.Context, modelName, modelKey, modelURL SetModelName(modelName). SetModelType(consts.ModelTypeCoder). SetAPIBase(modelURL). - SetProvider("百智云"). + SetProvider(consts.ModelProviderBaiZhiCloud). SetStatus(consts.ModelStatusActive). SetUserID(a.ID). Exec(ctx) diff --git a/backend/internal/model/usecase/model.go b/backend/internal/model/usecase/model.go index 5ab9fab..50f5a7d 100644 --- a/backend/internal/model/usecase/model.go +++ b/backend/internal/model/usecase/model.go @@ -1,24 +1,35 @@ package usecase import ( + "bytes" "context" + "encoding/json" + "fmt" "log/slog" + "maps" + "net/http" + "net/url" + "path" + "time" + "github.com/cloudwego/eino-ext/components/model/openai" + "github.com/cloudwego/eino/schema" "github.com/google/uuid" "github.com/chaitin/MonkeyCode/backend/config" - "github.com/chaitin/MonkeyCode/backend/db/model" - "github.com/chaitin/MonkeyCode/backend/pkg/cvt" - "github.com/chaitin/MonkeyCode/backend/consts" "github.com/chaitin/MonkeyCode/backend/db" + "github.com/chaitin/MonkeyCode/backend/db/model" "github.com/chaitin/MonkeyCode/backend/domain" + "github.com/chaitin/MonkeyCode/backend/pkg/cvt" + "github.com/chaitin/MonkeyCode/backend/pkg/request" ) type ModelUsecase struct { logger *slog.Logger repo domain.ModelRepo cfg *config.Config + client *http.Client } func NewModelUsecase( @@ -26,11 +37,131 @@ func NewModelUsecase( repo domain.ModelRepo, cfg *config.Config, ) domain.ModelUsecase { - return &ModelUsecase{repo: repo, cfg: cfg, logger: logger} + client := &http.Client{ + Timeout: time.Second * 30, + Transport: &http.Transport{ + MaxIdleConns: 100, + MaxIdleConnsPerHost: 100, + MaxConnsPerHost: 100, + IdleConnTimeout: time.Second * 30, + }, + } + return &ModelUsecase{repo: repo, cfg: cfg, logger: logger, client: client} } func (m *ModelUsecase) Check(ctx context.Context, req *domain.CheckModelReq) (*domain.Model, error) { - return nil, nil + if req.Type == consts.ModelTypeEmbedding || req.Type == consts.ModelTypeReranker { + url := req.APIBase + reqBody := map[string]any{} + if req.Type == consts.ModelTypeEmbedding { + reqBody = map[string]any{ + "model": req.ModelName, + "input": "MonkeyCode 是一个基于大模型的代码生成器,它可以根据用户的需求生成代码。", + "encoding_format": "float", + } + url = req.APIBase + "/embeddings" + } + if req.Type == consts.ModelTypeReranker { + reqBody = map[string]any{ + "model": req.ModelName, + "documents": []string{ + "MonkeyCode 是一个基于大模型的代码生成器,它可以根据用户的需求生成代码。", + "MonkeyCode 是一个基于大模型的代码生成器,它可以根据用户的需求生成代码。", + "MonkeyCode 是一个基于大模型的代码生成器,它可以根据用户的需求生成代码。", + }, + "query": "PandaWiki", + } + url = req.APIBase + "/rerank" + } + body, err := json.Marshal(reqBody) + if err != nil { + return nil, err + } + request, err := http.NewRequestWithContext(ctx, http.MethodPost, url, bytes.NewBuffer(body)) + if err != nil { + return nil, err + } + request.Header.Set("Authorization", fmt.Sprintf("Bearer %s", req.APIKey)) + request.Header.Set("Content-Type", "application/json") + resp, err := http.DefaultClient.Do(request) + if err != nil { + return nil, err + } + defer resp.Body.Close() + if resp.StatusCode != http.StatusOK { + return nil, fmt.Errorf("request failed: %s", resp.Status) + } + return &domain.Model{}, nil + } + config := &openai.ChatModelConfig{ + APIKey: req.APIKey, + BaseURL: req.APIBase, + Model: string(req.ModelName), + } + // for azure openai + if req.Provider == consts.ModelProviderAzureOpenAI { + config.ByAzure = true + config.APIVersion = req.APIVersion + if config.APIVersion == "" { + config.APIVersion = "2024-10-21" + } + } + if req.APIHeader != "" { + client := getHttpClientWithAPIHeaderMap(req.APIHeader) + if client != nil { + config.HTTPClient = client + } + } + chatModel, err := openai.NewChatModel(ctx, config) + if err != nil { + return nil, err + } + resp, err := chatModel.Generate(ctx, []*schema.Message{ + schema.SystemMessage("You are a helpful assistant."), + schema.UserMessage("hi"), + }) + if err != nil { + return nil, err + } + content := resp.Content + if content == "" { + return nil, fmt.Errorf("generate failed") + } + return &domain.Model{ + ModelType: req.Type, + Provider: req.Provider, + ModelName: req.ModelName, + APIBase: req.APIBase, + }, nil +} + +type headerTransport struct { + headers map[string]string + base http.RoundTripper +} + +func (t *headerTransport) RoundTrip(req *http.Request) (*http.Response, error) { + for k, v := range t.headers { + req.Header.Set(k, v) + } + return t.base.RoundTrip(req) +} + +func getHttpClientWithAPIHeaderMap(header string) *http.Client { + headerMap := request.GetHeaderMap(header) + if len(headerMap) > 0 { + // create http client with custom transport for headers + client := &http.Client{ + Timeout: 0, + } + // Wrap the transport to add headers + client.Transport = &headerTransport{ + headers: headerMap, + base: http.DefaultTransport, + } + return client + } + return nil } func (m *ModelUsecase) MyModelList(ctx context.Context, req *domain.MyModelListReq) ([]*domain.Model, error) { @@ -88,6 +219,12 @@ func (m *ModelUsecase) Update(ctx context.Context, req *domain.UpdateModelReq) ( if req.APIKey != nil { up.SetAPIKey(*req.APIKey) } + if req.APIVersion != nil { + up.SetAPIVersion(*req.APIVersion) + } + if req.APIHeader != nil { + up.SetAPIHeader(*req.APIHeader) + } if req.Status != nil { if *req.Status == consts.ModelStatusActive { if err := tx.Model.Update(). @@ -114,3 +251,105 @@ func (m *ModelUsecase) InitModel(ctx context.Context) error { } return m.repo.InitModel(ctx, m.cfg.InitModel.Name, m.cfg.InitModel.Key, m.cfg.InitModel.URL) } + +func (m *ModelUsecase) GetProviderModelList(ctx context.Context, req *domain.GetProviderModelListReq) (*domain.GetProviderModelListResp, error) { + switch req.Provider { + case consts.ModelProviderMoonshot, + consts.ModelProviderDeepSeek, + consts.ModelProviderAzureOpenAI, + consts.ModelProviderVolcengine: + return &domain.GetProviderModelListResp{ + Models: domain.ModelProviderBrandModelsList[req.Provider], + }, nil + case consts.ModelProviderOpenAI, + consts.ModelProviderHunyuan, + consts.ModelProviderBaiLian: + u, err := url.Parse(req.BaseURL) + if err != nil { + return nil, err + } + u.Path = path.Join(u.Path, "/models") + client := request.NewClient(u.Scheme, u.Host, m.client.Timeout, request.WithClient(m.client)) + resp, err := request.Get[domain.OpenAIResp](client, u.Path, request.WithHeader( + request.Header{ + "Authorization": fmt.Sprintf("Bearer %s", req.APIKey), + }, + )) + if err != nil { + return nil, err + } + + return &domain.GetProviderModelListResp{ + Models: cvt.Iter(resp.Data, func(_ int, e *domain.OpenAIData) domain.ProviderModelListItem { + return domain.ProviderModelListItem{ + Model: e.ID, + } + }), + }, nil + case consts.ModelProviderOllama: + // get from ollama http://10.10.16.24:11434/api/tags + u, err := url.Parse(req.BaseURL) + if err != nil { + return nil, err + } + u.Path = "/api/tags" + client := request.NewClient(u.Scheme, u.Host, m.client.Timeout, request.WithClient(m.client)) + + h := request.Header{} + if req.APIHeader != "" { + headers := request.GetHeaderMap(req.APIHeader) + maps.Copy(h, headers) + } + + return request.Get[domain.GetProviderModelListResp](client, u.Path, request.WithHeader(h)) + + case consts.ModelProviderSiliconFlow, consts.ModelProviderBaiZhiCloud: + if req.Type == consts.ModelTypeEmbedding || req.Type == consts.ModelTypeReranker { + if req.Provider == consts.ModelProviderBaiZhiCloud { + if req.Type == consts.ModelTypeEmbedding { + return &domain.GetProviderModelListResp{ + Models: []domain.ProviderModelListItem{ + { + Model: "bge-m3", + }, + }, + }, nil + } else { + return &domain.GetProviderModelListResp{ + Models: []domain.ProviderModelListItem{ + { + Model: "bge-reranker-v2-m3", + }, + }, + }, nil + } + } + } + u, err := url.Parse(req.BaseURL) + if err != nil { + return nil, err + } + client := request.NewClient(u.Scheme, u.Host, m.client.Timeout, request.WithClient(m.client)) + resp, err := request.Get[domain.OpenAIResp](client, "/v1/models", request.WithHeader( + request.Header{ + "Authorization": fmt.Sprintf("Bearer %s", req.APIKey), + }, + ), request.WithQuery(request.Query{ + "type": "text", + "sub_type": "chat", + })) + if err != nil { + return nil, err + } + + return &domain.GetProviderModelListResp{ + Models: cvt.Iter(resp.Data, func(_ int, e *domain.OpenAIData) domain.ProviderModelListItem { + return domain.ProviderModelListItem{ + Model: e.ID, + } + }), + }, nil + default: + return nil, fmt.Errorf("invalid provider: %s", req.Provider) + } +} diff --git a/backend/migration/000007_alter_model_table.down.sql b/backend/migration/000007_alter_model_table.down.sql new file mode 100644 index 0000000..e69de29 diff --git a/backend/migration/000007_alter_model_table.up.sql b/backend/migration/000007_alter_model_table.up.sql new file mode 100644 index 0000000..d32442f --- /dev/null +++ b/backend/migration/000007_alter_model_table.up.sql @@ -0,0 +1,3 @@ +ALTER TABLE models ADD COLUMN IF NOT EXISTS show_name VARCHAR(255); +ALTER TABLE models ADD COLUMN IF NOT EXISTS api_version VARCHAR(255); +ALTER TABLE models ADD COLUMN IF NOT EXISTS api_header TEXT; diff --git a/backend/pkg/request/request.go b/backend/pkg/request/request.go index b3711a7..7ed6a49 100644 --- a/backend/pkg/request/request.go +++ b/backend/pkg/request/request.go @@ -185,3 +185,13 @@ func Put[T any](c *Client, path string, body any, opts ...Opt) (*T, error) { func Delete[T any](c *Client, path string, opts ...Opt) (*T, error) { return sendRequest[T](c, http.MethodDelete, path, opts...) } + +func GetHeaderMap(header string) map[string]string { + headerMap := make(map[string]string) + for _, h := range strings.Split(header, "\n") { + if key, value, ok := strings.Cut(h, "="); ok { + headerMap[key] = value + } + } + return headerMap +}