feat(plugin): search & category list
This commit is contained in:
@ -331,7 +331,7 @@ func PublicGetProductCategoryList(ctx context.Context, c *app.RequestContext) {
|
||||
}
|
||||
|
||||
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)
|
||||
|
||||
@ -1,19 +1,3 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
// Code generated by thriftgo (0.4.2). DO NOT EDIT.
|
||||
|
||||
package product_public_api
|
||||
@ -1477,9 +1461,9 @@ func (p *SearchProductRequest) String() string {
|
||||
}
|
||||
|
||||
type SearchProductResponse struct {
|
||||
Code int32 `thrift:"Code,1,required" form:"Code,required" json:"Code,required" query:"Code,required"`
|
||||
Message string `thrift:"Message,2,required" form:"Message,required" json:"Message,required" query:"Message,required"`
|
||||
Data *SearchProductResponseData `thrift:"Data,3,optional" form:"Data" json:"Data,omitempty" query:"Data"`
|
||||
Code int32 `thrift:"Code,1,required" form:"code,required" json:"code,required"`
|
||||
Message string `thrift:"Message,2,required" form:"message,required" json:"message,required"`
|
||||
Data *SearchProductResponseData `thrift:"Data,3,optional" form:"data" json:"data,omitempty"`
|
||||
BaseResp *base.BaseResp `thrift:"BaseResp,255,optional" form:"BaseResp" json:"BaseResp,omitempty" query:"BaseResp"`
|
||||
}
|
||||
|
||||
@ -1782,11 +1766,11 @@ func (p *SearchProductResponse) String() string {
|
||||
}
|
||||
|
||||
type SearchProductResponseData struct {
|
||||
Products []*ProductInfo `thrift:"Products,1,optional" form:"Products" json:"Products,omitempty" query:"Products"`
|
||||
Total *int32 `thrift:"Total,2,optional" form:"Total" json:"Total,omitempty" query:"Total"`
|
||||
HasMore *bool `thrift:"HasMore,3,optional" form:"HasMore" json:"HasMore,omitempty" query:"HasMore"`
|
||||
Products []*ProductInfo `thrift:"Products,1,optional" form:"products" json:"products,omitempty"`
|
||||
Total *int32 `thrift:"Total,2,optional" form:"total" json:"total,omitempty"`
|
||||
HasMore *bool `thrift:"HasMore,3,optional" form:"has_more" json:"has_more,omitempty"`
|
||||
// Entity count
|
||||
EntityTotal map[product_common.ProductEntityType]int32 `thrift:"EntityTotal,4,optional" form:"EntityTotal" json:"EntityTotal,omitempty" query:"EntityTotal"`
|
||||
EntityTotal map[product_common.ProductEntityType]int32 `thrift:"EntityTotal,4,optional" form:"entity_total" json:"entity_total,omitempty"`
|
||||
}
|
||||
|
||||
func NewSearchProductResponseData() *SearchProductResponseData {
|
||||
@ -2150,9 +2134,9 @@ func (p *SearchProductResponseData) String() string {
|
||||
}
|
||||
|
||||
type SearchSuggestResponse struct {
|
||||
Code int32 `thrift:"Code,1,required" form:"Code,required" json:"Code,required" query:"Code,required"`
|
||||
Message string `thrift:"Message,2,required" form:"Message,required" json:"Message,required" query:"Message,required"`
|
||||
Data *SearchSuggestResponseData `thrift:"Data,3,optional" form:"Data" json:"Data,omitempty" query:"Data"`
|
||||
Code int32 `thrift:"Code,1,required" form:"code,required" json:"code,required"`
|
||||
Message string `thrift:"Message,2,required" form:"message,required" json:"message,required"`
|
||||
Data *SearchSuggestResponseData `thrift:"Data,3,optional" form:"data" json:"data,omitempty"`
|
||||
BaseResp *base.BaseResp `thrift:"BaseResp,255,optional" form:"BaseResp" json:"BaseResp,omitempty" query:"BaseResp"`
|
||||
}
|
||||
|
||||
@ -2456,9 +2440,9 @@ func (p *SearchSuggestResponse) String() string {
|
||||
|
||||
type SearchSuggestResponseData struct {
|
||||
// Deprecated
|
||||
Suggestions []*ProductMetaInfo `thrift:"Suggestions,1,optional" form:"Suggestions" json:"Suggestions,omitempty" query:"Suggestions"`
|
||||
HasMore *bool `thrift:"HasMore,2,optional" form:"HasMore" json:"HasMore,omitempty" query:"HasMore"`
|
||||
SuggestionV2 []*ProductInfo `thrift:"SuggestionV2,3,optional" form:"SuggestionV2" json:"SuggestionV2,omitempty" query:"SuggestionV2"`
|
||||
Suggestions []*ProductMetaInfo `thrift:"Suggestions,1,optional" form:"suggestions" json:"suggestions,omitempty"`
|
||||
HasMore *bool `thrift:"HasMore,2,optional" form:"has_more" json:"has_more,omitempty"`
|
||||
SuggestionV2 []*ProductInfo `thrift:"SuggestionV2,3,optional" form:"suggestion_v2" json:"suggestion_v2,omitempty"`
|
||||
}
|
||||
|
||||
func NewSearchSuggestResponseData() *SearchSuggestResponseData {
|
||||
@ -26784,8 +26768,8 @@ func (p *GetProductCategoryListRequest) String() string {
|
||||
}
|
||||
|
||||
type GetProductCategoryListData struct {
|
||||
EntityType product_common.ProductEntityType `thrift:"EntityType,1,required" form:"EntityType,required" json:"EntityType,required" query:"EntityType,required"`
|
||||
Categories []*ProductCategory `thrift:"Categories,2,optional" form:"Categories" json:"Categories,omitempty" query:"Categories"`
|
||||
EntityType product_common.ProductEntityType `thrift:"EntityType,1,required" form:"entity_type,required" json:"entity_type,required"`
|
||||
Categories []*ProductCategory `thrift:"Categories,2,optional" form:"categories" json:"categories,omitempty"`
|
||||
}
|
||||
|
||||
func NewGetProductCategoryListData() *GetProductCategoryListData {
|
||||
@ -27007,9 +26991,9 @@ func (p *GetProductCategoryListData) String() string {
|
||||
}
|
||||
|
||||
type GetProductCategoryListResponse struct {
|
||||
Code int32 `thrift:"Code,1,required" form:"Code,required" json:"Code,required" query:"Code,required"`
|
||||
Message string `thrift:"Message,2,required" form:"Message,required" json:"Message,required" query:"Message,required"`
|
||||
Data *GetProductCategoryListData `thrift:"Data,3" form:"Data" json:"Data" query:"Data"`
|
||||
Code int32 `thrift:"Code,1,required" form:"code,required" json:"code,required"`
|
||||
Message string `thrift:"Message,2,required" form:"message,required" json:"message,required"`
|
||||
Data *GetProductCategoryListData `thrift:"Data,3" form:"data" json:"data"`
|
||||
BaseResp *base.BaseResp `thrift:"BaseResp,255,optional" form:"BaseResp" json:"BaseResp,omitempty" query:"BaseResp"`
|
||||
}
|
||||
|
||||
|
||||
@ -326,6 +326,12 @@ func convertPluginToProductInfo(plugin *entity.PluginInfo) *productAPI.ProductIn
|
||||
Description: plugin.GetDesc(),
|
||||
IconURL: plugin.GetIconURI(),
|
||||
ListedAt: plugin.CreatedAt,
|
||||
EntityType: productCommon.ProductEntityType_Plugin,
|
||||
IsOfficial: true,
|
||||
Status: productCommon.ProductStatus_Listed,
|
||||
UserInfo: &productCommon.UserInfo{
|
||||
Name: "Coze Official",
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
@ -348,6 +354,21 @@ func (p *PluginApplicationService) convertPluginsToProductInfos(ctx context.Cont
|
||||
}
|
||||
return products
|
||||
}
|
||||
func (p *PluginApplicationService) convertPluginsToMetaInfos(ctx context.Context, plugins []*entity.PluginInfo, tools map[int64][]*entity.ToolInfo) []*productAPI.ProductMetaInfo {
|
||||
products := make([]*productAPI.ProductMetaInfo, 0, len(plugins))
|
||||
for _, plugin := range plugins {
|
||||
pi := &productAPI.ProductMetaInfo{
|
||||
ID: plugin.ID,
|
||||
Name: plugin.GetName(),
|
||||
Description: plugin.GetDesc(),
|
||||
IconURL: plugin.GetIconURI(),
|
||||
ListedAt: plugin.CreatedAt,
|
||||
EntityID: plugin.ID,
|
||||
}
|
||||
products = append(products, pi)
|
||||
}
|
||||
return products
|
||||
}
|
||||
|
||||
func (p *PluginApplicationService) getSaasPluginList(ctx context.Context, domainReq *dto.ListSaasPluginProductsRequest) (*dto.ListPluginProductsResponse, error) {
|
||||
return p.DomainSVC.ListSaasPluginProducts(ctx, domainReq)
|
||||
@ -402,10 +423,15 @@ func (p *PluginApplicationService) GetCozeSaasPluginList(ctx context.Context, re
|
||||
|
||||
func (p *PluginApplicationService) PublicSearchProduct(ctx context.Context, req *productAPI.SearchProductRequest) (resp *productAPI.SearchProductResponse, err error) {
|
||||
domainResp, err := p.getSaasPluginList(ctx, &dto.ListSaasPluginProductsRequest{
|
||||
PageNum: ptr.Of(req.PageNum),
|
||||
PageSize: ptr.Of(req.PageSize),
|
||||
Keyword: ptr.Of(req.Keyword),
|
||||
EntityTypes: p.convertEntityTypesStrToSlice(*req.EntityTypes),
|
||||
PageNum: ptr.Of(req.PageNum),
|
||||
PageSize: ptr.Of(req.PageSize),
|
||||
Keyword: ptr.Of(req.Keyword),
|
||||
EntityTypes: func() []productCommon.ProductEntityType {
|
||||
if req.EntityTypes == nil {
|
||||
return nil
|
||||
}
|
||||
return p.convertEntityTypesStrToSlice(*req.EntityTypes)
|
||||
}(),
|
||||
CategoryIDs: req.CategoryIDs,
|
||||
IsOfficial: req.IsOfficial,
|
||||
PluginType: req.PluginType,
|
||||
@ -462,11 +488,17 @@ func (p *PluginApplicationService) convertEntityTypesStrToSlice(entityTypesStr s
|
||||
}
|
||||
func (p *PluginApplicationService) PublicSearchSuggest(ctx context.Context, req *productAPI.SearchSuggestRequest) (resp *productAPI.SearchSuggestResponse, err error) {
|
||||
domainResp, err := p.getSaasPluginList(ctx, &dto.ListSaasPluginProductsRequest{
|
||||
PageNum: req.PageNum,
|
||||
PageSize: req.PageSize,
|
||||
Keyword: req.Keyword,
|
||||
EntityTypes: p.convertEntityTypesStrToSlice(*req.EntityTypes),
|
||||
PageNum: req.PageNum,
|
||||
PageSize: req.PageSize,
|
||||
Keyword: req.Keyword,
|
||||
EntityTypes: func() []productCommon.ProductEntityType {
|
||||
if req.EntityTypes == nil {
|
||||
return nil
|
||||
}
|
||||
return p.convertEntityTypesStrToSlice(*req.EntityTypes)
|
||||
}(),
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
logs.CtxErrorf(ctx, "ListSaasPluginProducts for suggestions failed: %v", err)
|
||||
return &productAPI.SearchSuggestResponse{
|
||||
@ -497,6 +529,7 @@ func (p *PluginApplicationService) PublicSearchSuggest(ctx context.Context, req
|
||||
Message: "success",
|
||||
Data: &productAPI.SearchSuggestResponseData{
|
||||
SuggestionV2: suggestionProducts,
|
||||
Suggestions: p.convertPluginsToMetaInfos(ctx, domainResp.Plugins, tools),
|
||||
HasMore: ptr.Of(domainResp.HasMore),
|
||||
},
|
||||
}, nil
|
||||
|
||||
@ -232,26 +232,23 @@ type JsonSchema struct {
|
||||
Extra map[string]*JsonSchema `json:"-"`
|
||||
}
|
||||
|
||||
|
||||
type SaasPluginToolsListResponse struct {
|
||||
Items []SaasPluginToolsList `json:"items"`
|
||||
}
|
||||
type SaasPluginToolsList struct {
|
||||
Tools []Tools `json:"tools"`
|
||||
PluginID string `json:"plugin_id"`
|
||||
McpJSON string `json:"mcp_json"`
|
||||
Tools []Tools `json:"tools"`
|
||||
PluginID string `json:"plugin_id"`
|
||||
McpJSON string `json:"mcp_json"`
|
||||
}
|
||||
|
||||
type Tools struct {
|
||||
ToolID string `json:"tool_id"`
|
||||
Description string `json:"description"`
|
||||
InputSchema *JsonSchema `json:"inputSchema"`
|
||||
Name string `json:"name"`
|
||||
OutputSchema *JsonSchema `json:"outputSchema"`
|
||||
ToolID string `json:"tool_id"`
|
||||
Description string `json:"description"`
|
||||
InputSchema *JsonSchema `json:"inputSchema"`
|
||||
Name string `json:"name"`
|
||||
OutputSchema *JsonSchema `json:"outputSchema"`
|
||||
}
|
||||
|
||||
|
||||
|
||||
// stringToJsonSchemaType converts a string to JsonSchemaType
|
||||
func stringToJsonSchemaType(s string) JsonSchemaType {
|
||||
switch s {
|
||||
|
||||
@ -446,4 +446,4 @@ func TestBatchGetSaasPluginToolsInfoIntegration(t *testing.T) {
|
||||
assert.Equal(t, pluginCommon.ParameterType_Bool, imageParam.Type)
|
||||
assert.Equal(t, pluginCommon.ParameterLocation_Body, imageParam.Location)
|
||||
assert.Equal(t, "是否需要返回图片url", imageParam.Desc)
|
||||
}
|
||||
}
|
||||
|
||||
@ -45,30 +45,30 @@ struct SearchProductRequest{
|
||||
}
|
||||
|
||||
struct SearchProductResponse{
|
||||
1 : required i32 Code (agw.key = "code") ,
|
||||
2 : required string Message (agw.key = "message"),
|
||||
3 : optional SearchProductResponseData Data (agw.key = "data") ,
|
||||
1 : required i32 Code (agw.key = "code",api.body = "code") ,
|
||||
2 : required string Message (agw.key = "message",api.body = "message"),
|
||||
3 : optional SearchProductResponseData Data (agw.key = "data",api.body = "data") ,
|
||||
255: optional base.BaseResp BaseResp ,
|
||||
}
|
||||
|
||||
struct SearchProductResponseData{
|
||||
1: optional list<ProductInfo> Products (agw.key = "products"),
|
||||
2: optional i32 Total (agw.key = "total") ,
|
||||
3: optional bool HasMore (agw.key = "has_more"),
|
||||
4: optional map<product_common.ProductEntityType, i32> EntityTotal (agw.key = "entity_total"), // Entity count
|
||||
1: optional list<ProductInfo> Products (agw.key = "products",api.body = "products"),
|
||||
2: optional i32 Total (agw.key = "total",api.body = "total") ,
|
||||
3: optional bool HasMore (agw.key = "has_more",api.body = "has_more"),
|
||||
4: optional map<product_common.ProductEntityType, i32> EntityTotal (agw.key = "entity_total",api.body = "entity_total"), // Entity count
|
||||
}
|
||||
|
||||
struct SearchSuggestResponse{
|
||||
1 : required i32 Code (agw.key = "code") ,
|
||||
2 : required string Message (agw.key = "message"),
|
||||
3 : optional SearchSuggestResponseData Data (agw.key = "data") ,
|
||||
1 : required i32 Code (agw.key = "code",api.body = "code") ,
|
||||
2 : required string Message (agw.key = "message",api.body = "message"),
|
||||
3 : optional SearchSuggestResponseData Data (agw.key = "data",api.body = "data") ,
|
||||
255: optional base.BaseResp BaseResp ,
|
||||
}
|
||||
|
||||
struct SearchSuggestResponseData{
|
||||
1: optional list<ProductMetaInfo> Suggestions (agw.key = "suggestions"), // Deprecated
|
||||
2: optional bool HasMore (agw.key = "has_more"),
|
||||
3: optional list<ProductInfo> SuggestionV2(agw.key = "suggestion_v2"),
|
||||
1: optional list<ProductMetaInfo> Suggestions (agw.key = "suggestions",api.body = "suggestions"), // Deprecated
|
||||
2: optional bool HasMore (agw.key = "has_more",api.body = "has_more"),
|
||||
3: optional list<ProductInfo> SuggestionV2(agw.key = "suggestion_v2",api.body = "suggestion_v2"),
|
||||
}
|
||||
|
||||
|
||||
@ -648,14 +648,14 @@ struct GetProductCategoryListRequest {
|
||||
}
|
||||
|
||||
struct GetProductCategoryListData{
|
||||
1: required product_common.ProductEntityType EntityType (agw.key = "entity_type"),
|
||||
2: optional list<ProductCategory> Categories (agw.key = "categories") ,
|
||||
1: required product_common.ProductEntityType EntityType (agw.key = "entity_type", api.body= "entity_type"),
|
||||
2: optional list<ProductCategory> Categories (agw.key = "categories", api.body= "categories") ,
|
||||
}
|
||||
|
||||
struct GetProductCategoryListResponse {
|
||||
1 : required i32 Code (agw.key = "code") ,
|
||||
2 : required string Message (agw.key = "message"),
|
||||
3 : GetProductCategoryListData Data (agw.key = "data") ,
|
||||
1 : required i32 Code (agw.key = "code", api.body= "code") ,
|
||||
2 : required string Message (agw.key = "message", api.body= "message"),
|
||||
3 : GetProductCategoryListData Data (agw.key = "data", api.body= "data") ,
|
||||
|
||||
255: optional base.BaseResp BaseResp ,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user