Skip to content

Commit 88cb54a

Browse files
authored
feat: web mcp (#241)
* feat: add mcp pannel * fix: log detail * feat: channel sets support * feat: model set * fix: pnpm version * fix: build web
1 parent aad7f78 commit 88cb54a

49 files changed

Lines changed: 8260 additions & 1947 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

core/controller/group.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -417,6 +417,12 @@ type SaveGroupModelConfigRequest struct {
417417
OverridePrice bool `json:"override_price"`
418418
ImagePrices map[string]float64 `json:"image_prices"`
419419
Price model.Price `json:"price"`
420+
421+
OverrideRetryTimes bool `json:"override_retry_times"`
422+
RetryTimes int64 `json:"retry_times"`
423+
424+
OverrideForceSaveDetail bool `json:"override_force_save_detail"`
425+
ForceSaveDetail bool `json:"force_save_detail"`
420426
}
421427

422428
func (r *SaveGroupModelConfigRequest) ToGroupModelConfig(groupID string) model.GroupModelConfig {
@@ -431,6 +437,12 @@ func (r *SaveGroupModelConfigRequest) ToGroupModelConfig(groupID string) model.G
431437
OverridePrice: r.OverridePrice,
432438
ImagePrices: r.ImagePrices,
433439
Price: r.Price,
440+
441+
OverrideRetryTimes: r.OverrideRetryTimes,
442+
RetryTimes: r.RetryTimes,
443+
444+
OverrideForceSaveDetail: r.OverrideForceSaveDetail,
445+
ForceSaveDetail: r.ForceSaveDetail,
434446
}
435447
}
436448

core/controller/model.go

Lines changed: 16 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -258,57 +258,38 @@ func newEnabledModelChannel(ch *model.Channel) EnabledModelChannel {
258258
}
259259
}
260260

261-
// EnabledModelChannels godoc
261+
// EnabledModelSets godoc
262262
//
263-
// @Summary Get enabled models and channels
264-
// @Description Returns a list of enabled models
263+
// @Summary Get enabled models and channels sets
264+
// @Description Returns a list of enabled models and channels sets
265265
// @Tags model
266266
// @Produce json
267267
// @Security ApiKeyAuth
268268
// @Success 200 {object} middleware.APIResponse{data=map[string]map[string][]EnabledModelChannel}
269-
// @Router /api/models/channel [get]
270-
func EnabledModelChannels(c *gin.Context) {
269+
// @Router /api/models/sets [get]
270+
func EnabledModelSets(c *gin.Context) {
271271
raw := model.LoadModelCaches().EnabledModel2ChannelsBySet
272272
result := make(map[string]map[string][]EnabledModelChannel)
273273

274+
// First iterate through sets to get all models
275+
for _, modelChannels := range raw {
276+
for model := range modelChannels {
277+
if _, exists := result[model]; !exists {
278+
result[model] = make(map[string][]EnabledModelChannel)
279+
}
280+
}
281+
}
282+
283+
// Then populate the channels for each model and set
274284
for set, modelChannels := range raw {
275-
result[set] = make(map[string][]EnabledModelChannel)
276285
for model, channels := range modelChannels {
277286
chs := make([]EnabledModelChannel, len(channels))
278287
for i, channel := range channels {
279288
chs[i] = newEnabledModelChannel(channel)
280289
}
281-
result[set][model] = chs
290+
result[model][set] = chs
282291
}
283292
}
284293

285294
middleware.SuccessResponse(c, result)
286295
}
287-
288-
// EnabledModelChannelsSet godoc
289-
//
290-
// @Summary Get enabled models and channels by set
291-
// @Description Returns a list of enabled models and channels by set
292-
// @Tags model
293-
// @Produce json
294-
// @Security ApiKeyAuth
295-
// @Param set path string true "Models set"
296-
// @Success 200 {object} middleware.APIResponse{data=map[string][]EnabledModelChannel}
297-
// @Router /api/models/channel/{set} [get]
298-
func EnabledModelChannelsSet(c *gin.Context) {
299-
set := c.Param("set")
300-
if set == "" {
301-
middleware.ErrorResponse(c, http.StatusBadRequest, "set is required")
302-
return
303-
}
304-
raw := model.LoadModelCaches().EnabledModel2ChannelsBySet[set]
305-
result := make(map[string][]EnabledModelChannel, len(raw))
306-
for model, channels := range raw {
307-
chs := make([]EnabledModelChannel, len(channels))
308-
for i, channel := range channels {
309-
chs[i] = newEnabledModelChannel(channel)
310-
}
311-
result[model] = chs
312-
}
313-
middleware.SuccessResponse(c, result)
314-
}

core/controller/modelconfig.go

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -116,11 +116,7 @@ func SearchModelConfigs(c *gin.Context) {
116116
})
117117
}
118118

