fix(plugin): update tool may reset request or response parameters (#302)

main
mrh997 3 months ago committed by GitHub
parent e3930873c6
commit efa20f22f6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 17
      backend/application/base/pluginutil/api.go
  2. 2
      backend/application/plugin/plugin.go
  3. 13
      backend/domain/plugin/internal/dal/plugin_draft.go
  4. 8
      backend/domain/plugin/repository/plugin_impl.go
  5. 1
      backend/domain/plugin/repository/plugin_repository.go
  6. 39
      backend/domain/plugin/repository/tool_impl.go
  7. 3
      backend/domain/plugin/repository/tool_repository.go
  8. 51
      backend/domain/plugin/service/plugin_draft.go
  9. 4
      backend/domain/plugin/service/service.go
  10. 2
      backend/internal/mock/domain/plugin/interface.go

@ -88,6 +88,15 @@ func APIParamsToOpenapiOperation(reqParams, respParams []*common.APIParameter) (
}
}
if reqParams != nil {
if !hasSetParams {
op.Parameters = []*openapi3.ParameterRef{}
}
if !hasSetReqBody {
op.RequestBody = entity.DefaultOpenapi3RequestBody()
}
}
hasSetRespBody := false
for _, apiParam := range respParams {
@ -127,13 +136,7 @@ func APIParamsToOpenapiOperation(reqParams, respParams []*common.APIParameter) (
}
}
if op.Parameters == nil {
op.Parameters = []*openapi3.ParameterRef{}
}
if op.RequestBody == nil {
op.RequestBody = entity.DefaultOpenapi3RequestBody()
}
if op.Responses == nil {
if respParams != nil && !hasSetRespBody {
op.Responses = entity.DefaultOpenapi3Responses()
}

@ -822,7 +822,7 @@ func (p *PluginApplicationService) UpdateAPI(ctx context.Context, req *pluginAPI
method = &m
}
updateReq := &service.UpdateToolDraftRequest{
updateReq := &service.UpdateDraftToolRequest{
PluginID: req.PluginID,
ToolID: req.APIID,
Name: req.Name,

@ -25,7 +25,7 @@ import (
"gorm.io/gen/field"
"gorm.io/gorm"
"github.com/coze-dev/coze-studio/backend/api/model/crossdomain/plugin"
pluginModel "github.com/coze-dev/coze-studio/backend/api/model/crossdomain/plugin"
"github.com/coze-dev/coze-studio/backend/api/model/plugin_develop_common"
"github.com/coze-dev/coze-studio/backend/domain/plugin/conf"
"github.com/coze-dev/coze-studio/backend/domain/plugin/entity"
@ -50,7 +50,7 @@ type PluginDraftDAO struct {
type pluginDraftPO model.PluginDraft
func (p pluginDraftPO) ToDO() *entity.PluginInfo {
return entity.NewPluginInfo(&plugin.PluginInfo{
return entity.NewPluginInfo(&pluginModel.PluginInfo{
ID: p.ID,
SpaceID: p.SpaceID,
DeveloperID: p.DeveloperID,
@ -257,9 +257,12 @@ func (p *PluginDraftDAO) List(ctx context.Context, spaceID, appID int64, pageInf
}
func (p *PluginDraftDAO) Update(ctx context.Context, plugin *entity.PluginInfo) (err error) {
mf, err := plugin.Manifest.EncryptAuthPayload()
if err != nil {
return fmt.Errorf("EncryptAuthPayload failed, err=%w", err)
var mf *pluginModel.PluginManifest
if plugin.Manifest != nil {
mf, err = plugin.Manifest.EncryptAuthPayload()
if err != nil {
return fmt.Errorf("EncryptAuthPayload failed, err=%w", err)
}
}
m := &model.PluginDraft{

@ -853,3 +853,11 @@ func (p *pluginRepoImpl) MoveAPPPluginToLibrary(ctx context.Context, draftPlugin
return nil
}
func (p *pluginRepoImpl) UpdateDebugExample(ctx context.Context, pluginID int64, openapiDoc *model.Openapi3T) (err error) {
updatedPlugin := entity.NewPluginInfo(&model.PluginInfo{
ID: pluginID,
OpenapiDoc: openapiDoc,
})
return p.pluginDraftDAO.Update(ctx, updatedPlugin)
}

@ -35,6 +35,7 @@ type PluginRepository interface {
UpdateDraftPluginWithCode(ctx context.Context, req *UpdatePluginDraftWithCode) (err error)
DeleteDraftPlugin(ctx context.Context, pluginID int64) (err error)
DeleteAPPAllPlugins(ctx context.Context, appID int64) (pluginIDs []int64, err error)
UpdateDebugExample(ctx context.Context, pluginID int64, openapiDoc *plugin.Openapi3T) (err error)
GetOnlinePlugin(ctx context.Context, pluginID int64, opts ...PluginSelectedOptions) (plugin *entity.PluginInfo, exist bool, err error)
MGetOnlinePlugins(ctx context.Context, pluginIDs []int64, opts ...PluginSelectedOptions) (plugins []*entity.PluginInfo, err error)

@ -23,7 +23,6 @@ import (
"gorm.io/gorm"
"github.com/coze-dev/coze-studio/backend/api/model/crossdomain/plugin"
pluginConf "github.com/coze-dev/coze-studio/backend/domain/plugin/conf"
"github.com/coze-dev/coze-studio/backend/domain/plugin/entity"
"github.com/coze-dev/coze-studio/backend/domain/plugin/internal/dal"
@ -389,41 +388,3 @@ func (t *toolRepoImpl) MGetVersionAgentTool(ctx context.Context, agentID int64,
func (t *toolRepoImpl) BatchCreateVersionAgentTools(ctx context.Context, agentID int64, agentVersion string, tools []*entity.ToolInfo) (err error) {
return t.agentToolVersionDAO.BatchCreate(ctx, agentID, agentVersion, tools)
}
func (t *toolRepoImpl) UpdateDraftToolAndDebugExample(ctx context.Context, pluginID int64, doc *plugin.Openapi3T, updatedTool *entity.ToolInfo) (err error) {
tx := t.query.Begin()
if tx.Error != nil {
return tx.Error
}
defer func() {
if r := recover(); r != nil {
if e := tx.Rollback(); e != nil {
logs.CtxErrorf(ctx, "rollback failed, err=%v", e)
}
err = fmt.Errorf("catch panic: %v\nstack=%s", r, string(debug.Stack()))
return
}
if err != nil {
if e := tx.Rollback(); e != nil {
logs.CtxErrorf(ctx, "rollback failed, err=%v", e)
}
}
}()
err = t.toolDraftDAO.UpdateWithTX(ctx, tx, updatedTool)
if err != nil {
return err
}
updatedPlugin := entity.NewPluginInfo(&plugin.PluginInfo{
ID: pluginID,
OpenapiDoc: doc,
})
err = t.pluginDraftDAO.UpdateWithTX(ctx, tx, updatedPlugin)
if err != nil {
return err
}
return tx.Commit()
}

@ -19,7 +19,6 @@ package repository
import (
"context"
"github.com/coze-dev/coze-studio/backend/api/model/crossdomain/plugin"
"github.com/coze-dev/coze-studio/backend/domain/plugin/entity"
)
@ -54,8 +53,6 @@ type ToolRepository interface {
MGetVersionAgentTool(ctx context.Context, agentID int64, vAgentTools []entity.VersionAgentTool) (tools []*entity.ToolInfo, err error)
BatchCreateVersionAgentTools(ctx context.Context, agentID int64, agentVersion string, tools []*entity.ToolInfo) (err error)
UpdateDraftToolAndDebugExample(ctx context.Context, pluginID int64, doc *plugin.Openapi3T, updatedTool *entity.ToolInfo) (err error)
GetPluginAllDraftTools(ctx context.Context, pluginID int64, opts ...ToolSelectedOptions) (tools []*entity.ToolInfo, err error)
GetPluginAllOnlineTools(ctx context.Context, pluginID int64) (tools []*entity.ToolInfo, err error)
ListPluginDraftTools(ctx context.Context, pluginID int64, pageInfo entity.PageInfo) (tools []*entity.ToolInfo, total int64, err error)

@ -578,7 +578,7 @@ func (p *pluginServiceImpl) MGetDraftTools(ctx context.Context, toolIDs []int64)
return tools, nil
}
func (p *pluginServiceImpl) UpdateDraftTool(ctx context.Context, req *UpdateToolDraftRequest) (err error) {
func (p *pluginServiceImpl) UpdateDraftTool(ctx context.Context, req *UpdateDraftToolRequest) (err error) {
draftPlugin, exist, err := p.pluginRepo.GetDraftPlugin(ctx, req.PluginID)
if err != nil {
return errorx.Wrapf(err, "GetDraftPlugin failed, pluginID=%d", req.PluginID)
@ -595,6 +595,14 @@ func (p *pluginServiceImpl) UpdateDraftTool(ctx context.Context, req *UpdateTool
return errorx.New(errno.ErrPluginRecordNotFound)
}
if req.SaveExample != nil {
return p.updateDraftToolDebugExample(ctx, draftPlugin, draftTool, *req.SaveExample, req.DebugExample)
}
return p.updateDraftTool(ctx, req, draftTool)
}
func (p *pluginServiceImpl) updateDraftTool(ctx context.Context, req *UpdateDraftToolRequest, draftTool *entity.ToolInfo) (err error) {
if req.Method != nil && req.SubURL != nil {
api := entity.UniqueToolAPI{
SubURL: ptr.FromOrDefault(req.SubURL, ""),
@ -634,9 +642,6 @@ func (p *pluginServiceImpl) UpdateDraftTool(ctx context.Context, req *UpdateTool
if req.Desc != nil {
op.Summary = *req.Desc
}
if req.Parameters != nil {
op.Parameters = req.Parameters
}
if req.APIExtend != nil {
if op.Extensions == nil {
op.Extensions = map[string]any{}
@ -647,6 +652,12 @@ func (p *pluginServiceImpl) UpdateDraftTool(ctx context.Context, req *UpdateTool
}
}
// update request parameters
if req.Parameters != nil {
op.Parameters = req.Parameters
}
// update request body
if req.RequestBody == nil {
op.RequestBody = draftTool.Operation.RequestBody
} else {
@ -664,6 +675,7 @@ func (p *pluginServiceImpl) UpdateDraftTool(ctx context.Context, req *UpdateTool
op.RequestBody.Value.Content[model.MediaTypeJson] = mType
}
// update responses
if req.Responses == nil {
op.Responses = draftTool.Operation.Responses
} else {
@ -707,11 +719,24 @@ func (p *pluginServiceImpl) UpdateDraftTool(ctx context.Context, req *UpdateTool
Operation: op,
}
err = p.toolRepo.UpdateDraftTool(ctx, updatedTool)
if err != nil {
return errorx.Wrapf(err, "UpdateDraftTool failed, toolID=%d", req.ToolID)
}
return nil
}
func (p *pluginServiceImpl) updateDraftToolDebugExample(ctx context.Context, draftPlugin *entity.PluginInfo,
draftTool *entity.ToolInfo, save bool, example *common.DebugExample) (err error) {
components := draftPlugin.OpenapiDoc.Components
if req.SaveExample != nil && !*req.SaveExample &&
components != nil && components.Examples != nil {
if !save && components != nil && components.Examples != nil {
delete(components.Examples, draftTool.Operation.OperationID)
} else if req.DebugExample != nil {
}
if save {
if components == nil {
components = &openapi3.Components{}
}
@ -722,14 +747,14 @@ func (p *pluginServiceImpl) UpdateDraftTool(ctx context.Context, req *UpdateTool
draftPlugin.OpenapiDoc.Components = components
reqExample, respExample := map[string]any{}, map[string]any{}
if req.DebugExample.ReqExample != "" {
err = sonic.UnmarshalString(req.DebugExample.ReqExample, &reqExample)
if example.ReqExample != "" {
err = sonic.UnmarshalString(example.ReqExample, &reqExample)
if err != nil {
return errorx.WrapByCode(err, errno.ErrPluginInvalidOpenapi3Doc, errorx.KV(errno.PluginMsgKey, "invalid request example"))
}
}
if req.DebugExample.RespExample != "" {
err = sonic.UnmarshalString(req.DebugExample.RespExample, &respExample)
if example.RespExample != "" {
err = sonic.UnmarshalString(example.RespExample, &respExample)
if err != nil {
return errorx.WrapByCode(err, errno.ErrPluginInvalidOpenapi3Doc, errorx.KV(errno.PluginMsgKey, "invalid response example"))
}
@ -745,9 +770,9 @@ func (p *pluginServiceImpl) UpdateDraftTool(ctx context.Context, req *UpdateTool
}
}
err = p.toolRepo.UpdateDraftToolAndDebugExample(ctx, draftPlugin.ID, draftPlugin.OpenapiDoc, updatedTool)
err = p.pluginRepo.UpdateDebugExample(ctx, draftPlugin.ID, draftPlugin.OpenapiDoc)
if err != nil {
return errorx.Wrapf(err, "UpdateDraftToolAndDebugExample failed, pluginID=%d, toolID=%d", draftPlugin.ID, req.ToolID)
return errorx.Wrapf(err, "UpdateDebugExample failed, pluginID=%d", draftPlugin.ID)
}
return nil

@ -57,7 +57,7 @@ type PluginService interface {
// Draft Tool
MGetDraftTools(ctx context.Context, toolIDs []int64) (tools []*entity.ToolInfo, err error)
UpdateDraftTool(ctx context.Context, req *UpdateToolDraftRequest) (err error)
UpdateDraftTool(ctx context.Context, req *UpdateDraftToolRequest) (err error)
ConvertToOpenapi3Doc(ctx context.Context, req *ConvertToOpenapi3DocRequest) (resp *ConvertToOpenapi3DocResponse)
CreateDraftToolsWithCode(ctx context.Context, req *CreateDraftToolsWithCodeRequest) (resp *CreateDraftToolsWithCodeResponse, err error)
CheckPluginToolsDebugStatus(ctx context.Context, pluginID int64) (err error)
@ -312,7 +312,7 @@ type PublishAPPPluginsResponse = model.PublishAPPPluginsResponse
type MGetPluginLatestVersionResponse = model.MGetPluginLatestVersionResponse
type UpdateToolDraftRequest struct {
type UpdateDraftToolRequest struct {
PluginID int64
ToolID int64
Name *string

@ -651,7 +651,7 @@ func (mr *MockPluginServiceMockRecorder) UpdateDraftPluginWithCode(ctx, req any)
}
// UpdateDraftTool mocks base method.
func (m *MockPluginService) UpdateDraftTool(ctx context.Context, req *service.UpdateToolDraftRequest) error {
func (m *MockPluginService) UpdateDraftTool(ctx context.Context, req *service.UpdateDraftToolRequest) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "UpdateDraftTool", ctx, req)
ret0, _ := ret[0].(error)

Loading…
Cancel
Save