feat(plugin): support saas plugin (#2349)
Co-authored-by: yuwenbinjie <yuwenbinjie@bytedance.com> Co-authored-by: ski <csu.zengxiaohui@gmail.com> Co-authored-by: Ryo <fanlv@bytedance.com>
This commit is contained in:
@ -1,72 +0,0 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package coze
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
"github.com/bytedance/sonic"
|
||||
"github.com/cloudwego/hertz/pkg/app/server"
|
||||
"github.com/cloudwego/hertz/pkg/common/ut"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/coze-dev/coze-studio/backend/api/model/conversation/common"
|
||||
"github.com/coze-dev/coze-studio/backend/api/model/conversation/conversation"
|
||||
"github.com/coze-dev/coze-studio/backend/application"
|
||||
"github.com/coze-dev/coze-studio/backend/pkg/lang/ptr"
|
||||
)
|
||||
|
||||
func TestClearConversationCtx(t *testing.T) {
|
||||
h := server.Default()
|
||||
err := application.Init(context.Background())
|
||||
|
||||
t.Logf("application init err: %v", err)
|
||||
h.POST("/api/conversation/create_section", ClearConversationCtx)
|
||||
|
||||
req := &conversation.ClearConversationCtxRequest{
|
||||
ConversationID: 7496795464885338112,
|
||||
Scene: ptr.Of(common.Scene_Playground),
|
||||
}
|
||||
m, err := sonic.Marshal(req)
|
||||
assert.Nil(t, err)
|
||||
|
||||
w := ut.PerformRequest(h.Engine, "POST", "/api/conversation/create_section", &ut.Body{Body: bytes.NewBuffer(m), Len: len(m)}, ut.Header{Key: "Content-Type", Value: "application/json"})
|
||||
res := w.Result()
|
||||
t.Logf("clear conversation ctx: %s", res.Body())
|
||||
assert.Equal(t, http.StatusInternalServerError, res.StatusCode())
|
||||
}
|
||||
|
||||
func TestClearConversationHistory(t *testing.T) {
|
||||
h := server.Default()
|
||||
err := application.Init(context.Background())
|
||||
t.Logf("application init err: %v", err)
|
||||
h.POST("/api/conversation/clear_message", ClearConversationHistory)
|
||||
req := &conversation.ClearConversationHistoryRequest{
|
||||
ConversationID: 7496795464885338113,
|
||||
Scene: ptr.Of(common.Scene_Playground),
|
||||
BotID: ptr.Of(int64(7366055842027922437)),
|
||||
}
|
||||
m, err := sonic.Marshal(req)
|
||||
assert.Nil(t, err)
|
||||
w := ut.PerformRequest(h.Engine, "POST", "/api/conversation/clear_message", &ut.Body{Body: bytes.NewBuffer(m), Len: len(m)}, ut.Header{Key: "Content-Type", Value: "application/json"})
|
||||
res := w.Result()
|
||||
t.Logf("clear conversation history: %s", res.Body())
|
||||
assert.Equal(t, http.StatusInternalServerError, res.StatusCode())
|
||||
}
|
||||
@ -20,7 +20,9 @@ package coze
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
product_public_api "github.com/coze-dev/coze-studio/backend/api/model/marketplace/product_public_api"
|
||||
"github.com/coze-dev/coze-studio/backend/api/model/workflow"
|
||||
@ -40,6 +42,7 @@ import (
|
||||
"github.com/coze-dev/coze-studio/backend/application/search"
|
||||
"github.com/coze-dev/coze-studio/backend/application/singleagent"
|
||||
"github.com/coze-dev/coze-studio/backend/application/template"
|
||||
"github.com/coze-dev/coze-studio/backend/pkg/logs"
|
||||
)
|
||||
|
||||
// PublicGetProductList .
|
||||
@ -68,6 +71,12 @@ func PublicGetProductList(ctx context.Context, c *app.RequestContext) {
|
||||
internalServerErrorResponse(ctx, c, err)
|
||||
return
|
||||
}
|
||||
case product_common.ProductEntityType_SaasPlugin:
|
||||
resp, err = plugin.PluginApplicationSVC.GetCozeSaasPluginList(ctx, &req)
|
||||
if err != nil {
|
||||
internalServerErrorResponse(ctx, c, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
c.JSON(consts.StatusOK, resp)
|
||||
@ -267,3 +276,145 @@ func PublicDuplicateProduct(ctx context.Context, c *app.RequestContext) {
|
||||
|
||||
c.JSON(consts.StatusOK, resp)
|
||||
}
|
||||
|
||||
// PublicSearchProduct .
|
||||
// @router /api/marketplace/product/search [GET]
|
||||
func PublicSearchProduct(ctx context.Context, c *app.RequestContext) {
|
||||
var err error
|
||||
var req product_public_api.SearchProductRequest
|
||||
|
||||
var categoryIDs []int64
|
||||
if categoryIDsStr := string(c.Query("category_ids")); categoryIDsStr != "" {
|
||||
categoryIDs, err = handlerCategoryIDs(c, &req)
|
||||
if err != nil {
|
||||
invalidParamRequestResponse(c, err.Error())
|
||||
return
|
||||
}
|
||||
c.Request.URI().QueryArgs().Del("category_ids")
|
||||
}
|
||||
|
||||
err = c.BindAndValidate(&req)
|
||||
if err != nil {
|
||||
invalidParamRequestResponse(c, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
if len(categoryIDs) > 0 {
|
||||
req.CategoryIDs = categoryIDs
|
||||
}
|
||||
// Call plugin application service
|
||||
resp, err := plugin.PluginApplicationSVC.PublicSearchProduct(ctx, &req)
|
||||
if err != nil {
|
||||
logs.CtxErrorf(ctx, "PublicSearchProduct failed: %v", err)
|
||||
internalServerErrorResponse(ctx, c, err)
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(consts.StatusOK, resp)
|
||||
}
|
||||
|
||||
func handlerCategoryIDs(c *app.RequestContext, req *product_public_api.SearchProductRequest) ([]int64, error) {
|
||||
var categoryIDs []int64
|
||||
if categoryIDsStr := string(c.Query("category_ids")); categoryIDsStr != "" {
|
||||
categoryIDStrs := strings.Split(categoryIDsStr, ",")
|
||||
categoryIDs = make([]int64, 0, len(categoryIDStrs))
|
||||
for _, idStr := range categoryIDStrs {
|
||||
idStr = strings.TrimSpace(idStr)
|
||||
if idStr != "" {
|
||||
// Validate that it's a valid integer
|
||||
if categoryID, parseErr := strconv.ParseInt(idStr, 10, 64); parseErr == nil {
|
||||
categoryIDs = append(categoryIDs, categoryID)
|
||||
} else {
|
||||
return nil, fmt.Errorf("invalid category_id: %s", idStr)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return categoryIDs, nil
|
||||
}
|
||||
|
||||
// PublicSearchSuggest .
|
||||
// @router /api/marketplace/product/search/suggest [GET]
|
||||
func PublicSearchSuggest(ctx context.Context, c *app.RequestContext) {
|
||||
var err error
|
||||
var req product_public_api.SearchSuggestRequest
|
||||
err = c.BindAndValidate(&req)
|
||||
if err != nil {
|
||||
invalidParamRequestResponse(c, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
// Call plugin application service
|
||||
resp, err := plugin.PluginApplicationSVC.PublicSearchSuggest(ctx, &req)
|
||||
if err != nil {
|
||||
logs.CtxErrorf(ctx, "PublicSearchSuggest failed: %v", err)
|
||||
internalServerErrorResponse(ctx, c, err)
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(consts.StatusOK, resp)
|
||||
}
|
||||
|
||||
// PublicGetProductCategoryList .
|
||||
// @router /api/marketplace/product/category/list [GET]
|
||||
func PublicGetProductCategoryList(ctx context.Context, c *app.RequestContext) {
|
||||
var err error
|
||||
var req product_public_api.GetProductCategoryListRequest
|
||||
err = c.BindAndValidate(&req)
|
||||
if err != nil {
|
||||
invalidParamRequestResponse(c, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
var resp *product_public_api.GetProductCategoryListResponse
|
||||
req.EntityType = product_common.ProductEntityType_SaasPlugin
|
||||
switch req.GetEntityType() {
|
||||
case product_common.ProductEntityType_SaasPlugin:
|
||||
resp, err = plugin.PluginApplicationSVC.GetSaasProductCategoryList(ctx, &req)
|
||||
if err != nil {
|
||||
internalServerErrorResponse(ctx, c, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
c.JSON(consts.StatusOK, resp)
|
||||
}
|
||||
|
||||
// PublicGetProductCallInfo .
|
||||
// @router /api/marketplace/product/call_info [GET]
|
||||
func PublicGetProductCallInfo(ctx context.Context, c *app.RequestContext) {
|
||||
var err error
|
||||
var req product_public_api.GetProductCallInfoRequest
|
||||
err = c.BindAndValidate(&req)
|
||||
if err != nil {
|
||||
invalidParamRequestResponse(c, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
resp, err := plugin.PluginApplicationSVC.GetProductCallInfo(ctx, &req)
|
||||
if err != nil {
|
||||
internalServerErrorResponse(ctx, c, err)
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(consts.StatusOK, resp)
|
||||
}
|
||||
|
||||
// PublicGetMarketPluginConfig .
|
||||
// @router /api/marketplace/product/config [GET]
|
||||
func PublicGetMarketPluginConfig(ctx context.Context, c *app.RequestContext) {
|
||||
var err error
|
||||
var req product_public_api.GetMarketPluginConfigRequest
|
||||
err = c.BindAndValidate(&req)
|
||||
if err != nil {
|
||||
invalidParamRequestResponse(c, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
resp, err := plugin.PluginApplicationSVC.GetMarketPluginConfig(ctx, &req)
|
||||
if err != nil {
|
||||
internalServerErrorResponse(ctx, c, err)
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(consts.StatusOK, resp)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user