119-
type SaveModelConfigsRequest struct {
120-
CreatedAt int64 `json:"created_at"`
121-
UpdatedAt int64 `json:"updated_at"`
122-
model.ModelConfig
123-
}
119+
type SaveModelConfigsRequest = model.ModelConfig
124120

125121
// SaveModelConfigs godoc
126122
//
@@ -138,11 +134,7 @@ func SaveModelConfigs(c *gin.Context) {
138134
middleware.ErrorResponse(c, http.StatusBadRequest, err.Error())
139135
return
140136
}
141-
modelConfigs := make([]model.ModelConfig, len(configs))
142-
for i, config := range configs {
143-
modelConfigs[i] = config.ModelConfig
144-
}
145-
err := model.SaveModelConfigs(modelConfigs)
137+
err := model.SaveModelConfigs(configs)
146138
if err != nil {
147139
middleware.ErrorResponse(c, http.StatusInternalServerError, err.Error())
148140
return
@@ -166,7 +158,7 @@ func SaveModelConfig(c *gin.Context) {
166158
middleware.ErrorResponse(c, http.StatusBadRequest, err.Error())
167159
return
168160
}
169-
err := model.SaveModelConfig(config.ModelConfig)
161+
err := model.SaveModelConfig(config)
170162
if err != nil {
171163
middleware.ErrorResponse(c, http.StatusInternalServerError, err.Error())
172164
return

core/controller/relay-controller.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -280,9 +280,7 @@ func recordResult(
280280

281281
var detail *model.RequestDetail
282282
firstByteAt := result.Detail.FirstByteAt
283-
if code == http.StatusOK && !config.GetSaveAllLogDetail() {
284-
detail = nil
285-
} else {
283+
if config.GetSaveAllLogDetail() || meta.ModelConfig.ForceSaveDetail || code != http.StatusOK {
286284
detail = &model.RequestDetail{
287285
RequestBody: result.Detail.RequestBody,
288286
ResponseBody: result.Detail.ResponseBody,

core/docs/docs.go

Lines changed: 73 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -4586,104 +4586,6 @@ const docTemplate = `{
45864586
}
45874587
}
45884588
},
4589-
"/api/models/channel": {
4590-
"get": {
4591-
"security": [
4592-
{
4593-
"ApiKeyAuth": []
4594-
}
4595-
],
4596-
"description": "Returns a list of enabled models",
4597-
"produces": [
4598-
"application/json"
4599-
],
4600-
"tags": [
4601-
"model"
4602-
],
4603-
"summary": "Get enabled models and channels",
4604-
"responses": {
4605-
"200": {
4606-
"description": "OK",
4607-
"schema": {
4608-
"allOf": [
4609-
{
4610-
"$ref": "#/definitions/middleware.APIResponse"
4611-
},
4612-
{
4613-
"type": "object",
4614-
"properties": {
4615-
"data": {
4616-
"type": "object",
4617-
"additionalProperties": {
4618-
"type": "object",
4619-
"additionalProperties": {
4620-
"type": "array",
4621-
"items": {
4622-
"$ref": "#/definitions/controller.EnabledModelChannel"
4623-
}
4624-
}
4625-
}
4626-
}
4627-
}
4628-
}
4629-
]
4630-
}
4631-
}
4632-
}
4633-
}
4634-
},
4635-
"/api/models/channel/{set}": {
4636-
"get": {
4637-
"security": [
4638-
{
4639-
"ApiKeyAuth": []
4640-
}
4641-
],
4642-
"description": "Returns a list of enabled models and channels by set",
4643-
"produces": [
4644-
"application/json"
4645-
],
4646-
"tags": [
4647-
"model"
4648-
],
4649-
"summary": "Get enabled models and channels by set",
4650-
"parameters": [
4651-
{
4652-
"type": "string",
4653-
"description": "Models set",
4654-
"name": "set",
4655-
"in": "path",
4656-
"required": true
4657-
}
4658-
],
4659-
"responses": {
4660-
"200": {
4661-
"description": "OK",
4662-
"schema": {
4663-
"allOf": [
4664-
{
4665-
"$ref": "#/definitions/middleware.APIResponse"
4666-
},
4667-
{
4668-
"type": "object",
4669-
"properties": {
4670-
"data": {
4671-
"type": "object",
4672-
"additionalProperties": {
4673-
"type": "array",
4674-
"items": {
4675-
"$ref": "#/definitions/controller.EnabledModelChannel"
4676-
}
4677-
}
4678-
}
4679-
}
4680-
}
4681-
]
4682-
}
4683-
}
4684-
}
4685-
}
4686-
},
46874589
"/api/models/default": {
46884590
"get": {
46894591
"security": [
@@ -4903,6 +4805,52 @@ const docTemplate = `{
49034805
}
49044806
}
49054807
},
4808+
"/api/models/sets": {
4809+
"get": {
4810+
"security": [
4811+
{
4812+
"ApiKeyAuth": []
4813+
}
4814+
],
4815+
"description": "Returns a list of enabled models and channels sets",
4816+
"produces": [
4817+
"application/json"
4818+
],
4819+
"tags": [
4820+
"model"
4821+
],
4822+
"summary": "Get enabled models and channels sets",
4823+
"responses": {
4824+
"200": {
4825+
"description": "OK",
4826+
"schema": {
4827+
"allOf": [
4828+
{
4829+
"$ref": "#/definitions/middleware.APIResponse"
4830+
},
4831+
{
4832+
"type": "object",
4833+
"properties": {
4834+
"data": {
4835+
"type": "object",
4836+
"additionalProperties": {
4837+
"type": "object",
4838+
"additionalProperties": {
4839+
"type": "array",
4840+
"items": {
4841+
"$ref": "#/definitions/controller.EnabledModelChannel"
4842+
}
4843+
}
4844+
}
4845+
}
4846+
}
4847+
}
4848+
]
4849+
}
4850+
}
4851+
}
4852+
}
4853+
},
49064854
"/api/monitor/": {
49074855
"get": {
49084856
"security": [
@@ -8091,6 +8039,9 @@ const docTemplate = `{
80918039
"exclude_from_tests": {
80928040
"type": "boolean"
80938041
},
8042+
"force_save_detail": {
8043+
"type": "boolean"
8044+
},
80948045
"image_prices": {
80958046
"description": "map[size]price_per_image",
80968047
"type": "object",
@@ -8490,6 +8441,9 @@ const docTemplate = `{
84908441
"controller.SaveGroupModelConfigRequest": {
84918442
"type": "object",
84928443
"properties": {
8444+
"force_save_detail": {
8445+
"type": "boolean"
8446+
},
84938447
"image_prices": {
84948448
"type": "object",
84958449
"additionalProperties": {
@@ -8499,15 +8453,24 @@ const docTemplate = `{
84998453
"model": {
85008454
"type": "string"
85018455
},
8456+
"override_force_save_detail": {
8457+
"type": "boolean"
8458+
},
85028459
"override_limit": {
85038460
"type": "boolean"
85048461
},
85058462
"override_price": {
85068463
"type": "boolean"
85078464
},
8465+
"override_retry_times": {
8466+
"type": "boolean"
8467+
},
85088468
"price": {
85098469
"$ref": "#/definitions/model.Price"
85108470
},
8471+
"retry_times": {
8472+
"type": "integer"
8473+
},
85118474
"rpm": {
85128475
"type": "integer"
85138476
},
@@ -8529,6 +8492,9 @@ const docTemplate = `{
85298492
"exclude_from_tests": {
85308493
"type": "boolean"
85318494
},
8495+
"force_save_detail": {
8496+
"type": "boolean"
8497+
},
85328498
"image_prices": {
85338499
"description": "map[size]price_per_image",
85348500
"type": "object",
@@ -9604,6 +9570,9 @@ const docTemplate = `{
96049570
"model.GroupModelConfig": {
96059571
"type": "object",
96069572
"properties": {
9573+
"force_save_detail": {
9574+
"type": "boolean"
9575+
},
96079576
"group_id": {
96089577
"type": "string"
96099578
},
@@ -9616,6 +9585,9 @@ const docTemplate = `{
96169585
"model": {
96179586
"type": "string"
96189587
},
9588+
"override_force_save_detail": {
9589+
"type": "boolean"
9590+
},
96199591
"override_limit": {
96209592
"type": "boolean"
96219593
},
@@ -9957,6 +9929,9 @@ const docTemplate = `{
99579929
"exclude_from_tests": {
99589930
"type": "boolean"
99599931
},
9932+
"force_save_detail": {
9933+
"type": "boolean"
9934+
},
99609935
"image_prices": {
99619936
"description": "map[size]price_per_image",
99629937
"type": "object",

0 commit comments

Comments
 (0)