feat: manually mirror opencoze's code from bytedance
Change-Id: I09a73aadda978ad9511264a756b2ce51f5761adf
This commit is contained in:
194
backend/application/search/project_pack.go
Normal file
194
backend/application/search/project_pack.go
Normal file
@@ -0,0 +1,194 @@
|
||||
/*
|
||||
* 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 search
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"github.com/coze-dev/coze-studio/backend/api/model/intelligence"
|
||||
"github.com/coze-dev/coze-studio/backend/api/model/intelligence/common"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/app/entity"
|
||||
appService "github.com/coze-dev/coze-studio/backend/domain/app/service"
|
||||
"github.com/coze-dev/coze-studio/backend/pkg/lang/conv"
|
||||
"github.com/coze-dev/coze-studio/backend/pkg/lang/slices"
|
||||
"github.com/coze-dev/coze-studio/backend/pkg/logs"
|
||||
)
|
||||
|
||||
type projectInfo struct {
|
||||
iconURI string
|
||||
desc string
|
||||
}
|
||||
|
||||
type ProjectPacker interface {
|
||||
GetProjectInfo(ctx context.Context) (*projectInfo, error)
|
||||
GetPermissionInfo() *intelligence.IntelligencePermissionInfo
|
||||
GetPublishedInfo(ctx context.Context) *intelligence.IntelligencePublishInfo
|
||||
GetUserInfo(ctx context.Context, userID int64) *common.User
|
||||
}
|
||||
|
||||
func NewPackProject(uid, projectID int64, tp common.IntelligenceType, s *SearchApplicationService) (ProjectPacker, error) {
|
||||
base := projectBase{SVC: s, projectID: projectID, iType: tp, uid: uid}
|
||||
|
||||
switch tp {
|
||||
case common.IntelligenceType_Bot:
|
||||
return &agentPacker{projectBase: base}, nil
|
||||
case common.IntelligenceType_Project:
|
||||
return &appPacker{projectBase: base}, nil
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("unsupported project_type: %d , project_id : %d", tp, projectID)
|
||||
}
|
||||
|
||||
type projectBase struct {
|
||||
projectID int64 // agent_id or application_id
|
||||
uid int64
|
||||
SVC *SearchApplicationService
|
||||
iType common.IntelligenceType
|
||||
}
|
||||
|
||||
func (p *projectBase) GetPermissionInfo() *intelligence.IntelligencePermissionInfo {
|
||||
return &intelligence.IntelligencePermissionInfo{
|
||||
InCollaboration: false,
|
||||
CanDelete: true,
|
||||
CanView: true,
|
||||
}
|
||||
}
|
||||
|
||||
func (p *projectBase) GetUserInfo(ctx context.Context, userID int64) *common.User {
|
||||
u, err := p.SVC.UserDomainSVC.GetUserInfo(ctx, userID)
|
||||
if err != nil {
|
||||
logs.CtxErrorf(ctx, "[projectBase-GetUserInfo] failed to get user info, user_id: %d, err: %v", userID, err)
|
||||
return nil
|
||||
}
|
||||
|
||||
return &common.User{
|
||||
UserID: u.UserID,
|
||||
AvatarURL: u.IconURL,
|
||||
UserUniqueName: u.UniqueName,
|
||||
}
|
||||
}
|
||||
|
||||
type agentPacker struct {
|
||||
projectBase
|
||||
}
|
||||
|
||||
func (a *agentPacker) GetProjectInfo(ctx context.Context) (*projectInfo, error) {
|
||||
agent, err := a.SVC.SingleAgentDomainSVC.GetSingleAgentDraft(ctx, a.projectID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if agent == nil {
|
||||
return nil, fmt.Errorf("agent info is nil")
|
||||
}
|
||||
return &projectInfo{
|
||||
iconURI: agent.IconURI,
|
||||
desc: agent.Desc,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (p *agentPacker) GetPublishedInfo(ctx context.Context) *intelligence.IntelligencePublishInfo {
|
||||
pubInfo, err := p.SVC.SingleAgentDomainSVC.GetPublishedInfo(ctx, p.projectID)
|
||||
if err != nil {
|
||||
logs.CtxErrorf(ctx, "[agent-GetPublishedInfo]failed to get published info, agent_id: %d, err: %v", p.projectID, err)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
connectors := make([]*common.ConnectorInfo, 0, len(pubInfo.ConnectorID2PublishTime))
|
||||
for connectorID := range pubInfo.ConnectorID2PublishTime {
|
||||
c, err := p.SVC.ConnectorDomainSVC.GetByID(ctx, connectorID)
|
||||
if err != nil {
|
||||
logs.CtxErrorf(ctx, "failed to get connector by id: %d, err: %v", connectorID, err)
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
connectors = append(connectors, &common.ConnectorInfo{
|
||||
ID: conv.Int64ToStr(c.ID),
|
||||
Name: c.Name,
|
||||
ConnectorStatus: common.ConnectorDynamicStatus(c.ConnectorStatus),
|
||||
Icon: c.URL,
|
||||
})
|
||||
}
|
||||
|
||||
return &intelligence.IntelligencePublishInfo{
|
||||
PublishTime: conv.Int64ToStr(pubInfo.LastPublishTimeMS / 1000),
|
||||
HasPublished: pubInfo.LastPublishTimeMS > 0,
|
||||
Connectors: connectors,
|
||||
}
|
||||
}
|
||||
|
||||
type appPacker struct {
|
||||
projectBase
|
||||
}
|
||||
|
||||
func (a *appPacker) GetProjectInfo(ctx context.Context) (*projectInfo, error) {
|
||||
app, err := a.SVC.APPDomainSVC.GetDraftAPP(ctx, a.projectID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &projectInfo{
|
||||
iconURI: app.GetIconURI(),
|
||||
desc: app.GetDesc(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (a *appPacker) GetPublishedInfo(ctx context.Context) *intelligence.IntelligencePublishInfo {
|
||||
record, exist, err := a.SVC.APPDomainSVC.GetAPPPublishRecord(ctx, &appService.GetAPPPublishRecordRequest{
|
||||
APPID: a.projectID,
|
||||
Oldest: true,
|
||||
})
|
||||
if err != nil {
|
||||
logs.CtxErrorf(ctx, "[app-GetPublishedInfo] failed to get published info, app_id=%d, err=%v", a.projectID, err)
|
||||
return nil
|
||||
}
|
||||
if !exist {
|
||||
return &intelligence.IntelligencePublishInfo{
|
||||
PublishTime: "",
|
||||
HasPublished: false,
|
||||
Connectors: nil,
|
||||
}
|
||||
}
|
||||
|
||||
connectorInfo := make([]*common.ConnectorInfo, 0, len(record.ConnectorPublishRecords))
|
||||
connectorIDs := slices.Transform(record.ConnectorPublishRecords, func(c *entity.ConnectorPublishRecord) int64 {
|
||||
return c.ConnectorID
|
||||
})
|
||||
|
||||
connectors, err := a.SVC.ConnectorDomainSVC.GetByIDs(ctx, connectorIDs)
|
||||
if err != nil {
|
||||
logs.CtxErrorf(ctx, "[app-GetPublishedInfo] failed to get connector info, app_id=%d, err=%v", a.projectID, err)
|
||||
} else {
|
||||
for _, c := range connectors {
|
||||
connectorInfo = append(connectorInfo, &common.ConnectorInfo{
|
||||
ID: conv.Int64ToStr(c.ID),
|
||||
Name: c.Name,
|
||||
ConnectorStatus: common.ConnectorDynamicStatus(c.ConnectorStatus),
|
||||
Icon: c.URL,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return &intelligence.IntelligencePublishInfo{
|
||||
PublishTime: strconv.FormatInt(record.APP.GetPublishedAtMS()/1000, 10),
|
||||
HasPublished: record.APP.Published(),
|
||||
Connectors: connectorInfo,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user