From 7654861eb8554f6ca14901df0efb9c65f624bec1 Mon Sep 17 00:00:00 2001 From: xueyizheng Date: Mon, 3 Nov 2025 16:25:54 +0800 Subject: [PATCH 01/21] add start/end time --- .../evaluation/application/experiment_app.go | 11 ++++++- .../domain/component/rpc/trace_agent.go | 2 +- .../modules/evaluation/domain/entity/event.go | 8 +++-- .../domain/service/insight_analysis.go | 4 +-- .../domain/service/insight_analysis_impl.go | 30 +++++++++++-------- .../infra/mq/rocket/consumer/expt_export.go | 2 +- .../evaluation/infra/rpc/agent/agent.go | 2 +- 7 files changed, 37 insertions(+), 22 deletions(-) diff --git a/backend/modules/evaluation/application/experiment_app.go b/backend/modules/evaluation/application/experiment_app.go index 7a02d4166..39ed60669 100644 --- a/backend/modules/evaluation/application/experiment_app.go +++ b/backend/modules/evaluation/application/experiment_app.go @@ -1263,12 +1263,21 @@ func (e *experimentApplication) InsightAnalysisExperiment(ctx context.Context, r if err != nil { return nil, err } + + var startTime, endTime *int64 + if got.StartAt != nil { + startTime = gptr.Of(got.StartAt.Unix()) + } + if got.EndAt != nil { + endTime = gptr.Of(got.EndAt.Unix()) + } + recordID, err := e.CreateAnalysisRecord(ctx, &entity.ExptInsightAnalysisRecord{ SpaceID: req.GetWorkspaceID(), ExptID: req.GetExptID(), CreatedBy: session.UserID, Status: entity.InsightAnalysisStatus_Running, - }, session) + }, session, gptr.Indirect(startTime), gptr.Indirect(endTime)) if err != nil { return nil, err } diff --git a/backend/modules/evaluation/domain/component/rpc/trace_agent.go b/backend/modules/evaluation/domain/component/rpc/trace_agent.go index 658736cae..97e30910c 100644 --- a/backend/modules/evaluation/domain/component/rpc/trace_agent.go +++ b/backend/modules/evaluation/domain/component/rpc/trace_agent.go @@ -11,6 +11,6 @@ import ( //go:generate mockgen -destination=mocks/trace_agent.go -package=mocks . IAgentAdapter type IAgentAdapter interface { - CallTraceAgent(ctx context.Context, spaceID int64, url string) (int64, error) + CallTraceAgent(ctx context.Context, spaceID int64, url string, startTime, endTime int64) (int64, error) GetReport(ctx context.Context, spaceID, reportID int64) (report string, status entity.ReportStatus, err error) } diff --git a/backend/modules/evaluation/domain/entity/event.go b/backend/modules/evaluation/domain/entity/event.go index 05d309766..3e8b6bc95 100644 --- a/backend/modules/evaluation/domain/entity/event.go +++ b/backend/modules/evaluation/domain/entity/event.go @@ -120,9 +120,11 @@ type ExportCSVEvent struct { ExperimentID int64 SpaceID int64 - Session *Session - ExportScene ExportScene - CreatedAt int64 + Session *Session + ExportScene ExportScene + CreatedAt int64 + ExptStartTime int64 // Unix Time + ExptEndTime int64 // Unix Time } type ExportScene int diff --git a/backend/modules/evaluation/domain/service/insight_analysis.go b/backend/modules/evaluation/domain/service/insight_analysis.go index e345fd7be..623dca355 100644 --- a/backend/modules/evaluation/domain/service/insight_analysis.go +++ b/backend/modules/evaluation/domain/service/insight_analysis.go @@ -10,8 +10,8 @@ import ( ) type IExptInsightAnalysisService interface { - CreateAnalysisRecord(ctx context.Context, record *entity.ExptInsightAnalysisRecord, session *entity.Session) (int64, error) - GenAnalysisReport(ctx context.Context, spaceID, exptID, recordID, CreateAt int64) error + CreateAnalysisRecord(ctx context.Context, record *entity.ExptInsightAnalysisRecord, session *entity.Session, startTime, endTime int64) (int64, error) + GenAnalysisReport(ctx context.Context, spaceID, exptID, recordID, CreateAt, startTime, endTime int64) error GetAnalysisRecordByID(ctx context.Context, spaceID, exptID, recordID int64, session *entity.Session) (*entity.ExptInsightAnalysisRecord, error) ListAnalysisRecord(ctx context.Context, spaceID, exptID int64, page entity.Page, session *entity.Session) ([]*entity.ExptInsightAnalysisRecord, int64, error) DeleteAnalysisRecord(ctx context.Context, spaceID, exptID, recordID int64) error diff --git a/backend/modules/evaluation/domain/service/insight_analysis_impl.go b/backend/modules/evaluation/domain/service/insight_analysis_impl.go index 9f5869464..1c83290f0 100644 --- a/backend/modules/evaluation/domain/service/insight_analysis_impl.go +++ b/backend/modules/evaluation/domain/service/insight_analysis_impl.go @@ -55,18 +55,20 @@ func NewInsightAnalysisService(repo repo.IExptInsightAnalysisRecordRepo, } } -func (e ExptInsightAnalysisServiceImpl) CreateAnalysisRecord(ctx context.Context, record *entity.ExptInsightAnalysisRecord, session *entity.Session) (int64, error) { +func (e ExptInsightAnalysisServiceImpl) CreateAnalysisRecord(ctx context.Context, record *entity.ExptInsightAnalysisRecord, session *entity.Session, startTime, endTime int64) (int64, error) { recordID, err := e.repo.CreateAnalysisRecord(ctx, record) if err != nil { return 0, err } exportEvent := &entity.ExportCSVEvent{ - ExportID: recordID, - ExperimentID: record.ExptID, - SpaceID: record.SpaceID, - ExportScene: entity.ExportSceneInsightAnalysis, - CreatedAt: time.Now().Unix(), + ExportID: recordID, + ExperimentID: record.ExptID, + SpaceID: record.SpaceID, + ExportScene: entity.ExportSceneInsightAnalysis, + CreatedAt: time.Now().Unix(), + ExptStartTime: startTime, + ExptEndTime: endTime, } err = e.exptPublisher.PublishExptExportCSVEvent(ctx, exportEvent, gptr.Of(time.Second*3)) if err != nil { @@ -76,7 +78,7 @@ func (e ExptInsightAnalysisServiceImpl) CreateAnalysisRecord(ctx context.Context return recordID, nil } -func (e ExptInsightAnalysisServiceImpl) GenAnalysisReport(ctx context.Context, spaceID, exptID, recordID, CreateAt int64) (err error) { +func (e ExptInsightAnalysisServiceImpl) GenAnalysisReport(ctx context.Context, spaceID, exptID, recordID, CreateAt, startTime, endTime int64) (err error) { analysisRecord, err := e.repo.GetAnalysisRecordByID(ctx, spaceID, exptID, recordID) if err != nil { return err @@ -125,7 +127,7 @@ func (e ExptInsightAnalysisServiceImpl) GenAnalysisReport(ctx context.Context, s return err } - reportID, err := e.agentAdapter.CallTraceAgent(ctx, spaceID, url) + reportID, err := e.agentAdapter.CallTraceAgent(ctx, spaceID, url, startTime, endTime) if err != nil { return err } @@ -135,11 +137,13 @@ func (e ExptInsightAnalysisServiceImpl) GenAnalysisReport(ctx context.Context, s // 发送时间检查分析报告生成状态 exportEvent := &entity.ExportCSVEvent{ - ExportID: recordID, - ExperimentID: exptID, - SpaceID: spaceID, - ExportScene: entity.ExportSceneInsightAnalysis, - CreatedAt: CreateAt, + ExportID: recordID, + ExperimentID: exptID, + SpaceID: spaceID, + ExportScene: entity.ExportSceneInsightAnalysis, + CreatedAt: CreateAt, + ExptStartTime: startTime, // 传递开始时间 + ExptEndTime: endTime, // 传递结束时间 } err = e.exptPublisher.PublishExptExportCSVEvent(ctx, exportEvent, gptr.Of(time.Minute*3)) if err != nil { diff --git a/backend/modules/evaluation/infra/mq/rocket/consumer/expt_export.go b/backend/modules/evaluation/infra/mq/rocket/consumer/expt_export.go index 07e44f0fa..b3a3603b8 100644 --- a/backend/modules/evaluation/infra/mq/rocket/consumer/expt_export.go +++ b/backend/modules/evaluation/infra/mq/rocket/consumer/expt_export.go @@ -53,7 +53,7 @@ func (e *ExptExportConsumer) HandleMessage(ctx context.Context, ext *mq.MessageE func (e *ExptExportConsumer) handleEvent(ctx context.Context, event *entity.ExportCSVEvent) (err error) { switch event.ExportScene { case entity.ExportSceneInsightAnalysis: - err = e.exptInsightAnalysisService.GenAnalysisReport(ctx, event.SpaceID, event.ExperimentID, event.ExportID, event.CreatedAt) + err = e.exptInsightAnalysisService.GenAnalysisReport(ctx, event.SpaceID, event.ExperimentID, event.ExportID, event.CreatedAt, event.ExptStartTime, event.ExptEndTime) if err != nil { logs.CtxError(ctx, "ExptExportConsumer GenAnalysisReport fail, expt_id:%v, err: %v", event.ExperimentID, err) return nil diff --git a/backend/modules/evaluation/infra/rpc/agent/agent.go b/backend/modules/evaluation/infra/rpc/agent/agent.go index c5b9e529f..bea8d450e 100644 --- a/backend/modules/evaluation/infra/rpc/agent/agent.go +++ b/backend/modules/evaluation/infra/rpc/agent/agent.go @@ -18,7 +18,7 @@ func NewAgentAdapter() rpc.IAgentAdapter { return &AgentAdapter{} } -func (a AgentAdapter) CallTraceAgent(ctx context.Context, spaceID int64, url string) (int64, error) { +func (a AgentAdapter) CallTraceAgent(ctx context.Context, spaceID int64, url string, startTime, endTime int64) (int64, error) { return 0, errorx.NewByCode(errno.CommonInternalErrorCode, errorx.WithExtraMsg("CallTraceAgent not implement")) } From 797f686ce42d0c21c4639f9ead544b4b3a247635 Mon Sep 17 00:00:00 2001 From: xueyizheng Date: Mon, 3 Nov 2025 18:22:02 +0800 Subject: [PATCH 02/21] fix ut --- .../application/experiment_app_test.go | 17 +++++++++++++---- .../domain/component/rpc/mocks/trace_agent.go | 8 ++++---- .../service/insight_analysis_impl_test.go | 10 +++++----- .../domain/service/mocks/insight_analysis.go | 16 ++++++++-------- .../evaluation/infra/rpc/agent/agent_test.go | 2 +- 5 files changed, 31 insertions(+), 22 deletions(-) diff --git a/backend/modules/evaluation/application/experiment_app_test.go b/backend/modules/evaluation/application/experiment_app_test.go index c6aa6d411..2f5f76188 100644 --- a/backend/modules/evaluation/application/experiment_app_test.go +++ b/backend/modules/evaluation/application/experiment_app_test.go @@ -10,6 +10,7 @@ import ( "reflect" "strconv" "testing" + "time" "github.com/bytedance/gg/gptr" "github.com/stretchr/testify/assert" @@ -3901,11 +3902,15 @@ func TestInsightAnalysisExperiment(t *testing.T) { t.Run("成功创建洞察分析", func(t *testing.T) { // Mock the manager.Get call - mockManager.EXPECT().Get(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(&entity.Experiment{CreatedBy: "test-user"}, nil) + mockManager.EXPECT().Get(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(&entity.Experiment{ + CreatedBy: "test-user", + StartAt: &[]time.Time{time.Now()}[0], + EndAt: &[]time.Time{time.Now()}[0], + }, nil) // Mock the auth.AuthorizationWithoutSPI call mockAuth.EXPECT().AuthorizationWithoutSPI(gomock.Any(), gomock.Any()).Return(nil) // Mock the CreateAnalysisRecord call - mockInsightService.EXPECT().CreateAnalysisRecord(gomock.Any(), gomock.Any(), gomock.Any()).Return(int64(123), nil) + mockInsightService.EXPECT().CreateAnalysisRecord(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(int64(123), nil) _, err := app.InsightAnalysisExperiment(ctx, req) assert.NoError(t, err) @@ -3929,9 +3934,13 @@ func TestInsightAnalysisExperiment(t *testing.T) { }) t.Run("创建分析记录失败", func(t *testing.T) { - mockManager.EXPECT().Get(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(&entity.Experiment{CreatedBy: "test-user"}, nil) + mockManager.EXPECT().Get(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(&entity.Experiment{ + CreatedBy: "test-user", + StartAt: &[]time.Time{time.Now()}[0], + EndAt: &[]time.Time{time.Now()}[0], + }, nil) mockAuth.EXPECT().AuthorizationWithoutSPI(gomock.Any(), gomock.Any()).Return(nil) - mockInsightService.EXPECT().CreateAnalysisRecord(gomock.Any(), gomock.Any(), gomock.Any()).Return(int64(0), errors.New("create analysis record error")) + mockInsightService.EXPECT().CreateAnalysisRecord(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(int64(0), errors.New("create analysis record error")) _, err := app.InsightAnalysisExperiment(ctx, req) assert.Error(t, err) diff --git a/backend/modules/evaluation/domain/component/rpc/mocks/trace_agent.go b/backend/modules/evaluation/domain/component/rpc/mocks/trace_agent.go index 509b8a761..8ba43466c 100644 --- a/backend/modules/evaluation/domain/component/rpc/mocks/trace_agent.go +++ b/backend/modules/evaluation/domain/component/rpc/mocks/trace_agent.go @@ -42,18 +42,18 @@ func (m *MockIAgentAdapter) EXPECT() *MockIAgentAdapterMockRecorder { } // CallTraceAgent mocks base method. -func (m *MockIAgentAdapter) CallTraceAgent(ctx context.Context, spaceID int64, url string) (int64, error) { +func (m *MockIAgentAdapter) CallTraceAgent(ctx context.Context, spaceID int64, url string, startTime, endTime int64) (int64, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "CallTraceAgent", ctx, spaceID, url) + ret := m.ctrl.Call(m, "CallTraceAgent", ctx, spaceID, url, startTime, endTime) ret0, _ := ret[0].(int64) ret1, _ := ret[1].(error) return ret0, ret1 } // CallTraceAgent indicates an expected call of CallTraceAgent. -func (mr *MockIAgentAdapterMockRecorder) CallTraceAgent(ctx, spaceID, url any) *gomock.Call { +func (mr *MockIAgentAdapterMockRecorder) CallTraceAgent(ctx, spaceID, url, startTime, endTime any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CallTraceAgent", reflect.TypeOf((*MockIAgentAdapter)(nil).CallTraceAgent), ctx, spaceID, url) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CallTraceAgent", reflect.TypeOf((*MockIAgentAdapter)(nil).CallTraceAgent), ctx, spaceID, url, startTime, endTime) } // GetReport mocks base method. diff --git a/backend/modules/evaluation/domain/service/insight_analysis_impl_test.go b/backend/modules/evaluation/domain/service/insight_analysis_impl_test.go index d4b434070..dbf918b6e 100644 --- a/backend/modules/evaluation/domain/service/insight_analysis_impl_test.go +++ b/backend/modules/evaluation/domain/service/insight_analysis_impl_test.go @@ -134,7 +134,7 @@ func TestExptInsightAnalysisServiceImpl_CreateAnalysisRecord(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { tt.setup() - result, err := service.CreateAnalysisRecord(ctx, tt.record, tt.session) + result, err := service.CreateAnalysisRecord(ctx, tt.record, tt.session, 0, 0) if tt.wantErr { assert.Error(t, err) } else { @@ -172,7 +172,7 @@ func TestExptInsightAnalysisServiceImpl_GenAnalysisReport(t *testing.T) { }, nil) mocks.exptResultExportService.EXPECT().DoExportCSV(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil) mocks.fileClient.EXPECT().SignDownloadReq(gomock.Any(), gomock.Any(), gomock.Any()).Return("http://test-url.com", make(map[string][]string), nil) - mocks.agentAdapter.EXPECT().CallTraceAgent(gomock.Any(), gomock.Any(), gomock.Any()).Return(int64(123), nil) + mocks.agentAdapter.EXPECT().CallTraceAgent(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(int64(123), nil) mocks.publisher.EXPECT().PublishExptExportCSVEvent(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil) mocks.repo.EXPECT().UpdateAnalysisRecord(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil) }, @@ -266,7 +266,7 @@ func TestExptInsightAnalysisServiceImpl_GenAnalysisReport(t *testing.T) { }, nil) mocks.exptResultExportService.EXPECT().DoExportCSV(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil) mocks.fileClient.EXPECT().SignDownloadReq(gomock.Any(), gomock.Any(), gomock.Any()).Return("http://test-url.com", make(map[string][]string), nil) - mocks.agentAdapter.EXPECT().CallTraceAgent(gomock.Any(), gomock.Any(), gomock.Any()).Return(int64(0), errors.New("agent error")) + mocks.agentAdapter.EXPECT().CallTraceAgent(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(int64(0), errors.New("agent error")) mocks.repo.EXPECT().UpdateAnalysisRecord(gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(func(ctx context.Context, record *entity.ExptInsightAnalysisRecord, opts ...db.Option) error { assert.Equal(t, entity.InsightAnalysisStatus_Failed, record.Status) return nil @@ -289,7 +289,7 @@ func TestExptInsightAnalysisServiceImpl_GenAnalysisReport(t *testing.T) { }, nil) mocks.exptResultExportService.EXPECT().DoExportCSV(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil) mocks.fileClient.EXPECT().SignDownloadReq(gomock.Any(), gomock.Any(), gomock.Any()).Return("http://test-url.com", make(map[string][]string), nil) - mocks.agentAdapter.EXPECT().CallTraceAgent(gomock.Any(), gomock.Any(), gomock.Any()).Return(int64(123), nil) + mocks.agentAdapter.EXPECT().CallTraceAgent(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(int64(123), nil) mocks.publisher.EXPECT().PublishExptExportCSVEvent(gomock.Any(), gomock.Any(), gomock.Any()).Return(errors.New("publish error")) mocks.repo.EXPECT().UpdateAnalysisRecord(gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(func(ctx context.Context, record *entity.ExptInsightAnalysisRecord, opts ...db.Option) error { assert.Equal(t, entity.InsightAnalysisStatus_Failed, record.Status) @@ -325,7 +325,7 @@ func TestExptInsightAnalysisServiceImpl_GenAnalysisReport(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { tt.setup() - err := service.GenAnalysisReport(ctx, tt.spaceID, tt.exptID, tt.recordID, tt.createAt) + err := service.GenAnalysisReport(ctx, tt.spaceID, tt.exptID, tt.recordID, tt.createAt, 0, 0) if tt.wantErr { assert.Error(t, err) } else { diff --git a/backend/modules/evaluation/domain/service/mocks/insight_analysis.go b/backend/modules/evaluation/domain/service/mocks/insight_analysis.go index 78d1223d8..7c8ad5c62 100644 --- a/backend/modules/evaluation/domain/service/mocks/insight_analysis.go +++ b/backend/modules/evaluation/domain/service/mocks/insight_analysis.go @@ -36,18 +36,18 @@ func (m *MockIExptInsightAnalysisService) EXPECT() *MockIExptInsightAnalysisServ } // CreateAnalysisRecord mocks base method. -func (m *MockIExptInsightAnalysisService) CreateAnalysisRecord(arg0 context.Context, arg1 *entity.ExptInsightAnalysisRecord, arg2 *entity.Session) (int64, error) { +func (m *MockIExptInsightAnalysisService) CreateAnalysisRecord(arg0 context.Context, arg1 *entity.ExptInsightAnalysisRecord, arg2 *entity.Session, arg3, arg4 int64) (int64, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "CreateAnalysisRecord", arg0, arg1, arg2) + ret := m.ctrl.Call(m, "CreateAnalysisRecord", arg0, arg1, arg2, arg3, arg4) ret0, _ := ret[0].(int64) ret1, _ := ret[1].(error) return ret0, ret1 } // CreateAnalysisRecord indicates an expected call of CreateAnalysisRecord. -func (mr *MockIExptInsightAnalysisServiceMockRecorder) CreateAnalysisRecord(arg0, arg1, arg2 interface{}) *gomock.Call { +func (mr *MockIExptInsightAnalysisServiceMockRecorder) CreateAnalysisRecord(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateAnalysisRecord", reflect.TypeOf((*MockIExptInsightAnalysisService)(nil).CreateAnalysisRecord), arg0, arg1, arg2) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateAnalysisRecord", reflect.TypeOf((*MockIExptInsightAnalysisService)(nil).CreateAnalysisRecord), arg0, arg1, arg2, arg3, arg4) } // DeleteAnalysisRecord mocks base method. @@ -79,17 +79,17 @@ func (mr *MockIExptInsightAnalysisServiceMockRecorder) FeedbackExptInsightAnalys } // GenAnalysisReport mocks base method. -func (m *MockIExptInsightAnalysisService) GenAnalysisReport(arg0 context.Context, arg1, arg2, arg3, arg4 int64) error { +func (m *MockIExptInsightAnalysisService) GenAnalysisReport(arg0 context.Context, arg1, arg2, arg3, arg4, arg5, arg6 int64) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GenAnalysisReport", arg0, arg1, arg2, arg3, arg4) + ret := m.ctrl.Call(m, "GenAnalysisReport", arg0, arg1, arg2, arg3, arg4, arg5, arg6) ret0, _ := ret[0].(error) return ret0 } // GenAnalysisReport indicates an expected call of GenAnalysisReport. -func (mr *MockIExptInsightAnalysisServiceMockRecorder) GenAnalysisReport(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { +func (mr *MockIExptInsightAnalysisServiceMockRecorder) GenAnalysisReport(arg0, arg1, arg2, arg3, arg4, arg5, arg6 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GenAnalysisReport", reflect.TypeOf((*MockIExptInsightAnalysisService)(nil).GenAnalysisReport), arg0, arg1, arg2, arg3, arg4) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GenAnalysisReport", reflect.TypeOf((*MockIExptInsightAnalysisService)(nil).GenAnalysisReport), arg0, arg1, arg2, arg3, arg4, arg5, arg6) } // GetAnalysisRecordByID mocks base method. diff --git a/backend/modules/evaluation/infra/rpc/agent/agent_test.go b/backend/modules/evaluation/infra/rpc/agent/agent_test.go index 295820750..eaa88f63c 100644 --- a/backend/modules/evaluation/infra/rpc/agent/agent_test.go +++ b/backend/modules/evaluation/infra/rpc/agent/agent_test.go @@ -34,7 +34,7 @@ func TestAgentAdapter_CallTraceAgent(t *testing.T) { ctx := context.Background() adapter, ctx := tt.setup(ctx) - result, err := adapter.CallTraceAgent(ctx, 123, "http://example.com") + result, err := adapter.CallTraceAgent(ctx, 123, "http://example.com", 0, 0) if tt.wantErr { assert.Error(t, err) From 10c7cfa22562d2abac8c584bdc32bec9216a5df6 Mon Sep 17 00:00:00 2001 From: xueyizheng Date: Mon, 3 Nov 2025 22:07:00 +0800 Subject: [PATCH 03/21] fix time in miliseconds --- backend/modules/evaluation/application/experiment_app.go | 4 ++-- .../evaluation/domain/service/insight_analysis_impl.go | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/backend/modules/evaluation/application/experiment_app.go b/backend/modules/evaluation/application/experiment_app.go index 39ed60669..8d5306156 100644 --- a/backend/modules/evaluation/application/experiment_app.go +++ b/backend/modules/evaluation/application/experiment_app.go @@ -1266,10 +1266,10 @@ func (e *experimentApplication) InsightAnalysisExperiment(ctx context.Context, r var startTime, endTime *int64 if got.StartAt != nil { - startTime = gptr.Of(got.StartAt.Unix()) + startTime = gptr.Of(got.StartAt.UnixMilli()) } if got.EndAt != nil { - endTime = gptr.Of(got.EndAt.Unix()) + endTime = gptr.Of(got.EndAt.UnixMilli()) } recordID, err := e.CreateAnalysisRecord(ctx, &entity.ExptInsightAnalysisRecord{ diff --git a/backend/modules/evaluation/domain/service/insight_analysis_impl.go b/backend/modules/evaluation/domain/service/insight_analysis_impl.go index 1c83290f0..76b4295f9 100644 --- a/backend/modules/evaluation/domain/service/insight_analysis_impl.go +++ b/backend/modules/evaluation/domain/service/insight_analysis_impl.go @@ -142,8 +142,8 @@ func (e ExptInsightAnalysisServiceImpl) GenAnalysisReport(ctx context.Context, s SpaceID: spaceID, ExportScene: entity.ExportSceneInsightAnalysis, CreatedAt: CreateAt, - ExptStartTime: startTime, // 传递开始时间 - ExptEndTime: endTime, // 传递结束时间 + ExptStartTime: startTime, + ExptEndTime: endTime, } err = e.exptPublisher.PublishExptExportCSVEvent(ctx, exportEvent, gptr.Of(time.Minute*3)) if err != nil { From a79fa8135df56bf9637e579b24462365071938e8 Mon Sep 17 00:00:00 2001 From: xueyizheng Date: Mon, 10 Nov 2025 20:01:00 +0800 Subject: [PATCH 04/21] running for 3h+ is thought failed --- .../domain/entity/expt_insight_analysis_record.go | 4 ++++ .../evaluation/domain/service/insight_analysis_impl.go | 8 ++++++++ 2 files changed, 12 insertions(+) diff --git a/backend/modules/evaluation/domain/entity/expt_insight_analysis_record.go b/backend/modules/evaluation/domain/entity/expt_insight_analysis_record.go index ff35af7c8..3f2272f1f 100644 --- a/backend/modules/evaluation/domain/entity/expt_insight_analysis_record.go +++ b/backend/modules/evaluation/domain/entity/expt_insight_analysis_record.go @@ -14,6 +14,10 @@ const ( InsightAnalysisStatus_Failed InsightAnalysisStatus = 3 ) +const ( + ThreeHour = 3 * time.Hour +) + type ExptInsightAnalysisRecord struct { ID int64 SpaceID int64 diff --git a/backend/modules/evaluation/domain/service/insight_analysis_impl.go b/backend/modules/evaluation/domain/service/insight_analysis_impl.go index 76b4295f9..d89771652 100644 --- a/backend/modules/evaluation/domain/service/insight_analysis_impl.go +++ b/backend/modules/evaluation/domain/service/insight_analysis_impl.go @@ -158,6 +158,14 @@ func (e ExptInsightAnalysisServiceImpl) checkAnalysisReportGenStatus(ctx context if err != nil { return err } + + // 超过3小时,未生成分析报告,认为是失败 + if status == entity.ReportStatus_Running && record.CreatedAt.Add(entity.ThreeHour).Unix() >= CreateAt { + record.Status = entity.InsightAnalysisStatus_Failed + logs.CtxWarn(ctx, "checkAnalysisReportGenStatus found timeout event, expt_id: %v, record_id: %v", record.ExptID, record.ID) + return e.repo.UpdateAnalysisRecord(ctx, record) + } + if status == entity.ReportStatus_Failed { record.Status = entity.InsightAnalysisStatus_Failed return e.repo.UpdateAnalysisRecord(ctx, record) From 034fd67792c65f26e6630cc9c739350c47aa1026 Mon Sep 17 00:00:00 2001 From: xueyizheng Date: Mon, 10 Nov 2025 20:54:33 +0800 Subject: [PATCH 05/21] fix time out --- .../modules/evaluation/domain/service/insight_analysis_impl.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/modules/evaluation/domain/service/insight_analysis_impl.go b/backend/modules/evaluation/domain/service/insight_analysis_impl.go index d89771652..90916b03c 100644 --- a/backend/modules/evaluation/domain/service/insight_analysis_impl.go +++ b/backend/modules/evaluation/domain/service/insight_analysis_impl.go @@ -160,7 +160,7 @@ func (e ExptInsightAnalysisServiceImpl) checkAnalysisReportGenStatus(ctx context } // 超过3小时,未生成分析报告,认为是失败 - if status == entity.ReportStatus_Running && record.CreatedAt.Add(entity.ThreeHour).Unix() >= CreateAt { + if status == entity.ReportStatus_Running && record.CreatedAt.Add(entity.ThreeHour).Unix() <= time.Now().Unix() { record.Status = entity.InsightAnalysisStatus_Failed logs.CtxWarn(ctx, "checkAnalysisReportGenStatus found timeout event, expt_id: %v, record_id: %v", record.ExptID, record.ID) return e.repo.UpdateAnalysisRecord(ctx, record) From d4ee5af6ef602ea27becd98f0ae6ca7864785845 Mon Sep 17 00:00:00 2001 From: xueyizheng Date: Mon, 10 Nov 2025 21:32:42 +0800 Subject: [PATCH 06/21] fix session, try another way to inject CreateBy --- backend/modules/evaluation/application/experiment_app.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/backend/modules/evaluation/application/experiment_app.go b/backend/modules/evaluation/application/experiment_app.go index 8d5306156..5dc3e98e8 100644 --- a/backend/modules/evaluation/application/experiment_app.go +++ b/backend/modules/evaluation/application/experiment_app.go @@ -10,6 +10,7 @@ import ( "time" "github.com/bytedance/gg/gptr" + loopsession "github.com/coze-dev/coze-loop/backend/infra/middleware/session" "github.com/coze-dev/coze-loop/backend/infra/backoff" "github.com/coze-dev/coze-loop/backend/infra/idgen" @@ -1247,6 +1248,12 @@ func (e *experimentApplication) InsightAnalysisExperiment(ctx context.Context, r session = &entity.Session{ UserID: strconv.FormatInt(gptr.Indirect(req.Session.UserID), 10), } + } else { + logs.CtxInfo(ctx, "InsightAnalysisExperiment found empty userID, expt_id: %v, workspace_id: %v", req.GetExptID(), req.GetWorkspaceID()) + userId := loopsession.UserIDInCtxOrEmpty(ctx) + session = &entity.Session{ + UserID: userId, + } } got, err := e.manager.Get(ctx, req.GetExptID(), req.GetWorkspaceID(), session) if err != nil { From 00647a90fe587dbed64114f77acba3830e93dfde Mon Sep 17 00:00:00 2001 From: xueyizheng Date: Mon, 10 Nov 2025 22:03:11 +0800 Subject: [PATCH 07/21] Revert "fix session, try another way to inject CreateBy" This reverts commit 3416ed5eb2b11fd8b5c6b2b2ac9d440a11e940b9. --- backend/modules/evaluation/application/experiment_app.go | 7 ------- 1 file changed, 7 deletions(-) diff --git a/backend/modules/evaluation/application/experiment_app.go b/backend/modules/evaluation/application/experiment_app.go index 5dc3e98e8..8d5306156 100644 --- a/backend/modules/evaluation/application/experiment_app.go +++ b/backend/modules/evaluation/application/experiment_app.go @@ -10,7 +10,6 @@ import ( "time" "github.com/bytedance/gg/gptr" - loopsession "github.com/coze-dev/coze-loop/backend/infra/middleware/session" "github.com/coze-dev/coze-loop/backend/infra/backoff" "github.com/coze-dev/coze-loop/backend/infra/idgen" @@ -1248,12 +1247,6 @@ func (e *experimentApplication) InsightAnalysisExperiment(ctx context.Context, r session = &entity.Session{ UserID: strconv.FormatInt(gptr.Indirect(req.Session.UserID), 10), } - } else { - logs.CtxInfo(ctx, "InsightAnalysisExperiment found empty userID, expt_id: %v, workspace_id: %v", req.GetExptID(), req.GetWorkspaceID()) - userId := loopsession.UserIDInCtxOrEmpty(ctx) - session = &entity.Session{ - UserID: userId, - } } got, err := e.manager.Get(ctx, req.GetExptID(), req.GetWorkspaceID(), session) if err != nil { From 84abd5cd4f6406066ec0e4d1061b928cbf689614 Mon Sep 17 00:00:00 2001 From: xueyizheng Date: Tue, 11 Nov 2025 11:46:03 +0800 Subject: [PATCH 08/21] fix timeout --- .../evaluation/domain/service/insight_analysis_impl.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/backend/modules/evaluation/domain/service/insight_analysis_impl.go b/backend/modules/evaluation/domain/service/insight_analysis_impl.go index 90916b03c..acd734a61 100644 --- a/backend/modules/evaluation/domain/service/insight_analysis_impl.go +++ b/backend/modules/evaluation/domain/service/insight_analysis_impl.go @@ -207,6 +207,15 @@ func (e ExptInsightAnalysisServiceImpl) GetAnalysisRecordByID(ctx context.Contex return nil, err } + if analysisRecord.Status == entity.InsightAnalysisStatus_Running && analysisRecord.CreatedAt.Add(entity.ThreeHour).Unix() < time.Now().Unix() { + analysisRecord.Status = entity.InsightAnalysisStatus_Failed + err = e.repo.UpdateAnalysisRecord(ctx, analysisRecord) + if err != nil { + logs.CtxError(ctx, "GetAnalysisRecordByID: UpdateAnalysisRecord failed: %v", err) + } + return analysisRecord, err + } + if analysisRecord.Status == entity.InsightAnalysisStatus_Running || analysisRecord.Status == entity.InsightAnalysisStatus_Failed { return analysisRecord, nil From 5f03ef73f757651d0812680ea509eab27408492d Mon Sep 17 00:00:00 2001 From: xueyizheng Date: Tue, 11 Nov 2025 19:33:10 +0800 Subject: [PATCH 09/21] timeout change to 2hour --- .../evaluation/domain/entity/expt_insight_analysis_record.go | 2 +- .../evaluation/domain/service/insight_analysis_impl.go | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/backend/modules/evaluation/domain/entity/expt_insight_analysis_record.go b/backend/modules/evaluation/domain/entity/expt_insight_analysis_record.go index 3f2272f1f..bfb50f901 100644 --- a/backend/modules/evaluation/domain/entity/expt_insight_analysis_record.go +++ b/backend/modules/evaluation/domain/entity/expt_insight_analysis_record.go @@ -15,7 +15,7 @@ const ( ) const ( - ThreeHour = 3 * time.Hour + InsightAnalysisRunningTimeout = 2 * time.Hour ) type ExptInsightAnalysisRecord struct { diff --git a/backend/modules/evaluation/domain/service/insight_analysis_impl.go b/backend/modules/evaluation/domain/service/insight_analysis_impl.go index acd734a61..ca46d1be9 100644 --- a/backend/modules/evaluation/domain/service/insight_analysis_impl.go +++ b/backend/modules/evaluation/domain/service/insight_analysis_impl.go @@ -160,7 +160,7 @@ func (e ExptInsightAnalysisServiceImpl) checkAnalysisReportGenStatus(ctx context } // 超过3小时,未生成分析报告,认为是失败 - if status == entity.ReportStatus_Running && record.CreatedAt.Add(entity.ThreeHour).Unix() <= time.Now().Unix() { + if status == entity.ReportStatus_Running && record.CreatedAt.Add(entity.InsightAnalysisRunningTimeout).Unix() <= time.Now().Unix() { record.Status = entity.InsightAnalysisStatus_Failed logs.CtxWarn(ctx, "checkAnalysisReportGenStatus found timeout event, expt_id: %v, record_id: %v", record.ExptID, record.ID) return e.repo.UpdateAnalysisRecord(ctx, record) @@ -207,7 +207,7 @@ func (e ExptInsightAnalysisServiceImpl) GetAnalysisRecordByID(ctx context.Contex return nil, err } - if analysisRecord.Status == entity.InsightAnalysisStatus_Running && analysisRecord.CreatedAt.Add(entity.ThreeHour).Unix() < time.Now().Unix() { + if analysisRecord.Status == entity.InsightAnalysisStatus_Running && analysisRecord.CreatedAt.Add(entity.InsightAnalysisRunningTimeout).Unix() < time.Now().Unix() { analysisRecord.Status = entity.InsightAnalysisStatus_Failed err = e.repo.UpdateAnalysisRecord(ctx, analysisRecord) if err != nil { From 42c6e7f1428616390a3854557c61b90818d50337 Mon Sep 17 00:00:00 2001 From: xueyizheng Date: Wed, 12 Nov 2025 12:17:46 +0800 Subject: [PATCH 10/21] =?UTF-8?q?feat:=20[Coda]=20=E5=BC=BA=E5=88=B6?= =?UTF-8?q?=E8=AF=BB=E4=B8=BB=E5=BA=93=E6=94=AF=E6=92=91=E6=B4=9E=E5=AF=9F?= =?UTF-8?q?=E5=8F=8D=E9=A6=88=20(LogID:=20202511121049110100911082412387DA?= =?UTF-8?q?E)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Coda --- .../platestwrite/latest_write_tracker.go | 3 + .../evaluation/application/wire_gen.go | 4 +- .../expt_insight_analysis_record.go | 141 ++++++++++++++++-- .../expt_insight_analysis_record_test.go | 131 +++++++++++++++- .../expt_insight_analysis_feedback_comment.go | 25 +++- .../expt_insight_analysis_feedback_vote.go | 8 +- .../mysql/expt_insight_analysis_record.go | 8 +- .../expt_insight_analysis_feedback_comment.go | 77 ++++++---- .../expt_insight_analysis_feedback_vote.go | 49 +++--- .../mocks/expt_insight_analysis_record.go | 57 ++++--- 10 files changed, 388 insertions(+), 115 deletions(-) diff --git a/backend/infra/platestwrite/latest_write_tracker.go b/backend/infra/platestwrite/latest_write_tracker.go index 814848156..69b6cd859 100644 --- a/backend/infra/platestwrite/latest_write_tracker.go +++ b/backend/infra/platestwrite/latest_write_tracker.go @@ -137,4 +137,7 @@ const ( ResourceTypeTarget ResourceType = "eval_target" ResourceTypeTargetVersion ResourceType = "eval_target_version" ResourceTypeEvaluator ResourceType = "evaluator" + + ResourceTypeExptInsightAnalysisRecord ResourceType = "expt_insight_analysis_record" + ResourceTypeExptInsightAnalysisFeedback ResourceType = "expt_insight_analysis_feedback" ) diff --git a/backend/modules/evaluation/application/wire_gen.go b/backend/modules/evaluation/application/wire_gen.go index 78f44e7fd..4237c878a 100644 --- a/backend/modules/evaluation/application/wire_gen.go +++ b/backend/modules/evaluation/application/wire_gen.go @@ -159,7 +159,7 @@ func InitExperimentApplication(ctx context.Context, idgen2 idgen.IIDGenerator, d iExptInsightAnalysisRecordDAO := mysql.NewExptInsightAnalysisRecordDAO(db2) iExptInsightAnalysisFeedbackCommentDAO := mysql.NewExptInsightAnalysisFeedbackCommentDAO(db2) iExptInsightAnalysisFeedbackVoteDAO := mysql.NewExptInsightAnalysisFeedbackVoteDAO(db2) - iExptInsightAnalysisRecordRepo := experiment.NewExptInsightAnalysisRecordRepo(iExptInsightAnalysisRecordDAO, iExptInsightAnalysisFeedbackCommentDAO, iExptInsightAnalysisFeedbackVoteDAO, idgen2) + iExptInsightAnalysisRecordRepo := experiment.NewExptInsightAnalysisRecordRepo(iExptInsightAnalysisRecordDAO, iExptInsightAnalysisFeedbackCommentDAO, iExptInsightAnalysisFeedbackVoteDAO, idgen2, iLatestWriteTracker) iAgentAdapter := agent.NewAgentAdapter() iNotifyRPCAdapter := notify.NewNotifyRPCAdapter() iExptInsightAnalysisService := service.NewInsightAnalysisService(iExptInsightAnalysisRecordRepo, exptEventPublisher, objectStorage, iAgentAdapter, iExptResultExportService, iNotifyRPCAdapter, iUserProvider, iExperimentRepo) @@ -337,7 +337,7 @@ func InitEvalOpenAPIApplication(ctx context.Context, configFactory conf.IConfigL iExptInsightAnalysisRecordDAO := mysql.NewExptInsightAnalysisRecordDAO(db2) iExptInsightAnalysisFeedbackCommentDAO := mysql.NewExptInsightAnalysisFeedbackCommentDAO(db2) iExptInsightAnalysisFeedbackVoteDAO := mysql.NewExptInsightAnalysisFeedbackVoteDAO(db2) - iExptInsightAnalysisRecordRepo := experiment.NewExptInsightAnalysisRecordRepo(iExptInsightAnalysisRecordDAO, iExptInsightAnalysisFeedbackCommentDAO, iExptInsightAnalysisFeedbackVoteDAO, idgen2) + iExptInsightAnalysisRecordRepo := experiment.NewExptInsightAnalysisRecordRepo(iExptInsightAnalysisRecordDAO, iExptInsightAnalysisFeedbackCommentDAO, iExptInsightAnalysisFeedbackVoteDAO, idgen2, iLatestWriteTracker) iAgentAdapter := agent.NewAgentAdapter() iNotifyRPCAdapter := notify.NewNotifyRPCAdapter() iExptInsightAnalysisService := service.NewInsightAnalysisService(iExptInsightAnalysisRecordRepo, exptEventPublisher, objectStorage, iAgentAdapter, iExptResultExportService, iNotifyRPCAdapter, iUserProvider, iExperimentRepo) diff --git a/backend/modules/evaluation/infra/repo/experiment/expt_insight_analysis_record.go b/backend/modules/evaluation/infra/repo/experiment/expt_insight_analysis_record.go index de1355145..ff0c48ea2 100644 --- a/backend/modules/evaluation/infra/repo/experiment/expt_insight_analysis_record.go +++ b/backend/modules/evaluation/infra/repo/experiment/expt_insight_analysis_record.go @@ -5,9 +5,11 @@ package experiment import ( "context" + "fmt" "github.com/coze-dev/coze-loop/backend/infra/db" "github.com/coze-dev/coze-loop/backend/infra/idgen" + "github.com/coze-dev/coze-loop/backend/infra/platestwrite" "github.com/coze-dev/coze-loop/backend/modules/evaluation/domain/entity" "github.com/coze-dev/coze-loop/backend/modules/evaluation/domain/repo" "github.com/coze-dev/coze-loop/backend/modules/evaluation/infra/repo/experiment/mysql" @@ -19,6 +21,7 @@ type ExptInsightAnalysisRecordRepo struct { exptInsightAnalysisFeedbackCommentDAO mysql.IExptInsightAnalysisFeedbackCommentDAO exptInsightAnalysisFeedbackVoteDAO mysql.IExptInsightAnalysisFeedbackVoteDAO idgenerator idgen.IIDGenerator + writeTracker platestwrite.ILatestWriteTracker } func NewExptInsightAnalysisRecordRepo( @@ -26,12 +29,14 @@ func NewExptInsightAnalysisRecordRepo( exptInsightAnalysisFeedbackCommentDAO mysql.IExptInsightAnalysisFeedbackCommentDAO, exptInsightAnalysisFeedbackVoteDAO mysql.IExptInsightAnalysisFeedbackVoteDAO, idgenerator idgen.IIDGenerator, + writeTracker platestwrite.ILatestWriteTracker, ) repo.IExptInsightAnalysisRecordRepo { return &ExptInsightAnalysisRecordRepo{ exptInsightAnalysisRecordDAO: exptInsightAnalysisRecordDAO, exptInsightAnalysisFeedbackCommentDAO: exptInsightAnalysisFeedbackCommentDAO, exptInsightAnalysisFeedbackVoteDAO: exptInsightAnalysisFeedbackVoteDAO, idgenerator: idgenerator, + writeTracker: writeTracker, } } @@ -47,15 +52,34 @@ func (e ExptInsightAnalysisRecordRepo) CreateAnalysisRecord(ctx context.Context, return 0, err } + if e.writeTracker != nil { + e.writeTracker.SetWriteFlag(ctx, platestwrite.ResourceTypeExptInsightAnalysisRecord, id, + platestwrite.SetWithSearchParam(buildRecordSearchParam(record.SpaceID, record.ExptID))) + } + return id, nil } func (e ExptInsightAnalysisRecordRepo) UpdateAnalysisRecord(ctx context.Context, record *entity.ExptInsightAnalysisRecord, opts ...db.Option) error { - return e.exptInsightAnalysisRecordDAO.Update(ctx, convert.ExptInsightAnalysisRecordDOToPO(record), opts...) + if err := e.exptInsightAnalysisRecordDAO.Update(ctx, convert.ExptInsightAnalysisRecordDOToPO(record), opts...); err != nil { + return err + } + + if e.writeTracker != nil { + e.writeTracker.SetWriteFlag(ctx, platestwrite.ResourceTypeExptInsightAnalysisRecord, record.ID, + platestwrite.SetWithSearchParam(buildRecordSearchParam(record.SpaceID, record.ExptID))) + } + + return nil } func (e ExptInsightAnalysisRecordRepo) GetAnalysisRecordByID(ctx context.Context, spaceID, exptID, recordID int64) (*entity.ExptInsightAnalysisRecord, error) { - po, err := e.exptInsightAnalysisRecordDAO.GetByID(ctx, spaceID, exptID, recordID) + opts := make([]db.Option, 0) + if e.needForceMasterByRecord(ctx, platestwrite.ResourceTypeExptInsightAnalysisRecord, recordID, buildRecordSearchParam(spaceID, exptID)) { + opts = append(opts, db.WithMaster()) + } + + po, err := e.exptInsightAnalysisRecordDAO.GetByID(ctx, spaceID, exptID, recordID, opts...) if err != nil { return nil, err } @@ -64,7 +88,11 @@ func (e ExptInsightAnalysisRecordRepo) GetAnalysisRecordByID(ctx context.Context } func (e ExptInsightAnalysisRecordRepo) ListAnalysisRecord(ctx context.Context, spaceID, exptID int64, page entity.Page) ([]*entity.ExptInsightAnalysisRecord, int64, error) { - pos, total, err := e.exptInsightAnalysisRecordDAO.List(ctx, spaceID, exptID, page) + opts := make([]db.Option, 0) + if e.needForceMasterByRecord(ctx, platestwrite.ResourceTypeExptInsightAnalysisRecord, 0, buildRecordSearchParam(spaceID, exptID)) { + opts = append(opts, db.WithMaster()) + } + pos, total, err := e.exptInsightAnalysisRecordDAO.List(ctx, spaceID, exptID, page, opts...) if err != nil { return nil, 0, err } @@ -77,7 +105,14 @@ func (e ExptInsightAnalysisRecordRepo) ListAnalysisRecord(ctx context.Context, s } func (e ExptInsightAnalysisRecordRepo) DeleteAnalysisRecord(ctx context.Context, spaceID, exptID, recordID int64) error { - return e.exptInsightAnalysisRecordDAO.Delete(ctx, spaceID, exptID, recordID) + if err := e.exptInsightAnalysisRecordDAO.Delete(ctx, spaceID, exptID, recordID); err != nil { + return err + } + if e.writeTracker != nil { + e.writeTracker.SetWriteFlag(ctx, platestwrite.ResourceTypeExptInsightAnalysisRecord, recordID, + platestwrite.SetWithSearchParam(buildRecordSearchParam(spaceID, exptID))) + } + return nil } func (e ExptInsightAnalysisRecordRepo) CreateFeedbackComment(ctx context.Context, feedbackComment *entity.ExptInsightAnalysisFeedbackComment, opts ...db.Option) error { @@ -86,15 +121,33 @@ func (e ExptInsightAnalysisRecordRepo) CreateFeedbackComment(ctx context.Context return err } feedbackComment.ID = id - return e.exptInsightAnalysisFeedbackCommentDAO.Create(ctx, convert.ExptInsightAnalysisFeedbackCommentDOToPO(feedbackComment), opts...) + if err := e.exptInsightAnalysisFeedbackCommentDAO.Create(ctx, convert.ExptInsightAnalysisFeedbackCommentDOToPO(feedbackComment), opts...); err != nil { + return err + } + if e.writeTracker != nil { + e.writeTracker.SetWriteFlag(ctx, platestwrite.ResourceTypeExptInsightAnalysisFeedback, feedbackComment.AnalysisRecordID, + platestwrite.SetWithSearchParam(buildFeedbackSearchParam(feedbackComment.SpaceID, feedbackComment.ExptID, feedbackComment.AnalysisRecordID))) + } + return nil } func (e ExptInsightAnalysisRecordRepo) UpdateFeedbackComment(ctx context.Context, feedbackComment *entity.ExptInsightAnalysisFeedbackComment, opts ...db.Option) error { - return e.exptInsightAnalysisFeedbackCommentDAO.Update(ctx, convert.ExptInsightAnalysisFeedbackCommentDOToPO(feedbackComment), opts...) + if err := e.exptInsightAnalysisFeedbackCommentDAO.Update(ctx, convert.ExptInsightAnalysisFeedbackCommentDOToPO(feedbackComment), opts...); err != nil { + return err + } + if e.writeTracker != nil { + e.writeTracker.SetWriteFlag(ctx, platestwrite.ResourceTypeExptInsightAnalysisFeedback, feedbackComment.AnalysisRecordID, + platestwrite.SetWithSearchParam(buildFeedbackSearchParam(feedbackComment.SpaceID, feedbackComment.ExptID, feedbackComment.AnalysisRecordID))) + } + return nil } func (e ExptInsightAnalysisRecordRepo) GetFeedbackCommentByRecordID(ctx context.Context, spaceID, exptID, recordID int64, opts ...db.Option) (*entity.ExptInsightAnalysisFeedbackComment, error) { - po, err := e.exptInsightAnalysisFeedbackCommentDAO.GetByRecordID(ctx, spaceID, exptID, recordID, opts...) + innerOpts := append([]db.Option{}, opts...) + if e.needForceMasterByRecord(ctx, platestwrite.ResourceTypeExptInsightAnalysisFeedback, recordID, buildFeedbackSearchParam(spaceID, exptID, recordID)) && !db.ContainWithMasterOpt(innerOpts) { + innerOpts = append(innerOpts, db.WithMaster()) + } + po, err := e.exptInsightAnalysisFeedbackCommentDAO.GetByRecordID(ctx, spaceID, exptID, recordID, innerOpts...) if err != nil { return nil, err } @@ -102,7 +155,22 @@ func (e ExptInsightAnalysisRecordRepo) GetFeedbackCommentByRecordID(ctx context. } func (e ExptInsightAnalysisRecordRepo) DeleteFeedbackComment(ctx context.Context, spaceID, exptID, commentID int64) error { - return e.exptInsightAnalysisFeedbackCommentDAO.Delete(ctx, spaceID, exptID, commentID) + po, err := e.exptInsightAnalysisFeedbackCommentDAO.GetByID(ctx, spaceID, exptID, commentID, db.WithMaster()) + if err != nil { + return err + } + if err := e.exptInsightAnalysisFeedbackCommentDAO.Delete(ctx, spaceID, exptID, commentID); err != nil { + return err + } + recordID := int64(0) + if po.AnalysisRecordID != nil { + recordID = *po.AnalysisRecordID + } + if e.writeTracker != nil && recordID > 0 { + e.writeTracker.SetWriteFlag(ctx, platestwrite.ResourceTypeExptInsightAnalysisFeedback, recordID, + platestwrite.SetWithSearchParam(buildFeedbackSearchParam(po.SpaceID, po.ExptID, recordID))) + } + return nil } func (e ExptInsightAnalysisRecordRepo) CreateFeedbackVote(ctx context.Context, feedbackVote *entity.ExptInsightAnalysisFeedbackVote, opts ...db.Option) error { @@ -111,15 +179,33 @@ func (e ExptInsightAnalysisRecordRepo) CreateFeedbackVote(ctx context.Context, f return err } feedbackVote.ID = id - return e.exptInsightAnalysisFeedbackVoteDAO.Create(ctx, convert.ExptInsightAnalysisFeedbackVoteDOToPO(feedbackVote), opts...) + if err := e.exptInsightAnalysisFeedbackVoteDAO.Create(ctx, convert.ExptInsightAnalysisFeedbackVoteDOToPO(feedbackVote), opts...); err != nil { + return err + } + if e.writeTracker != nil { + e.writeTracker.SetWriteFlag(ctx, platestwrite.ResourceTypeExptInsightAnalysisFeedback, feedbackVote.AnalysisRecordID, + platestwrite.SetWithSearchParam(buildFeedbackSearchParam(feedbackVote.SpaceID, feedbackVote.ExptID, feedbackVote.AnalysisRecordID))) + } + return nil } func (e ExptInsightAnalysisRecordRepo) UpdateFeedbackVote(ctx context.Context, feedbackVote *entity.ExptInsightAnalysisFeedbackVote, opts ...db.Option) error { - return e.exptInsightAnalysisFeedbackVoteDAO.Update(ctx, convert.ExptInsightAnalysisFeedbackVoteDOToPO(feedbackVote), opts...) + if err := e.exptInsightAnalysisFeedbackVoteDAO.Update(ctx, convert.ExptInsightAnalysisFeedbackVoteDOToPO(feedbackVote), opts...); err != nil { + return err + } + if e.writeTracker != nil { + e.writeTracker.SetWriteFlag(ctx, platestwrite.ResourceTypeExptInsightAnalysisFeedback, feedbackVote.AnalysisRecordID, + platestwrite.SetWithSearchParam(buildFeedbackSearchParam(feedbackVote.SpaceID, feedbackVote.ExptID, feedbackVote.AnalysisRecordID))) + } + return nil } func (e ExptInsightAnalysisRecordRepo) GetFeedbackVoteByUser(ctx context.Context, spaceID, exptID, recordID int64, userID string, opts ...db.Option) (*entity.ExptInsightAnalysisFeedbackVote, error) { - po, err := e.exptInsightAnalysisFeedbackVoteDAO.GetByUser(ctx, spaceID, exptID, recordID, userID, opts...) + innerOpts := append([]db.Option{}, opts...) + if e.needForceMasterByRecord(ctx, platestwrite.ResourceTypeExptInsightAnalysisFeedback, recordID, buildFeedbackSearchParam(spaceID, exptID, recordID)) && !db.ContainWithMasterOpt(innerOpts) { + innerOpts = append(innerOpts, db.WithMaster()) + } + po, err := e.exptInsightAnalysisFeedbackVoteDAO.GetByUser(ctx, spaceID, exptID, recordID, userID, innerOpts...) if err != nil { return nil, err } @@ -127,11 +213,19 @@ func (e ExptInsightAnalysisRecordRepo) GetFeedbackVoteByUser(ctx context.Context } func (e ExptInsightAnalysisRecordRepo) CountFeedbackVote(ctx context.Context, spaceID, exptID, recordID int64) (int64, int64, error) { - return e.exptInsightAnalysisFeedbackVoteDAO.Count(ctx, spaceID, exptID, recordID) + opts := make([]db.Option, 0) + if e.needForceMasterByRecord(ctx, platestwrite.ResourceTypeExptInsightAnalysisFeedback, recordID, buildFeedbackSearchParam(spaceID, exptID, recordID)) { + opts = append(opts, db.WithMaster()) + } + return e.exptInsightAnalysisFeedbackVoteDAO.Count(ctx, spaceID, exptID, recordID, opts...) } func (e ExptInsightAnalysisRecordRepo) List(ctx context.Context, spaceID, exptID, recordID int64, page entity.Page) ([]*entity.ExptInsightAnalysisFeedbackComment, int64, error) { - pos, total, err := e.exptInsightAnalysisFeedbackCommentDAO.List(ctx, spaceID, exptID, recordID, page) + opts := make([]db.Option, 0) + if e.needForceMasterByRecord(ctx, platestwrite.ResourceTypeExptInsightAnalysisFeedback, recordID, buildFeedbackSearchParam(spaceID, exptID, recordID)) { + opts = append(opts, db.WithMaster()) + } + pos, total, err := e.exptInsightAnalysisFeedbackCommentDAO.List(ctx, spaceID, exptID, recordID, page, opts...) if err != nil { return nil, 0, err } @@ -141,3 +235,24 @@ func (e ExptInsightAnalysisRecordRepo) List(ctx context.Context, spaceID, exptID } return dos, total, nil } + +func (e ExptInsightAnalysisRecordRepo) needForceMasterByRecord(ctx context.Context, resourceType platestwrite.ResourceType, resourceID int64, searchParam string) bool { + if e.writeTracker == nil { + return false + } + if resourceID > 0 && e.writeTracker.CheckWriteFlagByID(ctx, resourceType, resourceID) { + return true + } + if searchParam != "" && e.writeTracker.CheckWriteFlagBySearchParam(ctx, resourceType, searchParam) { + return true + } + return false +} + +func buildRecordSearchParam(spaceID, exptID int64) string { + return fmt.Sprintf("%d:%d", spaceID, exptID) +} + +func buildFeedbackSearchParam(spaceID, exptID, recordID int64) string { + return fmt.Sprintf("%d:%d:%d", spaceID, exptID, recordID) +} diff --git a/backend/modules/evaluation/infra/repo/experiment/expt_insight_analysis_record_test.go b/backend/modules/evaluation/infra/repo/experiment/expt_insight_analysis_record_test.go index a8070373b..30a829500 100644 --- a/backend/modules/evaluation/infra/repo/experiment/expt_insight_analysis_record_test.go +++ b/backend/modules/evaluation/infra/repo/experiment/expt_insight_analysis_record_test.go @@ -11,7 +11,9 @@ import ( "github.com/stretchr/testify/assert" "go.uber.org/mock/gomock" + "github.com/coze-dev/coze-loop/backend/infra/db" mockidgen "github.com/coze-dev/coze-loop/backend/infra/idgen/mocks" + platestwritemocks "github.com/coze-dev/coze-loop/backend/infra/platestwrite/mocks" "github.com/coze-dev/coze-loop/backend/modules/evaluation/domain/entity" "github.com/coze-dev/coze-loop/backend/modules/evaluation/infra/repo/experiment/mysql/gorm_gen/model" "github.com/coze-dev/coze-loop/backend/modules/evaluation/infra/repo/experiment/mysql/mocks" @@ -23,6 +25,7 @@ type testMocks struct { feedbackCommentDAO *mocks.MockIExptInsightAnalysisFeedbackCommentDAO feedbackVoteDAO *mocks.MockIExptInsightAnalysisFeedbackVoteDAO idGenerator *mockidgen.MockIIDGenerator + writeTracker *platestwritemocks.MockILatestWriteTracker } func newTestExptInsightAnalysisRecordRepo(ctrl *gomock.Controller) (*ExptInsightAnalysisRecordRepo, *testMocks) { @@ -31,6 +34,7 @@ func newTestExptInsightAnalysisRecordRepo(ctrl *gomock.Controller) (*ExptInsight feedbackCommentDAO: mocks.NewMockIExptInsightAnalysisFeedbackCommentDAO(ctrl), feedbackVoteDAO: mocks.NewMockIExptInsightAnalysisFeedbackVoteDAO(ctrl), idGenerator: mockidgen.NewMockIIDGenerator(ctrl), + writeTracker: platestwritemocks.NewMockILatestWriteTracker(ctrl), } repo := &ExptInsightAnalysisRecordRepo{ @@ -38,16 +42,29 @@ func newTestExptInsightAnalysisRecordRepo(ctrl *gomock.Controller) (*ExptInsight exptInsightAnalysisFeedbackCommentDAO: mocks.feedbackCommentDAO, exptInsightAnalysisFeedbackVoteDAO: mocks.feedbackVoteDAO, idgenerator: mocks.idGenerator, + writeTracker: mocks.writeTracker, } return repo, mocks } +func expectWriteFlagAny(m *testMocks) { + m.writeTracker.EXPECT().SetWriteFlag(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes() +} + +func expectNoWriteFlagRead(m *testMocks) { + m.writeTracker.EXPECT().CheckWriteFlagByID(gomock.Any(), gomock.Any(), gomock.Any()).Return(false).AnyTimes() + m.writeTracker.EXPECT().CheckWriteFlagBySearchParam(gomock.Any(), gomock.Any(), gomock.Any()).Return(false).AnyTimes() +} + func TestExptInsightAnalysisRecordRepo_CreateAnalysisRecord(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() repo, mocks := newTestExptInsightAnalysisRecordRepo(ctrl) + expectWriteFlagAny(mocks) + expectWriteFlagAny(mocks) + expectWriteFlagAny(mocks) record := &entity.ExptInsightAnalysisRecord{ SpaceID: 1, @@ -72,6 +89,9 @@ func TestExptInsightAnalysisRecordRepo_UpdateAnalysisRecord(t *testing.T) { defer ctrl.Finish() repo, mocks := newTestExptInsightAnalysisRecordRepo(ctrl) + expectWriteFlagAny(mocks) + expectWriteFlagAny(mocks) + expectWriteFlagAny(mocks) record := &entity.ExptInsightAnalysisRecord{ ID: 1, @@ -93,8 +113,9 @@ func TestExptInsightAnalysisRecordRepo_GetAnalysisRecordByID(t *testing.T) { defer ctrl.Finish() repo, mocks := newTestExptInsightAnalysisRecordRepo(ctrl) + expectNoWriteFlagRead(mocks) - mocks.analysisRecordDAO.EXPECT().GetByID(gomock.Any(), int64(1), int64(1), int64(1), gomock.Any()).Return(&model.ExptInsightAnalysisRecord{ + mocks.analysisRecordDAO.EXPECT().GetByID(gomock.Any(), int64(1), int64(1), int64(1)).Return(&model.ExptInsightAnalysisRecord{ ID: 1, SpaceID: 1, ExptID: 1, @@ -111,11 +132,34 @@ func TestExptInsightAnalysisRecordRepo_GetAnalysisRecordByID(t *testing.T) { assert.Equal(t, int64(1), record.ID) } +func TestExptInsightAnalysisRecordRepo_GetAnalysisRecordByID_ForceMaster(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + repo, mocks := newTestExptInsightAnalysisRecordRepo(ctrl) + + mocks.writeTracker.EXPECT().CheckWriteFlagByID(gomock.Any(), gomock.Any(), int64(1)).Return(true) + mocks.writeTracker.EXPECT().CheckWriteFlagBySearchParam(gomock.Any(), gomock.Any(), gomock.Any()).Return(false).AnyTimes() + mocks.analysisRecordDAO.EXPECT().GetByID(gomock.Any(), int64(1), int64(1), int64(1), gomock.Any()).DoAndReturn( + func(_ context.Context, _ int64, _ int64, _ int64, opts ...db.Option) (*model.ExptInsightAnalysisRecord, error) { + assert.True(t, db.ContainWithMasterOpt(opts)) + return &model.ExptInsightAnalysisRecord{ID: 1, SpaceID: 1, ExptID: 1}, nil + }, + ) + + record, err := repo.GetAnalysisRecordByID(context.Background(), 1, 1, 1) + + assert.NoError(t, err) + assert.NotNil(t, record) + assert.Equal(t, int64(1), record.ID) +} + func TestExptInsightAnalysisRecordRepo_ListAnalysisRecord(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() repo, mocks := newTestExptInsightAnalysisRecordRepo(ctrl) + expectNoWriteFlagRead(mocks) mocks.analysisRecordDAO.EXPECT().List(gomock.Any(), int64(1), int64(1), entity.NewPage(1, 10)).Return([]*model.ExptInsightAnalysisRecord{ { @@ -140,6 +184,7 @@ func TestExptInsightAnalysisRecordRepo_DeleteAnalysisRecord(t *testing.T) { defer ctrl.Finish() repo, mocks := newTestExptInsightAnalysisRecordRepo(ctrl) + expectWriteFlagAny(mocks) mocks.analysisRecordDAO.EXPECT().Delete(gomock.Any(), int64(1), int64(1), int64(1)).Return(nil) @@ -153,6 +198,7 @@ func TestExptInsightAnalysisRecordRepo_CreateFeedbackComment(t *testing.T) { defer ctrl.Finish() repo, mocks := newTestExptInsightAnalysisRecordRepo(ctrl) + expectWriteFlagAny(mocks) comment := &entity.ExptInsightAnalysisFeedbackComment{ SpaceID: 1, @@ -176,6 +222,7 @@ func TestExptInsightAnalysisRecordRepo_UpdateFeedbackComment(t *testing.T) { defer ctrl.Finish() repo, mocks := newTestExptInsightAnalysisRecordRepo(ctrl) + expectWriteFlagAny(mocks) comment := &entity.ExptInsightAnalysisFeedbackComment{ ID: 1, @@ -197,7 +244,14 @@ func TestExptInsightAnalysisRecordRepo_DeleteFeedbackComment(t *testing.T) { defer ctrl.Finish() repo, mocks := newTestExptInsightAnalysisRecordRepo(ctrl) + expectWriteFlagAny(mocks) + mocks.feedbackCommentDAO.EXPECT().GetByID(gomock.Any(), int64(1), int64(1), int64(1), gomock.Any()).Return(&model.ExptInsightAnalysisFeedbackComment{ + ID: 1, + SpaceID: 1, + ExptID: 1, + AnalysisRecordID: ptr.Of(int64(1)), + }, nil) mocks.feedbackCommentDAO.EXPECT().Delete(gomock.Any(), int64(1), int64(1), int64(1)).Return(nil) err := repo.DeleteFeedbackComment(context.Background(), 1, 1, 1) @@ -205,11 +259,26 @@ func TestExptInsightAnalysisRecordRepo_DeleteFeedbackComment(t *testing.T) { assert.NoError(t, err) } +func TestExptInsightAnalysisRecordRepo_DeleteFeedbackComment_GetByIDError(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + repo, mocks := newTestExptInsightAnalysisRecordRepo(ctrl) + expectWriteFlagAny(mocks) + + mocks.feedbackCommentDAO.EXPECT().GetByID(gomock.Any(), int64(1), int64(1), int64(1), gomock.Any()).Return(nil, assert.AnError) + + err := repo.DeleteFeedbackComment(context.Background(), 1, 1, 1) + + assert.Error(t, err) +} + func TestExptInsightAnalysisRecordRepo_CreateFeedbackVote(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() repo, mocks := newTestExptInsightAnalysisRecordRepo(ctrl) + expectWriteFlagAny(mocks) vote := &entity.ExptInsightAnalysisFeedbackVote{ SpaceID: 1, @@ -233,6 +302,7 @@ func TestExptInsightAnalysisRecordRepo_UpdateFeedbackVote(t *testing.T) { defer ctrl.Finish() repo, mocks := newTestExptInsightAnalysisRecordRepo(ctrl) + expectWriteFlagAny(mocks) vote := &entity.ExptInsightAnalysisFeedbackVote{ ID: 1, @@ -254,8 +324,9 @@ func TestExptInsightAnalysisRecordRepo_GetFeedbackVoteByUser(t *testing.T) { defer ctrl.Finish() repo, mocks := newTestExptInsightAnalysisRecordRepo(ctrl) + expectNoWriteFlagRead(mocks) - mocks.feedbackVoteDAO.EXPECT().GetByUser(gomock.Any(), int64(1), int64(1), int64(1), "user123", gomock.Any()).Return(&model.ExptInsightAnalysisFeedbackVote{ + mocks.feedbackVoteDAO.EXPECT().GetByUser(gomock.Any(), int64(1), int64(1), int64(1), "user123").Return(&model.ExptInsightAnalysisFeedbackVote{ ID: 1, SpaceID: 1, ExptID: 1, @@ -278,6 +349,7 @@ func TestExptInsightAnalysisRecordRepo_CountFeedbackVote(t *testing.T) { defer ctrl.Finish() repo, mocks := newTestExptInsightAnalysisRecordRepo(ctrl) + expectNoWriteFlagRead(mocks) mocks.feedbackVoteDAO.EXPECT().Count(gomock.Any(), int64(1), int64(1), int64(1)).Return(int64(3), int64(2), nil) @@ -288,11 +360,34 @@ func TestExptInsightAnalysisRecordRepo_CountFeedbackVote(t *testing.T) { assert.Equal(t, int64(2), downVoteCount) } +func TestExptInsightAnalysisRecordRepo_CountFeedbackVote_ForceMaster(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + repo, mocks := newTestExptInsightAnalysisRecordRepo(ctrl) + + mocks.writeTracker.EXPECT().CheckWriteFlagByID(gomock.Any(), gomock.Any(), gomock.Any()).Return(false).AnyTimes() + mocks.writeTracker.EXPECT().CheckWriteFlagBySearchParam(gomock.Any(), gomock.Any(), gomock.Any()).Return(true) + mocks.feedbackVoteDAO.EXPECT().Count(gomock.Any(), int64(1), int64(1), int64(1), gomock.Any()).DoAndReturn( + func(_ context.Context, _ int64, _ int64, _ int64, opts ...db.Option) (int64, int64, error) { + assert.True(t, db.ContainWithMasterOpt(opts)) + return 3, 2, nil + }, + ) + + upVoteCount, downVoteCount, err := repo.CountFeedbackVote(context.Background(), 1, 1, 1) + + assert.NoError(t, err) + assert.Equal(t, int64(3), upVoteCount) + assert.Equal(t, int64(2), downVoteCount) +} + func TestExptInsightAnalysisRecordRepo_List(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() repo, mocks := newTestExptInsightAnalysisRecordRepo(ctrl) + expectNoWriteFlagRead(mocks) mocks.feedbackCommentDAO.EXPECT().List(gomock.Any(), int64(1), int64(1), int64(1), entity.NewPage(1, 10)).Return([]*model.ExptInsightAnalysisFeedbackComment{ { @@ -411,8 +506,9 @@ func TestExptInsightAnalysisRecordRepo_GetFeedbackCommentByRecordID(t *testing.T defer ctrl.Finish() repo, mocks := newTestExptInsightAnalysisRecordRepo(ctrl) + expectNoWriteFlagRead(mocks) - mocks.feedbackCommentDAO.EXPECT().GetByRecordID(gomock.Any(), int64(1), int64(1), int64(1), gomock.Any()).Return(&model.ExptInsightAnalysisFeedbackComment{ + mocks.feedbackCommentDAO.EXPECT().GetByRecordID(gomock.Any(), int64(1), int64(1), int64(1)).Return(&model.ExptInsightAnalysisFeedbackComment{ ID: 1, SpaceID: 1, ExptID: 1, @@ -430,13 +526,36 @@ func TestExptInsightAnalysisRecordRepo_GetFeedbackCommentByRecordID(t *testing.T assert.Equal(t, int64(1), comment.ID) } +func TestExptInsightAnalysisRecordRepo_GetFeedbackCommentByRecordID_ForceMaster(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + repo, mocks := newTestExptInsightAnalysisRecordRepo(ctrl) + + mocks.writeTracker.EXPECT().CheckWriteFlagByID(gomock.Any(), gomock.Any(), int64(1)).Return(true) + mocks.writeTracker.EXPECT().CheckWriteFlagBySearchParam(gomock.Any(), gomock.Any(), gomock.Any()).Return(false).AnyTimes() + mocks.feedbackCommentDAO.EXPECT().GetByRecordID(gomock.Any(), int64(1), int64(1), int64(1), gomock.Any()).DoAndReturn( + func(_ context.Context, _ int64, _ int64, _ int64, opts ...db.Option) (*model.ExptInsightAnalysisFeedbackComment, error) { + assert.True(t, db.ContainWithMasterOpt(opts)) + return &model.ExptInsightAnalysisFeedbackComment{ID: 1, SpaceID: 1, ExptID: 1, AnalysisRecordID: ptr.Of(int64(1))}, nil + }, + ) + + comment, err := repo.GetFeedbackCommentByRecordID(context.Background(), 1, 1, 1) + + assert.NoError(t, err) + assert.NotNil(t, comment) + assert.Equal(t, int64(1), comment.ID) +} + func TestExptInsightAnalysisRecordRepo_GetFeedbackCommentByRecordID_Error(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() repo, mocks := newTestExptInsightAnalysisRecordRepo(ctrl) + expectNoWriteFlagRead(mocks) - mocks.feedbackCommentDAO.EXPECT().GetByRecordID(gomock.Any(), int64(1), int64(1), int64(1), gomock.Any()).Return(nil, assert.AnError) + mocks.feedbackCommentDAO.EXPECT().GetByRecordID(gomock.Any(), int64(1), int64(1), int64(1)).Return(nil, assert.AnError) comment, err := repo.GetFeedbackCommentByRecordID(context.Background(), 1, 1, 1) @@ -449,8 +568,9 @@ func TestExptInsightAnalysisRecordRepo_GetFeedbackVoteByUser_Error(t *testing.T) defer ctrl.Finish() repo, mocks := newTestExptInsightAnalysisRecordRepo(ctrl) + expectNoWriteFlagRead(mocks) - mocks.feedbackVoteDAO.EXPECT().GetByUser(gomock.Any(), int64(1), int64(1), int64(1), "user123", gomock.Any()).Return(nil, assert.AnError) + mocks.feedbackVoteDAO.EXPECT().GetByUser(gomock.Any(), int64(1), int64(1), int64(1), "user123").Return(nil, assert.AnError) vote, err := repo.GetFeedbackVoteByUser(context.Background(), 1, 1, 1, "user123") @@ -463,6 +583,7 @@ func TestExptInsightAnalysisRecordRepo_List_Error(t *testing.T) { defer ctrl.Finish() repo, mocks := newTestExptInsightAnalysisRecordRepo(ctrl) + expectNoWriteFlagRead(mocks) mocks.feedbackCommentDAO.EXPECT().List(gomock.Any(), int64(1), int64(1), int64(1), entity.NewPage(1, 10)).Return(nil, int64(0), assert.AnError) diff --git a/backend/modules/evaluation/infra/repo/experiment/mysql/expt_insight_analysis_feedback_comment.go b/backend/modules/evaluation/infra/repo/experiment/mysql/expt_insight_analysis_feedback_comment.go index 33944ba43..b495b1e7a 100644 --- a/backend/modules/evaluation/infra/repo/experiment/mysql/expt_insight_analysis_feedback_comment.go +++ b/backend/modules/evaluation/infra/repo/experiment/mysql/expt_insight_analysis_feedback_comment.go @@ -19,8 +19,9 @@ type IExptInsightAnalysisFeedbackCommentDAO interface { Create(ctx context.Context, feedbackComment *model.ExptInsightAnalysisFeedbackComment, opts ...db.Option) error Update(ctx context.Context, feedbackComment *model.ExptInsightAnalysisFeedbackComment, opts ...db.Option) error GetByRecordID(ctx context.Context, spaceID, exptID, recordID int64, opts ...db.Option) (*model.ExptInsightAnalysisFeedbackComment, error) + GetByID(ctx context.Context, spaceID, exptID, commentID int64, opts ...db.Option) (*model.ExptInsightAnalysisFeedbackComment, error) Delete(ctx context.Context, spaceID, exptID, commentID int64) error - List(ctx context.Context, spaceID, exptID, recordID int64, page entity.Page) ([]*model.ExptInsightAnalysisFeedbackComment, int64, error) + List(ctx context.Context, spaceID, exptID, recordID int64, page entity.Page, opts ...db.Option) ([]*model.ExptInsightAnalysisFeedbackComment, int64, error) } func NewExptInsightAnalysisFeedbackCommentDAO(db db.Provider) IExptInsightAnalysisFeedbackCommentDAO { @@ -50,7 +51,7 @@ func (e exptInsightAnalysisFeedbackCommentDAO) Update(ctx context.Context, feedb } func (e exptInsightAnalysisFeedbackCommentDAO) GetByRecordID(ctx context.Context, spaceID, exptID, recordID int64, opts ...db.Option) (*model.ExptInsightAnalysisFeedbackComment, error) { - db := e.db.NewSession(ctx) + db := e.db.NewSession(ctx, opts...) q := query.Use(db).ExptInsightAnalysisFeedbackComment feedbackVote, err := q.WithContext(ctx).Where( @@ -65,6 +66,22 @@ func (e exptInsightAnalysisFeedbackCommentDAO) GetByRecordID(ctx context.Context return feedbackVote, nil } +func (e exptInsightAnalysisFeedbackCommentDAO) GetByID(ctx context.Context, spaceID, exptID, commentID int64, opts ...db.Option) (*model.ExptInsightAnalysisFeedbackComment, error) { + db := e.db.NewSession(ctx, opts...) + q := query.Use(db).ExptInsightAnalysisFeedbackComment + + comment, err := q.WithContext(ctx).Where( + q.SpaceID.Eq(spaceID), + q.ExptID.Eq(exptID), + q.ID.Eq(commentID), + ).First() + if err != nil { + return nil, errorx.Wrapf(err, "exptInsightAnalysisFeedbackCommentDAO GetByID fail, commentID: %v", commentID) + } + + return comment, nil +} + func (e exptInsightAnalysisFeedbackCommentDAO) Delete(ctx context.Context, spaceID, exptID, commentID int64) error { po := &model.ExptInsightAnalysisFeedbackComment{} db := e.db.NewSession(ctx) @@ -77,12 +94,12 @@ func (e exptInsightAnalysisFeedbackCommentDAO) Delete(ctx context.Context, space return nil } -func (e exptInsightAnalysisFeedbackCommentDAO) List(ctx context.Context, spaceID, exptID, recordID int64, page entity.Page) ([]*model.ExptInsightAnalysisFeedbackComment, int64, error) { +func (e exptInsightAnalysisFeedbackCommentDAO) List(ctx context.Context, spaceID, exptID, recordID int64, page entity.Page, opts ...db.Option) ([]*model.ExptInsightAnalysisFeedbackComment, int64, error) { var ( finds []*model.ExptInsightAnalysisFeedbackComment total int64 ) - db := e.db.NewSession(ctx).Model(&model.ExptInsightAnalysisFeedbackComment{}). + db := e.db.NewSession(ctx, opts...).Model(&model.ExptInsightAnalysisFeedbackComment{}). Where("space_id =?", spaceID). Where("expt_id =?", exptID). Where("analysis_record_id =?", recordID).Order("created_at DESC") diff --git a/backend/modules/evaluation/infra/repo/experiment/mysql/expt_insight_analysis_feedback_vote.go b/backend/modules/evaluation/infra/repo/experiment/mysql/expt_insight_analysis_feedback_vote.go index a22fcd40e..799b3073b 100644 --- a/backend/modules/evaluation/infra/repo/experiment/mysql/expt_insight_analysis_feedback_vote.go +++ b/backend/modules/evaluation/infra/repo/experiment/mysql/expt_insight_analysis_feedback_vote.go @@ -23,7 +23,7 @@ type IExptInsightAnalysisFeedbackVoteDAO interface { Create(ctx context.Context, feedbackVote *model.ExptInsightAnalysisFeedbackVote, opts ...db.Option) error Update(ctx context.Context, feedbackVote *model.ExptInsightAnalysisFeedbackVote, opts ...db.Option) error GetByUser(ctx context.Context, spaceID, exptID, recordID int64, userID string, opts ...db.Option) (*model.ExptInsightAnalysisFeedbackVote, error) - Count(ctx context.Context, spaceID, exptID, recordID int64) (int64, int64, error) + Count(ctx context.Context, spaceID, exptID, recordID int64, opts ...db.Option) (int64, int64, error) } func NewExptInsightAnalysisFeedbackVoteDAO(db db.Provider) IExptInsightAnalysisFeedbackVoteDAO { @@ -59,7 +59,7 @@ func (e exptInsightAnalysisFeedbackVoteDAO) Update(ctx context.Context, feedback } func (e exptInsightAnalysisFeedbackVoteDAO) GetByUser(ctx context.Context, spaceID, exptID, recordID int64, userID string, opts ...db.Option) (*model.ExptInsightAnalysisFeedbackVote, error) { - db := e.db.NewSession(ctx) + db := e.db.NewSession(ctx, opts...) q := query.Use(db).ExptInsightAnalysisFeedbackVote feedbackVote, err := q.WithContext(ctx).Where( @@ -78,8 +78,8 @@ func (e exptInsightAnalysisFeedbackVoteDAO) GetByUser(ctx context.Context, space return feedbackVote, nil } -func (e exptInsightAnalysisFeedbackVoteDAO) Count(ctx context.Context, spaceID, exptID, recordID int64) (int64, int64, error) { - db := e.db.NewSession(ctx) +func (e exptInsightAnalysisFeedbackVoteDAO) Count(ctx context.Context, spaceID, exptID, recordID int64, opts ...db.Option) (int64, int64, error) { + db := e.db.NewSession(ctx, opts...) type VoteStatistic struct { UpvoteCount int64 `json:"upvote_count"` DownvoteCount int64 `json:"downvote_count"` diff --git a/backend/modules/evaluation/infra/repo/experiment/mysql/expt_insight_analysis_record.go b/backend/modules/evaluation/infra/repo/experiment/mysql/expt_insight_analysis_record.go index a19161106..7cf1e4714 100644 --- a/backend/modules/evaluation/infra/repo/experiment/mysql/expt_insight_analysis_record.go +++ b/backend/modules/evaluation/infra/repo/experiment/mysql/expt_insight_analysis_record.go @@ -19,7 +19,7 @@ type IExptInsightAnalysisRecordDAO interface { Create(ctx context.Context, record *model.ExptInsightAnalysisRecord, opts ...db.Option) error Update(ctx context.Context, record *model.ExptInsightAnalysisRecord, opts ...db.Option) error GetByID(ctx context.Context, spaceID, exptID, recordID int64, opts ...db.Option) (*model.ExptInsightAnalysisRecord, error) - List(ctx context.Context, spaceID, exptID int64, page entity.Page) ([]*model.ExptInsightAnalysisRecord, int64, error) + List(ctx context.Context, spaceID, exptID int64, page entity.Page, opts ...db.Option) ([]*model.ExptInsightAnalysisRecord, int64, error) Delete(ctx context.Context, spaceID, exptID, recordID int64) error } @@ -50,7 +50,7 @@ func (e exptInsightAnalysisRecordDAO) Update(ctx context.Context, record *model. } func (e exptInsightAnalysisRecordDAO) GetByID(ctx context.Context, spaceID, exptID, recordID int64, opts ...db.Option) (*model.ExptInsightAnalysisRecord, error) { - db := e.db.NewSession(ctx) + db := e.db.NewSession(ctx, opts...) q := query.Use(db).ExptInsightAnalysisRecord record, err := q.WithContext(ctx).Where( @@ -65,13 +65,13 @@ func (e exptInsightAnalysisRecordDAO) GetByID(ctx context.Context, spaceID, expt return record, nil } -func (e exptInsightAnalysisRecordDAO) List(ctx context.Context, spaceID, exptID int64, page entity.Page) ([]*model.ExptInsightAnalysisRecord, int64, error) { +func (e exptInsightAnalysisRecordDAO) List(ctx context.Context, spaceID, exptID int64, page entity.Page, opts ...db.Option) ([]*model.ExptInsightAnalysisRecord, int64, error) { var ( finds []*model.ExptInsightAnalysisRecord total int64 ) - db := e.db.NewSession(ctx).Model(&model.ExptInsightAnalysisRecord{}).Where("space_id = ?", spaceID).Where("expt_id = ?", exptID) + db := e.db.NewSession(ctx, opts...).Model(&model.ExptInsightAnalysisRecord{}).Where("space_id = ?", spaceID).Where("expt_id = ?", exptID) db = db.Order("created_at desc") // 总记录数 diff --git a/backend/modules/evaluation/infra/repo/experiment/mysql/mocks/expt_insight_analysis_feedback_comment.go b/backend/modules/evaluation/infra/repo/experiment/mysql/mocks/expt_insight_analysis_feedback_comment.go index 691ec4388..187b29441 100644 --- a/backend/modules/evaluation/infra/repo/experiment/mysql/mocks/expt_insight_analysis_feedback_comment.go +++ b/backend/modules/evaluation/infra/repo/experiment/mysql/mocks/expt_insight_analysis_feedback_comment.go @@ -1,10 +1,5 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/coze-dev/coze-loop/backend/modules/evaluation/infra/repo/experiment/mysql (interfaces: IExptInsightAnalysisFeedbackCommentDAO) -// -// Generated by this command: -// -// mockgen -destination=mocks/expt_insight_analysis_feedback_comment.go -package mocks . IExptInsightAnalysisFeedbackCommentDAO -// // Package mocks is a generated GoMock package. package mocks @@ -23,7 +18,6 @@ import ( type MockIExptInsightAnalysisFeedbackCommentDAO struct { ctrl *gomock.Controller recorder *MockIExptInsightAnalysisFeedbackCommentDAOMockRecorder - isgomock struct{} } // MockIExptInsightAnalysisFeedbackCommentDAOMockRecorder is the mock recorder for MockIExptInsightAnalysisFeedbackCommentDAO. @@ -44,10 +38,10 @@ func (m *MockIExptInsightAnalysisFeedbackCommentDAO) EXPECT() *MockIExptInsightA } // Create mocks base method. -func (m *MockIExptInsightAnalysisFeedbackCommentDAO) Create(ctx context.Context, feedbackComment *model.ExptInsightAnalysisFeedbackComment, opts ...db.Option) error { +func (m *MockIExptInsightAnalysisFeedbackCommentDAO) Create(arg0 context.Context, arg1 *model.ExptInsightAnalysisFeedbackComment, arg2 ...db.Option) error { m.ctrl.T.Helper() - varargs := []any{ctx, feedbackComment} - for _, a := range opts { + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { varargs = append(varargs, a) } ret := m.ctrl.Call(m, "Create", varargs...) @@ -56,31 +50,31 @@ func (m *MockIExptInsightAnalysisFeedbackCommentDAO) Create(ctx context.Context, } // Create indicates an expected call of Create. -func (mr *MockIExptInsightAnalysisFeedbackCommentDAOMockRecorder) Create(ctx, feedbackComment any, opts ...any) *gomock.Call { +func (mr *MockIExptInsightAnalysisFeedbackCommentDAOMockRecorder) Create(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - varargs := append([]any{ctx, feedbackComment}, opts...) + varargs := append([]interface{}{arg0, arg1}, arg2...) return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Create", reflect.TypeOf((*MockIExptInsightAnalysisFeedbackCommentDAO)(nil).Create), varargs...) } // Delete mocks base method. -func (m *MockIExptInsightAnalysisFeedbackCommentDAO) Delete(ctx context.Context, spaceID, exptID, commentID int64) error { +func (m *MockIExptInsightAnalysisFeedbackCommentDAO) Delete(arg0 context.Context, arg1, arg2, arg3 int64) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Delete", ctx, spaceID, exptID, commentID) + ret := m.ctrl.Call(m, "Delete", arg0, arg1, arg2, arg3) ret0, _ := ret[0].(error) return ret0 } // Delete indicates an expected call of Delete. -func (mr *MockIExptInsightAnalysisFeedbackCommentDAOMockRecorder) Delete(ctx, spaceID, exptID, commentID any) *gomock.Call { +func (mr *MockIExptInsightAnalysisFeedbackCommentDAOMockRecorder) Delete(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Delete", reflect.TypeOf((*MockIExptInsightAnalysisFeedbackCommentDAO)(nil).Delete), ctx, spaceID, exptID, commentID) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Delete", reflect.TypeOf((*MockIExptInsightAnalysisFeedbackCommentDAO)(nil).Delete), arg0, arg1, arg2, arg3) } // GetByRecordID mocks base method. -func (m *MockIExptInsightAnalysisFeedbackCommentDAO) GetByRecordID(ctx context.Context, spaceID, exptID, recordID int64, opts ...db.Option) (*model.ExptInsightAnalysisFeedbackComment, error) { +func (m *MockIExptInsightAnalysisFeedbackCommentDAO) GetByRecordID(arg0 context.Context, arg1, arg2, arg3 int64, arg4 ...db.Option) (*model.ExptInsightAnalysisFeedbackComment, error) { m.ctrl.T.Helper() - varargs := []any{ctx, spaceID, exptID, recordID} - for _, a := range opts { + varargs := []interface{}{arg0, arg1, arg2, arg3} + for _, a := range arg4 { varargs = append(varargs, a) } ret := m.ctrl.Call(m, "GetByRecordID", varargs...) @@ -90,16 +84,40 @@ func (m *MockIExptInsightAnalysisFeedbackCommentDAO) GetByRecordID(ctx context.C } // GetByRecordID indicates an expected call of GetByRecordID. -func (mr *MockIExptInsightAnalysisFeedbackCommentDAOMockRecorder) GetByRecordID(ctx, spaceID, exptID, recordID any, opts ...any) *gomock.Call { +func (mr *MockIExptInsightAnalysisFeedbackCommentDAOMockRecorder) GetByRecordID(arg0, arg1, arg2, arg3 interface{}, arg4 ...interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - varargs := append([]any{ctx, spaceID, exptID, recordID}, opts...) + varargs := append([]interface{}{arg0, arg1, arg2, arg3}, arg4...) return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetByRecordID", reflect.TypeOf((*MockIExptInsightAnalysisFeedbackCommentDAO)(nil).GetByRecordID), varargs...) } +// GetByID mocks base method. +func (m *MockIExptInsightAnalysisFeedbackCommentDAO) GetByID(arg0 context.Context, arg1, arg2, arg3 int64, arg4 ...db.Option) (*model.ExptInsightAnalysisFeedbackComment, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1, arg2, arg3} + for _, a := range arg4 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "GetByID", varargs...) + ret0, _ := ret[0].(*model.ExptInsightAnalysisFeedbackComment) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetByID indicates an expected call of GetByID. +func (mr *MockIExptInsightAnalysisFeedbackCommentDAOMockRecorder) GetByID(arg0, arg1, arg2, arg3 interface{}, arg4 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1, arg2, arg3}, arg4...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetByID", reflect.TypeOf((*MockIExptInsightAnalysisFeedbackCommentDAO)(nil).GetByID), varargs...) +} + // List mocks base method. -func (m *MockIExptInsightAnalysisFeedbackCommentDAO) List(ctx context.Context, spaceID, exptID, recordID int64, page entity.Page) ([]*model.ExptInsightAnalysisFeedbackComment, int64, error) { +func (m *MockIExptInsightAnalysisFeedbackCommentDAO) List(arg0 context.Context, arg1, arg2, arg3 int64, arg4 entity.Page, arg5 ...db.Option) ([]*model.ExptInsightAnalysisFeedbackComment, int64, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "List", ctx, spaceID, exptID, recordID, page) + varargs := []interface{}{arg0, arg1, arg2, arg3, arg4} + for _, a := range arg5 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "List", varargs...) ret0, _ := ret[0].([]*model.ExptInsightAnalysisFeedbackComment) ret1, _ := ret[1].(int64) ret2, _ := ret[2].(error) @@ -107,16 +125,17 @@ func (m *MockIExptInsightAnalysisFeedbackCommentDAO) List(ctx context.Context, s } // List indicates an expected call of List. -func (mr *MockIExptInsightAnalysisFeedbackCommentDAOMockRecorder) List(ctx, spaceID, exptID, recordID, page any) *gomock.Call { +func (mr *MockIExptInsightAnalysisFeedbackCommentDAOMockRecorder) List(arg0, arg1, arg2, arg3, arg4 interface{}, arg5 ...interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "List", reflect.TypeOf((*MockIExptInsightAnalysisFeedbackCommentDAO)(nil).List), ctx, spaceID, exptID, recordID, page) + varargs := append([]interface{}{arg0, arg1, arg2, arg3, arg4}, arg5...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "List", reflect.TypeOf((*MockIExptInsightAnalysisFeedbackCommentDAO)(nil).List), varargs...) } // Update mocks base method. -func (m *MockIExptInsightAnalysisFeedbackCommentDAO) Update(ctx context.Context, feedbackComment *model.ExptInsightAnalysisFeedbackComment, opts ...db.Option) error { +func (m *MockIExptInsightAnalysisFeedbackCommentDAO) Update(arg0 context.Context, arg1 *model.ExptInsightAnalysisFeedbackComment, arg2 ...db.Option) error { m.ctrl.T.Helper() - varargs := []any{ctx, feedbackComment} - for _, a := range opts { + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { varargs = append(varargs, a) } ret := m.ctrl.Call(m, "Update", varargs...) @@ -125,8 +144,8 @@ func (m *MockIExptInsightAnalysisFeedbackCommentDAO) Update(ctx context.Context, } // Update indicates an expected call of Update. -func (mr *MockIExptInsightAnalysisFeedbackCommentDAOMockRecorder) Update(ctx, feedbackComment any, opts ...any) *gomock.Call { +func (mr *MockIExptInsightAnalysisFeedbackCommentDAOMockRecorder) Update(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - varargs := append([]any{ctx, feedbackComment}, opts...) + varargs := append([]interface{}{arg0, arg1}, arg2...) return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Update", reflect.TypeOf((*MockIExptInsightAnalysisFeedbackCommentDAO)(nil).Update), varargs...) } diff --git a/backend/modules/evaluation/infra/repo/experiment/mysql/mocks/expt_insight_analysis_feedback_vote.go b/backend/modules/evaluation/infra/repo/experiment/mysql/mocks/expt_insight_analysis_feedback_vote.go index 13964dd1b..2c12c6390 100644 --- a/backend/modules/evaluation/infra/repo/experiment/mysql/mocks/expt_insight_analysis_feedback_vote.go +++ b/backend/modules/evaluation/infra/repo/experiment/mysql/mocks/expt_insight_analysis_feedback_vote.go @@ -1,10 +1,5 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/coze-dev/coze-loop/backend/modules/evaluation/infra/repo/experiment/mysql (interfaces: IExptInsightAnalysisFeedbackVoteDAO) -// -// Generated by this command: -// -// mockgen -destination=mocks/expt_insight_analysis_feedback_vote.go -package mocks . IExptInsightAnalysisFeedbackVoteDAO -// // Package mocks is a generated GoMock package. package mocks @@ -22,7 +17,6 @@ import ( type MockIExptInsightAnalysisFeedbackVoteDAO struct { ctrl *gomock.Controller recorder *MockIExptInsightAnalysisFeedbackVoteDAOMockRecorder - isgomock struct{} } // MockIExptInsightAnalysisFeedbackVoteDAOMockRecorder is the mock recorder for MockIExptInsightAnalysisFeedbackVoteDAO. @@ -43,9 +37,13 @@ func (m *MockIExptInsightAnalysisFeedbackVoteDAO) EXPECT() *MockIExptInsightAnal } // Count mocks base method. -func (m *MockIExptInsightAnalysisFeedbackVoteDAO) Count(ctx context.Context, spaceID, exptID, recordID int64) (int64, int64, error) { +func (m *MockIExptInsightAnalysisFeedbackVoteDAO) Count(arg0 context.Context, arg1, arg2, arg3 int64, arg4 ...db.Option) (int64, int64, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Count", ctx, spaceID, exptID, recordID) + varargs := []interface{}{arg0, arg1, arg2, arg3} + for _, a := range arg4 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "Count", varargs...) ret0, _ := ret[0].(int64) ret1, _ := ret[1].(int64) ret2, _ := ret[2].(error) @@ -53,16 +51,17 @@ func (m *MockIExptInsightAnalysisFeedbackVoteDAO) Count(ctx context.Context, spa } // Count indicates an expected call of Count. -func (mr *MockIExptInsightAnalysisFeedbackVoteDAOMockRecorder) Count(ctx, spaceID, exptID, recordID any) *gomock.Call { +func (mr *MockIExptInsightAnalysisFeedbackVoteDAOMockRecorder) Count(arg0, arg1, arg2, arg3 interface{}, arg4 ...interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Count", reflect.TypeOf((*MockIExptInsightAnalysisFeedbackVoteDAO)(nil).Count), ctx, spaceID, exptID, recordID) + varargs := append([]interface{}{arg0, arg1, arg2, arg3}, arg4...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Count", reflect.TypeOf((*MockIExptInsightAnalysisFeedbackVoteDAO)(nil).Count), varargs...) } // Create mocks base method. -func (m *MockIExptInsightAnalysisFeedbackVoteDAO) Create(ctx context.Context, feedbackVote *model.ExptInsightAnalysisFeedbackVote, opts ...db.Option) error { +func (m *MockIExptInsightAnalysisFeedbackVoteDAO) Create(arg0 context.Context, arg1 *model.ExptInsightAnalysisFeedbackVote, arg2 ...db.Option) error { m.ctrl.T.Helper() - varargs := []any{ctx, feedbackVote} - for _, a := range opts { + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { varargs = append(varargs, a) } ret := m.ctrl.Call(m, "Create", varargs...) @@ -71,17 +70,17 @@ func (m *MockIExptInsightAnalysisFeedbackVoteDAO) Create(ctx context.Context, fe } // Create indicates an expected call of Create. -func (mr *MockIExptInsightAnalysisFeedbackVoteDAOMockRecorder) Create(ctx, feedbackVote any, opts ...any) *gomock.Call { +func (mr *MockIExptInsightAnalysisFeedbackVoteDAOMockRecorder) Create(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - varargs := append([]any{ctx, feedbackVote}, opts...) + varargs := append([]interface{}{arg0, arg1}, arg2...) return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Create", reflect.TypeOf((*MockIExptInsightAnalysisFeedbackVoteDAO)(nil).Create), varargs...) } // GetByUser mocks base method. -func (m *MockIExptInsightAnalysisFeedbackVoteDAO) GetByUser(ctx context.Context, spaceID, exptID, recordID int64, userID string, opts ...db.Option) (*model.ExptInsightAnalysisFeedbackVote, error) { +func (m *MockIExptInsightAnalysisFeedbackVoteDAO) GetByUser(arg0 context.Context, arg1, arg2, arg3 int64, arg4 string, arg5 ...db.Option) (*model.ExptInsightAnalysisFeedbackVote, error) { m.ctrl.T.Helper() - varargs := []any{ctx, spaceID, exptID, recordID, userID} - for _, a := range opts { + varargs := []interface{}{arg0, arg1, arg2, arg3, arg4} + for _, a := range arg5 { varargs = append(varargs, a) } ret := m.ctrl.Call(m, "GetByUser", varargs...) @@ -91,17 +90,17 @@ func (m *MockIExptInsightAnalysisFeedbackVoteDAO) GetByUser(ctx context.Context, } // GetByUser indicates an expected call of GetByUser. -func (mr *MockIExptInsightAnalysisFeedbackVoteDAOMockRecorder) GetByUser(ctx, spaceID, exptID, recordID, userID any, opts ...any) *gomock.Call { +func (mr *MockIExptInsightAnalysisFeedbackVoteDAOMockRecorder) GetByUser(arg0, arg1, arg2, arg3, arg4 interface{}, arg5 ...interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - varargs := append([]any{ctx, spaceID, exptID, recordID, userID}, opts...) + varargs := append([]interface{}{arg0, arg1, arg2, arg3, arg4}, arg5...) return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetByUser", reflect.TypeOf((*MockIExptInsightAnalysisFeedbackVoteDAO)(nil).GetByUser), varargs...) } // Update mocks base method. -func (m *MockIExptInsightAnalysisFeedbackVoteDAO) Update(ctx context.Context, feedbackVote *model.ExptInsightAnalysisFeedbackVote, opts ...db.Option) error { +func (m *MockIExptInsightAnalysisFeedbackVoteDAO) Update(arg0 context.Context, arg1 *model.ExptInsightAnalysisFeedbackVote, arg2 ...db.Option) error { m.ctrl.T.Helper() - varargs := []any{ctx, feedbackVote} - for _, a := range opts { + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { varargs = append(varargs, a) } ret := m.ctrl.Call(m, "Update", varargs...) @@ -110,8 +109,8 @@ func (m *MockIExptInsightAnalysisFeedbackVoteDAO) Update(ctx context.Context, fe } // Update indicates an expected call of Update. -func (mr *MockIExptInsightAnalysisFeedbackVoteDAOMockRecorder) Update(ctx, feedbackVote any, opts ...any) *gomock.Call { +func (mr *MockIExptInsightAnalysisFeedbackVoteDAOMockRecorder) Update(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - varargs := append([]any{ctx, feedbackVote}, opts...) + varargs := append([]interface{}{arg0, arg1}, arg2...) return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Update", reflect.TypeOf((*MockIExptInsightAnalysisFeedbackVoteDAO)(nil).Update), varargs...) } diff --git a/backend/modules/evaluation/infra/repo/experiment/mysql/mocks/expt_insight_analysis_record.go b/backend/modules/evaluation/infra/repo/experiment/mysql/mocks/expt_insight_analysis_record.go index 63def3504..d27da1fab 100644 --- a/backend/modules/evaluation/infra/repo/experiment/mysql/mocks/expt_insight_analysis_record.go +++ b/backend/modules/evaluation/infra/repo/experiment/mysql/mocks/expt_insight_analysis_record.go @@ -1,10 +1,5 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/coze-dev/coze-loop/backend/modules/evaluation/infra/repo/experiment/mysql (interfaces: IExptInsightAnalysisRecordDAO) -// -// Generated by this command: -// -// mockgen -destination=mocks/expt_insight_analysis_record.go -package mocks . IExptInsightAnalysisRecordDAO -// // Package mocks is a generated GoMock package. package mocks @@ -23,7 +18,6 @@ import ( type MockIExptInsightAnalysisRecordDAO struct { ctrl *gomock.Controller recorder *MockIExptInsightAnalysisRecordDAOMockRecorder - isgomock struct{} } // MockIExptInsightAnalysisRecordDAOMockRecorder is the mock recorder for MockIExptInsightAnalysisRecordDAO. @@ -44,10 +38,10 @@ func (m *MockIExptInsightAnalysisRecordDAO) EXPECT() *MockIExptInsightAnalysisRe } // Create mocks base method. -func (m *MockIExptInsightAnalysisRecordDAO) Create(ctx context.Context, record *model.ExptInsightAnalysisRecord, opts ...db.Option) error { +func (m *MockIExptInsightAnalysisRecordDAO) Create(arg0 context.Context, arg1 *model.ExptInsightAnalysisRecord, arg2 ...db.Option) error { m.ctrl.T.Helper() - varargs := []any{ctx, record} - for _, a := range opts { + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { varargs = append(varargs, a) } ret := m.ctrl.Call(m, "Create", varargs...) @@ -56,31 +50,31 @@ func (m *MockIExptInsightAnalysisRecordDAO) Create(ctx context.Context, record * } // Create indicates an expected call of Create. -func (mr *MockIExptInsightAnalysisRecordDAOMockRecorder) Create(ctx, record any, opts ...any) *gomock.Call { +func (mr *MockIExptInsightAnalysisRecordDAOMockRecorder) Create(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - varargs := append([]any{ctx, record}, opts...) + varargs := append([]interface{}{arg0, arg1}, arg2...) return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Create", reflect.TypeOf((*MockIExptInsightAnalysisRecordDAO)(nil).Create), varargs...) } // Delete mocks base method. -func (m *MockIExptInsightAnalysisRecordDAO) Delete(ctx context.Context, spaceID, exptID, recordID int64) error { +func (m *MockIExptInsightAnalysisRecordDAO) Delete(arg0 context.Context, arg1, arg2, arg3 int64) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Delete", ctx, spaceID, exptID, recordID) + ret := m.ctrl.Call(m, "Delete", arg0, arg1, arg2, arg3) ret0, _ := ret[0].(error) return ret0 } // Delete indicates an expected call of Delete. -func (mr *MockIExptInsightAnalysisRecordDAOMockRecorder) Delete(ctx, spaceID, exptID, recordID any) *gomock.Call { +func (mr *MockIExptInsightAnalysisRecordDAOMockRecorder) Delete(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Delete", reflect.TypeOf((*MockIExptInsightAnalysisRecordDAO)(nil).Delete), ctx, spaceID, exptID, recordID) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Delete", reflect.TypeOf((*MockIExptInsightAnalysisRecordDAO)(nil).Delete), arg0, arg1, arg2, arg3) } // GetByID mocks base method. -func (m *MockIExptInsightAnalysisRecordDAO) GetByID(ctx context.Context, spaceID, exptID, recordID int64, opts ...db.Option) (*model.ExptInsightAnalysisRecord, error) { +func (m *MockIExptInsightAnalysisRecordDAO) GetByID(arg0 context.Context, arg1, arg2, arg3 int64, arg4 ...db.Option) (*model.ExptInsightAnalysisRecord, error) { m.ctrl.T.Helper() - varargs := []any{ctx, spaceID, exptID, recordID} - for _, a := range opts { + varargs := []interface{}{arg0, arg1, arg2, arg3} + for _, a := range arg4 { varargs = append(varargs, a) } ret := m.ctrl.Call(m, "GetByID", varargs...) @@ -90,16 +84,20 @@ func (m *MockIExptInsightAnalysisRecordDAO) GetByID(ctx context.Context, spaceID } // GetByID indicates an expected call of GetByID. -func (mr *MockIExptInsightAnalysisRecordDAOMockRecorder) GetByID(ctx, spaceID, exptID, recordID any, opts ...any) *gomock.Call { +func (mr *MockIExptInsightAnalysisRecordDAOMockRecorder) GetByID(arg0, arg1, arg2, arg3 interface{}, arg4 ...interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - varargs := append([]any{ctx, spaceID, exptID, recordID}, opts...) + varargs := append([]interface{}{arg0, arg1, arg2, arg3}, arg4...) return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetByID", reflect.TypeOf((*MockIExptInsightAnalysisRecordDAO)(nil).GetByID), varargs...) } // List mocks base method. -func (m *MockIExptInsightAnalysisRecordDAO) List(ctx context.Context, spaceID, exptID int64, page entity.Page) ([]*model.ExptInsightAnalysisRecord, int64, error) { +func (m *MockIExptInsightAnalysisRecordDAO) List(arg0 context.Context, arg1, arg2 int64, arg3 entity.Page, arg4 ...db.Option) ([]*model.ExptInsightAnalysisRecord, int64, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "List", ctx, spaceID, exptID, page) + varargs := []interface{}{arg0, arg1, arg2, arg3} + for _, a := range arg4 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "List", varargs...) ret0, _ := ret[0].([]*model.ExptInsightAnalysisRecord) ret1, _ := ret[1].(int64) ret2, _ := ret[2].(error) @@ -107,16 +105,17 @@ func (m *MockIExptInsightAnalysisRecordDAO) List(ctx context.Context, spaceID, e } // List indicates an expected call of List. -func (mr *MockIExptInsightAnalysisRecordDAOMockRecorder) List(ctx, spaceID, exptID, page any) *gomock.Call { +func (mr *MockIExptInsightAnalysisRecordDAOMockRecorder) List(arg0, arg1, arg2, arg3 interface{}, arg4 ...interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "List", reflect.TypeOf((*MockIExptInsightAnalysisRecordDAO)(nil).List), ctx, spaceID, exptID, page) + varargs := append([]interface{}{arg0, arg1, arg2, arg3}, arg4...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "List", reflect.TypeOf((*MockIExptInsightAnalysisRecordDAO)(nil).List), varargs...) } // Update mocks base method. -func (m *MockIExptInsightAnalysisRecordDAO) Update(ctx context.Context, record *model.ExptInsightAnalysisRecord, opts ...db.Option) error { +func (m *MockIExptInsightAnalysisRecordDAO) Update(arg0 context.Context, arg1 *model.ExptInsightAnalysisRecord, arg2 ...db.Option) error { m.ctrl.T.Helper() - varargs := []any{ctx, record} - for _, a := range opts { + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { varargs = append(varargs, a) } ret := m.ctrl.Call(m, "Update", varargs...) @@ -125,8 +124,8 @@ func (m *MockIExptInsightAnalysisRecordDAO) Update(ctx context.Context, record * } // Update indicates an expected call of Update. -func (mr *MockIExptInsightAnalysisRecordDAOMockRecorder) Update(ctx, record any, opts ...any) *gomock.Call { +func (mr *MockIExptInsightAnalysisRecordDAOMockRecorder) Update(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - varargs := append([]any{ctx, record}, opts...) + varargs := append([]interface{}{arg0, arg1}, arg2...) return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Update", reflect.TypeOf((*MockIExptInsightAnalysisRecordDAO)(nil).Update), varargs...) } From 1b12e71b44ed1aa49026a27f76618cb24c2141f8 Mon Sep 17 00:00:00 2001 From: xueyizheng Date: Wed, 12 Nov 2025 14:40:47 +0800 Subject: [PATCH 11/21] first record of ListExptInsightAnalysisRecord would contain feedback info for frontend display --- .../evaluation/application/experiment_app.go | 4 ++- .../domain/service/insight_analysis_impl.go | 35 ++++++++++++++++++- 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/backend/modules/evaluation/application/experiment_app.go b/backend/modules/evaluation/application/experiment_app.go index 8d5306156..d3b4505ab 100644 --- a/backend/modules/evaluation/application/experiment_app.go +++ b/backend/modules/evaluation/application/experiment_app.go @@ -1294,7 +1294,6 @@ func (e *experimentApplication) ListExptInsightAnalysisRecord(ctx context.Contex UserID: strconv.FormatInt(gptr.Indirect(req.Session.UserID), 10), } } - err = e.auth.Authorization(ctx, &rpc.AuthorizationParam{ ObjectID: strconv.FormatInt(req.WorkspaceID, 10), SpaceID: req.WorkspaceID, @@ -1303,6 +1302,9 @@ func (e *experimentApplication) ListExptInsightAnalysisRecord(ctx context.Contex if err != nil { return nil, err } + + // First record contains the upvote/downvote count info for display purpose, + // Other records' feedback is not necessary for this list api records, total, err := e.ListAnalysisRecord(ctx, req.GetWorkspaceID(), req.GetExptID(), entity.NewPage(int(req.GetPageNumber()), int(req.GetPageSize())), session) if err != nil { return nil, err diff --git a/backend/modules/evaluation/domain/service/insight_analysis_impl.go b/backend/modules/evaluation/domain/service/insight_analysis_impl.go index ca46d1be9..ec45b6b27 100644 --- a/backend/modules/evaluation/domain/service/insight_analysis_impl.go +++ b/backend/modules/evaluation/domain/service/insight_analysis_impl.go @@ -275,7 +275,40 @@ func (e ExptInsightAnalysisServiceImpl) notifyAnalysisComplete(ctx context.Conte } func (e ExptInsightAnalysisServiceImpl) ListAnalysisRecord(ctx context.Context, spaceID, exptID int64, page entity.Page, session *entity.Session) ([]*entity.ExptInsightAnalysisRecord, int64, error) { - return e.repo.ListAnalysisRecord(ctx, spaceID, exptID, page) + analysisRecords, total, err := e.repo.ListAnalysisRecord(ctx, spaceID, exptID, page) + if err != nil { + return nil, 0, err + } + if total == 0 { + return analysisRecords, total, nil + } + + firstAnalysisRecord := analysisRecords[0] + + upvoteCount, downvoteCount, err := e.repo.CountFeedbackVote(ctx, spaceID, exptID, firstAnalysisRecord.ID) + if err != nil { + // side path, don't block the main flow + logs.CtxWarn(ctx, "CountFeedbackVote failed for space_id: %v, expt_id: %v, record_id: %v, err=%v", spaceID, exptID, firstAnalysisRecord.ID, err) + return analysisRecords, total, nil + } + + curUserFeedbackVote, err := e.repo.GetFeedbackVoteByUser(ctx, spaceID, exptID, firstAnalysisRecord.ID, session.UserID) + if err != nil { + // side path, don't block the main flow + logs.CtxWarn(ctx, "GetFeedbackVoteByUser failed for space_id: %v, expt_id: %v, record_id: %v, err=%v", spaceID, exptID, firstAnalysisRecord.ID, err) + return analysisRecords, total, nil + } + firstAnalysisRecord.ExptInsightAnalysisFeedback = entity.ExptInsightAnalysisFeedback{ + UpvoteCount: upvoteCount, + DownvoteCount: downvoteCount, + CurrentUserVoteType: entity.None, + } + firstAnalysisRecord.ExptInsightAnalysisFeedback.CurrentUserVoteType = entity.None + if curUserFeedbackVote != nil { + firstAnalysisRecord.ExptInsightAnalysisFeedback.CurrentUserVoteType = curUserFeedbackVote.VoteType + } + + return analysisRecords, total, nil } func (e ExptInsightAnalysisServiceImpl) DeleteAnalysisRecord(ctx context.Context, spaceID, exptID, recordID int64) error { From 98f76c0ec068072bdda4bc3088e470f451cc7454 Mon Sep 17 00:00:00 2001 From: xueyizheng Date: Mon, 17 Nov 2025 14:22:21 +0800 Subject: [PATCH 12/21] insight_analysis record timeout set to 2hour --- .../domain/service/insight_analysis_impl.go | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/backend/modules/evaluation/domain/service/insight_analysis_impl.go b/backend/modules/evaluation/domain/service/insight_analysis_impl.go index ec45b6b27..7ad1cc8e2 100644 --- a/backend/modules/evaluation/domain/service/insight_analysis_impl.go +++ b/backend/modules/evaluation/domain/service/insight_analysis_impl.go @@ -159,13 +159,6 @@ func (e ExptInsightAnalysisServiceImpl) checkAnalysisReportGenStatus(ctx context return err } - // 超过3小时,未生成分析报告,认为是失败 - if status == entity.ReportStatus_Running && record.CreatedAt.Add(entity.InsightAnalysisRunningTimeout).Unix() <= time.Now().Unix() { - record.Status = entity.InsightAnalysisStatus_Failed - logs.CtxWarn(ctx, "checkAnalysisReportGenStatus found timeout event, expt_id: %v, record_id: %v", record.ExptID, record.ID) - return e.repo.UpdateAnalysisRecord(ctx, record) - } - if status == entity.ReportStatus_Failed { record.Status = entity.InsightAnalysisStatus_Failed return e.repo.UpdateAnalysisRecord(ctx, record) @@ -179,10 +172,10 @@ func (e ExptInsightAnalysisServiceImpl) checkAnalysisReportGenStatus(ctx context return e.repo.UpdateAnalysisRecord(ctx, record) } - defaultIntervalSecond := 60 * 60 * 1 - if time.Now().Unix()-CreateAt >= int64(defaultIntervalSecond) { - logs.CtxWarn(ctx, "checkAnalysisReportGenStatus found timeout event, expt_id: %v, record_id: %v", record.ExptID, record.ID) + // 超过2小时,未生成分析报告,认为是失败 + if status == entity.ReportStatus_Running && record.CreatedAt.Add(entity.InsightAnalysisRunningTimeout).Unix() <= time.Now().Unix() { record.Status = entity.InsightAnalysisStatus_Failed + logs.CtxWarn(ctx, "checkAnalysisReportGenStatus found timeout event, expt_id: %v, record_id: %v", record.ExptID, record.ID) return e.repo.UpdateAnalysisRecord(ctx, record) } From fb75fea4c18705bc630652c22a0089e31e7f985e Mon Sep 17 00:00:00 2001 From: xueyizheng Date: Tue, 18 Nov 2025 16:58:41 +0800 Subject: [PATCH 13/21] insight analysis add exptID as input param --- backend/modules/evaluation/domain/component/rpc/trace_agent.go | 2 +- .../modules/evaluation/domain/service/insight_analysis_impl.go | 2 +- backend/modules/evaluation/infra/rpc/agent/agent.go | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/backend/modules/evaluation/domain/component/rpc/trace_agent.go b/backend/modules/evaluation/domain/component/rpc/trace_agent.go index 97e30910c..462271460 100644 --- a/backend/modules/evaluation/domain/component/rpc/trace_agent.go +++ b/backend/modules/evaluation/domain/component/rpc/trace_agent.go @@ -11,6 +11,6 @@ import ( //go:generate mockgen -destination=mocks/trace_agent.go -package=mocks . IAgentAdapter type IAgentAdapter interface { - CallTraceAgent(ctx context.Context, spaceID int64, url string, startTime, endTime int64) (int64, error) + CallTraceAgent(ctx context.Context, spaceID int64, url string, exptId int64, startTime, endTime int64) (int64, error) GetReport(ctx context.Context, spaceID, reportID int64) (report string, status entity.ReportStatus, err error) } diff --git a/backend/modules/evaluation/domain/service/insight_analysis_impl.go b/backend/modules/evaluation/domain/service/insight_analysis_impl.go index 7ad1cc8e2..33518a9ab 100644 --- a/backend/modules/evaluation/domain/service/insight_analysis_impl.go +++ b/backend/modules/evaluation/domain/service/insight_analysis_impl.go @@ -127,7 +127,7 @@ func (e ExptInsightAnalysisServiceImpl) GenAnalysisReport(ctx context.Context, s return err } - reportID, err := e.agentAdapter.CallTraceAgent(ctx, spaceID, url, startTime, endTime) + reportID, err := e.agentAdapter.CallTraceAgent(ctx, spaceID, url, exptID, startTime, endTime) if err != nil { return err } diff --git a/backend/modules/evaluation/infra/rpc/agent/agent.go b/backend/modules/evaluation/infra/rpc/agent/agent.go index bea8d450e..659aee2e9 100644 --- a/backend/modules/evaluation/infra/rpc/agent/agent.go +++ b/backend/modules/evaluation/infra/rpc/agent/agent.go @@ -18,7 +18,7 @@ func NewAgentAdapter() rpc.IAgentAdapter { return &AgentAdapter{} } -func (a AgentAdapter) CallTraceAgent(ctx context.Context, spaceID int64, url string, startTime, endTime int64) (int64, error) { +func (a AgentAdapter) CallTraceAgent(ctx context.Context, spaceID int64, url string, exptId int64, startTime, endTime int64) (int64, error) { return 0, errorx.NewByCode(errno.CommonInternalErrorCode, errorx.WithExtraMsg("CallTraceAgent not implement")) } From 59b856f7f7c8562ec8a1b56eeb061efbf3b77338 Mon Sep 17 00:00:00 2001 From: xueyizheng Date: Tue, 25 Nov 2025 14:28:15 +0800 Subject: [PATCH 14/21] insight analysis add index list for front end --- .../coze/loop/evaluation/domain/expt/expt.go | 372 +++++++++++++++++- .../evaluation/domain/expt/expt_validator.go | 3 + .../loop/evaluation/domain/expt/k-expt.go | 261 ++++++++++++ .../experiment/expt_insight_analysis.go | 15 + .../evaluation/application/experiment_app.go | 10 +- .../domain/component/rpc/mocks/trace_agent.go | 12 +- .../domain/component/rpc/trace_agent.go | 17 +- .../modules/evaluation/domain/entity/event.go | 8 +- .../entity/expt_insight_analysis_record.go | 6 + .../domain/service/insight_analysis.go | 4 +- .../domain/service/insight_analysis_impl.go | 57 ++- .../service/insight_analysis_impl_test.go | 4 +- .../infra/mq/rocket/consumer/expt_export.go | 2 +- .../evaluation/infra/rpc/agent/agent.go | 4 +- .../coze/loop/evaluation/domain/expt.thrift | 7 + 15 files changed, 726 insertions(+), 56 deletions(-) diff --git a/backend/kitex_gen/coze/loop/evaluation/domain/expt/expt.go b/backend/kitex_gen/coze/loop/evaluation/domain/expt/expt.go index 42f756729..79d5031c9 100644 --- a/backend/kitex_gen/coze/loop/evaluation/domain/expt/expt.go +++ b/backend/kitex_gen/coze/loop/evaluation/domain/expt/expt.go @@ -17540,6 +17540,7 @@ type ExptInsightAnalysisRecord struct { AnalysisReportContent *string `thrift:"analysis_report_content,6,optional" frugal:"6,optional,string" form:"analysis_report_content" json:"analysis_report_content,omitempty" query:"analysis_report_content"` ExptInsightAnalysisFeedback *ExptInsightAnalysisFeedback `thrift:"expt_insight_analysis_feedback,7,optional" frugal:"7,optional,ExptInsightAnalysisFeedback" form:"expt_insight_analysis_feedback" json:"expt_insight_analysis_feedback,omitempty" query:"expt_insight_analysis_feedback"` BaseInfo *common.BaseInfo `thrift:"base_info,8,optional" frugal:"8,optional,common.BaseInfo" form:"base_info" json:"base_info,omitempty" query:"base_info"` + AnalysisReportIndex []*ExptInsightAnalysisIndex `thrift:"analysis_report_index,21,optional" frugal:"21,optional,list" form:"analysis_report_index" json:"analysis_report_index,omitempty" query:"analysis_report_index"` } func NewExptInsightAnalysisRecord() *ExptInsightAnalysisRecord { @@ -17624,6 +17625,18 @@ func (p *ExptInsightAnalysisRecord) GetBaseInfo() (v *common.BaseInfo) { } return p.BaseInfo } + +var ExptInsightAnalysisRecord_AnalysisReportIndex_DEFAULT []*ExptInsightAnalysisIndex + +func (p *ExptInsightAnalysisRecord) GetAnalysisReportIndex() (v []*ExptInsightAnalysisIndex) { + if p == nil { + return + } + if !p.IsSetAnalysisReportIndex() { + return ExptInsightAnalysisRecord_AnalysisReportIndex_DEFAULT + } + return p.AnalysisReportIndex +} func (p *ExptInsightAnalysisRecord) SetRecordID(val int64) { p.RecordID = val } @@ -17648,16 +17661,20 @@ func (p *ExptInsightAnalysisRecord) SetExptInsightAnalysisFeedback(val *ExptInsi func (p *ExptInsightAnalysisRecord) SetBaseInfo(val *common.BaseInfo) { p.BaseInfo = val } +func (p *ExptInsightAnalysisRecord) SetAnalysisReportIndex(val []*ExptInsightAnalysisIndex) { + p.AnalysisReportIndex = val +} var fieldIDToName_ExptInsightAnalysisRecord = map[int16]string{ - 1: "record_id", - 2: "workspace_id", - 3: "expt_id", - 4: "analysis_status", - 5: "analysis_report_id", - 6: "analysis_report_content", - 7: "expt_insight_analysis_feedback", - 8: "base_info", + 1: "record_id", + 2: "workspace_id", + 3: "expt_id", + 4: "analysis_status", + 5: "analysis_report_id", + 6: "analysis_report_content", + 7: "expt_insight_analysis_feedback", + 8: "base_info", + 21: "analysis_report_index", } func (p *ExptInsightAnalysisRecord) IsSetAnalysisReportID() bool { @@ -17676,6 +17693,10 @@ func (p *ExptInsightAnalysisRecord) IsSetBaseInfo() bool { return p.BaseInfo != nil } +func (p *ExptInsightAnalysisRecord) IsSetAnalysisReportIndex() bool { + return p.AnalysisReportIndex != nil +} + func (p *ExptInsightAnalysisRecord) Read(iprot thrift.TProtocol) (err error) { var fieldTypeId thrift.TType var fieldId int16 @@ -17766,6 +17787,14 @@ func (p *ExptInsightAnalysisRecord) Read(iprot thrift.TProtocol) (err error) { } else if err = iprot.Skip(fieldTypeId); err != nil { goto SkipFieldError } + case 21: + if fieldTypeId == thrift.LIST { + if err = p.ReadField21(iprot); err != nil { + goto ReadFieldError + } + } else if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } default: if err = iprot.Skip(fieldTypeId); err != nil { goto SkipFieldError @@ -17898,6 +17927,29 @@ func (p *ExptInsightAnalysisRecord) ReadField8(iprot thrift.TProtocol) error { p.BaseInfo = _field return nil } +func (p *ExptInsightAnalysisRecord) ReadField21(iprot thrift.TProtocol) error { + _, size, err := iprot.ReadListBegin() + if err != nil { + return err + } + _field := make([]*ExptInsightAnalysisIndex, 0, size) + values := make([]ExptInsightAnalysisIndex, size) + for i := 0; i < size; i++ { + _elem := &values[i] + _elem.InitDefault() + + if err := _elem.Read(iprot); err != nil { + return err + } + + _field = append(_field, _elem) + } + if err := iprot.ReadListEnd(); err != nil { + return err + } + p.AnalysisReportIndex = _field + return nil +} func (p *ExptInsightAnalysisRecord) Write(oprot thrift.TProtocol) (err error) { var fieldId int16 @@ -17937,6 +17989,10 @@ func (p *ExptInsightAnalysisRecord) Write(oprot thrift.TProtocol) (err error) { fieldId = 8 goto WriteFieldError } + if err = p.writeField21(oprot); err != nil { + fieldId = 21 + goto WriteFieldError + } } if err = oprot.WriteFieldStop(); err != nil { goto WriteFieldStopError @@ -18091,6 +18147,32 @@ WriteFieldBeginError: WriteFieldEndError: return thrift.PrependError(fmt.Sprintf("%T write field 8 end error: ", p), err) } +func (p *ExptInsightAnalysisRecord) writeField21(oprot thrift.TProtocol) (err error) { + if p.IsSetAnalysisReportIndex() { + if err = oprot.WriteFieldBegin("analysis_report_index", thrift.LIST, 21); err != nil { + goto WriteFieldBeginError + } + if err := oprot.WriteListBegin(thrift.STRUCT, len(p.AnalysisReportIndex)); err != nil { + return err + } + for _, v := range p.AnalysisReportIndex { + if err := v.Write(oprot); err != nil { + return err + } + } + if err := oprot.WriteListEnd(); err != nil { + return err + } + if err = oprot.WriteFieldEnd(); err != nil { + goto WriteFieldEndError + } + } + return nil +WriteFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T write field 21 begin error: ", p), err) +WriteFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T write field 21 end error: ", p), err) +} func (p *ExptInsightAnalysisRecord) String() string { if p == nil { @@ -18130,6 +18212,9 @@ func (p *ExptInsightAnalysisRecord) DeepEqual(ano *ExptInsightAnalysisRecord) bo if !p.Field8DeepEqual(ano.BaseInfo) { return false } + if !p.Field21DeepEqual(ano.AnalysisReportIndex) { + return false + } return true } @@ -18199,6 +18284,277 @@ func (p *ExptInsightAnalysisRecord) Field8DeepEqual(src *common.BaseInfo) bool { } return true } +func (p *ExptInsightAnalysisRecord) Field21DeepEqual(src []*ExptInsightAnalysisIndex) bool { + + if len(p.AnalysisReportIndex) != len(src) { + return false + } + for i, v := range p.AnalysisReportIndex { + _src := src[i] + if !v.DeepEqual(_src) { + return false + } + } + return true +} + +type ExptInsightAnalysisIndex struct { + ID *string `thrift:"id,1,optional" frugal:"1,optional,string" form:"id" json:"id,omitempty" query:"id"` + Title *string `thrift:"title,2,optional" frugal:"2,optional,string" form:"title" json:"title,omitempty" query:"title"` +} + +func NewExptInsightAnalysisIndex() *ExptInsightAnalysisIndex { + return &ExptInsightAnalysisIndex{} +} + +func (p *ExptInsightAnalysisIndex) InitDefault() { +} + +var ExptInsightAnalysisIndex_ID_DEFAULT string + +func (p *ExptInsightAnalysisIndex) GetID() (v string) { + if p == nil { + return + } + if !p.IsSetID() { + return ExptInsightAnalysisIndex_ID_DEFAULT + } + return *p.ID +} + +var ExptInsightAnalysisIndex_Title_DEFAULT string + +func (p *ExptInsightAnalysisIndex) GetTitle() (v string) { + if p == nil { + return + } + if !p.IsSetTitle() { + return ExptInsightAnalysisIndex_Title_DEFAULT + } + return *p.Title +} +func (p *ExptInsightAnalysisIndex) SetID(val *string) { + p.ID = val +} +func (p *ExptInsightAnalysisIndex) SetTitle(val *string) { + p.Title = val +} + +var fieldIDToName_ExptInsightAnalysisIndex = map[int16]string{ + 1: "id", + 2: "title", +} + +func (p *ExptInsightAnalysisIndex) IsSetID() bool { + return p.ID != nil +} + +func (p *ExptInsightAnalysisIndex) IsSetTitle() bool { + return p.Title != nil +} + +func (p *ExptInsightAnalysisIndex) Read(iprot thrift.TProtocol) (err error) { + var fieldTypeId thrift.TType + var fieldId int16 + + if _, err = iprot.ReadStructBegin(); err != nil { + goto ReadStructBeginError + } + + for { + _, fieldTypeId, fieldId, err = iprot.ReadFieldBegin() + if err != nil { + goto ReadFieldBeginError + } + if fieldTypeId == thrift.STOP { + break + } + + switch fieldId { + case 1: + if fieldTypeId == thrift.STRING { + if err = p.ReadField1(iprot); err != nil { + goto ReadFieldError + } + } else if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + case 2: + if fieldTypeId == thrift.STRING { + if err = p.ReadField2(iprot); err != nil { + goto ReadFieldError + } + } else if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + default: + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + } + if err = iprot.ReadFieldEnd(); err != nil { + goto ReadFieldEndError + } + } + if err = iprot.ReadStructEnd(); err != nil { + goto ReadStructEndError + } + + return nil +ReadStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T read struct begin error: ", p), err) +ReadFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T read field %d begin error: ", p, fieldId), err) +ReadFieldError: + return thrift.PrependError(fmt.Sprintf("%T read field %d '%s' error: ", p, fieldId, fieldIDToName_ExptInsightAnalysisIndex[fieldId]), err) +SkipFieldError: + return thrift.PrependError(fmt.Sprintf("%T field %d skip type %d error: ", p, fieldId, fieldTypeId), err) + +ReadFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T read field end error", p), err) +ReadStructEndError: + return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err) +} + +func (p *ExptInsightAnalysisIndex) ReadField1(iprot thrift.TProtocol) error { + + var _field *string + if v, err := iprot.ReadString(); err != nil { + return err + } else { + _field = &v + } + p.ID = _field + return nil +} +func (p *ExptInsightAnalysisIndex) ReadField2(iprot thrift.TProtocol) error { + + var _field *string + if v, err := iprot.ReadString(); err != nil { + return err + } else { + _field = &v + } + p.Title = _field + return nil +} + +func (p *ExptInsightAnalysisIndex) Write(oprot thrift.TProtocol) (err error) { + var fieldId int16 + if err = oprot.WriteStructBegin("ExptInsightAnalysisIndex"); err != nil { + goto WriteStructBeginError + } + if p != nil { + if err = p.writeField1(oprot); err != nil { + fieldId = 1 + goto WriteFieldError + } + if err = p.writeField2(oprot); err != nil { + fieldId = 2 + goto WriteFieldError + } + } + if err = oprot.WriteFieldStop(); err != nil { + goto WriteFieldStopError + } + if err = oprot.WriteStructEnd(); err != nil { + goto WriteStructEndError + } + return nil +WriteStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err) +WriteFieldError: + return thrift.PrependError(fmt.Sprintf("%T write field %d error: ", p, fieldId), err) +WriteFieldStopError: + return thrift.PrependError(fmt.Sprintf("%T write field stop error: ", p), err) +WriteStructEndError: + return thrift.PrependError(fmt.Sprintf("%T write struct end error: ", p), err) +} + +func (p *ExptInsightAnalysisIndex) writeField1(oprot thrift.TProtocol) (err error) { + if p.IsSetID() { + if err = oprot.WriteFieldBegin("id", thrift.STRING, 1); err != nil { + goto WriteFieldBeginError + } + if err := oprot.WriteString(*p.ID); err != nil { + return err + } + if err = oprot.WriteFieldEnd(); err != nil { + goto WriteFieldEndError + } + } + return nil +WriteFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T write field 1 begin error: ", p), err) +WriteFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T write field 1 end error: ", p), err) +} +func (p *ExptInsightAnalysisIndex) writeField2(oprot thrift.TProtocol) (err error) { + if p.IsSetTitle() { + if err = oprot.WriteFieldBegin("title", thrift.STRING, 2); err != nil { + goto WriteFieldBeginError + } + if err := oprot.WriteString(*p.Title); err != nil { + return err + } + if err = oprot.WriteFieldEnd(); err != nil { + goto WriteFieldEndError + } + } + return nil +WriteFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T write field 2 begin error: ", p), err) +WriteFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T write field 2 end error: ", p), err) +} + +func (p *ExptInsightAnalysisIndex) String() string { + if p == nil { + return "" + } + return fmt.Sprintf("ExptInsightAnalysisIndex(%+v)", *p) + +} + +func (p *ExptInsightAnalysisIndex) DeepEqual(ano *ExptInsightAnalysisIndex) bool { + if p == ano { + return true + } else if p == nil || ano == nil { + return false + } + if !p.Field1DeepEqual(ano.ID) { + return false + } + if !p.Field2DeepEqual(ano.Title) { + return false + } + return true +} + +func (p *ExptInsightAnalysisIndex) Field1DeepEqual(src *string) bool { + + if p.ID == src { + return true + } else if p.ID == nil || src == nil { + return false + } + if strings.Compare(*p.ID, *src) != 0 { + return false + } + return true +} +func (p *ExptInsightAnalysisIndex) Field2DeepEqual(src *string) bool { + + if p.Title == src { + return true + } else if p.Title == nil || src == nil { + return false + } + if strings.Compare(*p.Title, *src) != 0 { + return false + } + return true +} // 洞察分析反馈统计 type ExptInsightAnalysisFeedback struct { diff --git a/backend/kitex_gen/coze/loop/evaluation/domain/expt/expt_validator.go b/backend/kitex_gen/coze/loop/evaluation/domain/expt/expt_validator.go index 09ca4bbec..9aed3b607 100644 --- a/backend/kitex_gen/coze/loop/evaluation/domain/expt/expt_validator.go +++ b/backend/kitex_gen/coze/loop/evaluation/domain/expt/expt_validator.go @@ -315,6 +315,9 @@ func (p *ExptInsightAnalysisRecord) IsValid() error { } return nil } +func (p *ExptInsightAnalysisIndex) IsValid() error { + return nil +} func (p *ExptInsightAnalysisFeedback) IsValid() error { return nil } diff --git a/backend/kitex_gen/coze/loop/evaluation/domain/expt/k-expt.go b/backend/kitex_gen/coze/loop/evaluation/domain/expt/k-expt.go index f281ebbfc..cd5ef5bd7 100644 --- a/backend/kitex_gen/coze/loop/evaluation/domain/expt/k-expt.go +++ b/backend/kitex_gen/coze/loop/evaluation/domain/expt/k-expt.go @@ -12228,6 +12228,20 @@ func (p *ExptInsightAnalysisRecord) FastRead(buf []byte) (int, error) { goto SkipFieldError } } + case 21: + if fieldTypeId == thrift.LIST { + l, err = p.FastReadField21(buf[offset:]) + offset += l + if err != nil { + goto ReadFieldError + } + } else { + l, err = thrift.Binary.Skip(buf[offset:], fieldTypeId) + offset += l + if err != nil { + goto SkipFieldError + } + } default: l, err = thrift.Binary.Skip(buf[offset:], fieldTypeId) offset += l @@ -12375,6 +12389,31 @@ func (p *ExptInsightAnalysisRecord) FastReadField8(buf []byte) (int, error) { return offset, nil } +func (p *ExptInsightAnalysisRecord) FastReadField21(buf []byte) (int, error) { + offset := 0 + + _, size, l, err := thrift.Binary.ReadListBegin(buf[offset:]) + offset += l + if err != nil { + return offset, err + } + _field := make([]*ExptInsightAnalysisIndex, 0, size) + values := make([]ExptInsightAnalysisIndex, size) + for i := 0; i < size; i++ { + _elem := &values[i] + _elem.InitDefault() + if l, err := _elem.FastRead(buf[offset:]); err != nil { + return offset, err + } else { + offset += l + } + + _field = append(_field, _elem) + } + p.AnalysisReportIndex = _field + return offset, nil +} + func (p *ExptInsightAnalysisRecord) FastWrite(buf []byte) int { return p.FastWriteNocopy(buf, nil) } @@ -12390,6 +12429,7 @@ func (p *ExptInsightAnalysisRecord) FastWriteNocopy(buf []byte, w thrift.NocopyW offset += p.fastWriteField6(buf[offset:], w) offset += p.fastWriteField7(buf[offset:], w) offset += p.fastWriteField8(buf[offset:], w) + offset += p.fastWriteField21(buf[offset:], w) } offset += thrift.Binary.WriteFieldStop(buf[offset:]) return offset @@ -12406,6 +12446,7 @@ func (p *ExptInsightAnalysisRecord) BLength() int { l += p.field6Length() l += p.field7Length() l += p.field8Length() + l += p.field21Length() } l += thrift.Binary.FieldStopLength() return l @@ -12475,6 +12516,22 @@ func (p *ExptInsightAnalysisRecord) fastWriteField8(buf []byte, w thrift.NocopyW return offset } +func (p *ExptInsightAnalysisRecord) fastWriteField21(buf []byte, w thrift.NocopyWriter) int { + offset := 0 + if p.IsSetAnalysisReportIndex() { + offset += thrift.Binary.WriteFieldBegin(buf[offset:], thrift.LIST, 21) + listBeginOffset := offset + offset += thrift.Binary.ListBeginLength() + var length int + for _, v := range p.AnalysisReportIndex { + length++ + offset += v.FastWriteNocopy(buf[offset:], w) + } + thrift.Binary.WriteListBegin(buf[listBeginOffset:], thrift.STRUCT, length) + } + return offset +} + func (p *ExptInsightAnalysisRecord) field1Length() int { l := 0 l += thrift.Binary.FieldBeginLength() @@ -12539,6 +12596,19 @@ func (p *ExptInsightAnalysisRecord) field8Length() int { return l } +func (p *ExptInsightAnalysisRecord) field21Length() int { + l := 0 + if p.IsSetAnalysisReportIndex() { + l += thrift.Binary.FieldBeginLength() + l += thrift.Binary.ListBeginLength() + for _, v := range p.AnalysisReportIndex { + _ = v + l += v.BLength() + } + } + return l +} + func (p *ExptInsightAnalysisRecord) DeepCopy(s interface{}) error { src, ok := s.(*ExptInsightAnalysisRecord) if !ok { @@ -12584,6 +12654,197 @@ func (p *ExptInsightAnalysisRecord) DeepCopy(s interface{}) error { } p.BaseInfo = _baseInfo + if src.AnalysisReportIndex != nil { + p.AnalysisReportIndex = make([]*ExptInsightAnalysisIndex, 0, len(src.AnalysisReportIndex)) + for _, elem := range src.AnalysisReportIndex { + var _elem *ExptInsightAnalysisIndex + if elem != nil { + _elem = &ExptInsightAnalysisIndex{} + if err := _elem.DeepCopy(elem); err != nil { + return err + } + } + + p.AnalysisReportIndex = append(p.AnalysisReportIndex, _elem) + } + } + + return nil +} + +func (p *ExptInsightAnalysisIndex) FastRead(buf []byte) (int, error) { + + var err error + var offset int + var l int + var fieldTypeId thrift.TType + var fieldId int16 + for { + fieldTypeId, fieldId, l, err = thrift.Binary.ReadFieldBegin(buf[offset:]) + offset += l + if err != nil { + goto ReadFieldBeginError + } + if fieldTypeId == thrift.STOP { + break + } + switch fieldId { + case 1: + if fieldTypeId == thrift.STRING { + l, err = p.FastReadField1(buf[offset:]) + offset += l + if err != nil { + goto ReadFieldError + } + } else { + l, err = thrift.Binary.Skip(buf[offset:], fieldTypeId) + offset += l + if err != nil { + goto SkipFieldError + } + } + case 2: + if fieldTypeId == thrift.STRING { + l, err = p.FastReadField2(buf[offset:]) + offset += l + if err != nil { + goto ReadFieldError + } + } else { + l, err = thrift.Binary.Skip(buf[offset:], fieldTypeId) + offset += l + if err != nil { + goto SkipFieldError + } + } + default: + l, err = thrift.Binary.Skip(buf[offset:], fieldTypeId) + offset += l + if err != nil { + goto SkipFieldError + } + } + } + + return offset, nil +ReadFieldBeginError: + return offset, thrift.PrependError(fmt.Sprintf("%T read field %d begin error: ", p, fieldId), err) +ReadFieldError: + return offset, thrift.PrependError(fmt.Sprintf("%T read field %d '%s' error: ", p, fieldId, fieldIDToName_ExptInsightAnalysisIndex[fieldId]), err) +SkipFieldError: + return offset, thrift.PrependError(fmt.Sprintf("%T field %d skip type %d error: ", p, fieldId, fieldTypeId), err) +} + +func (p *ExptInsightAnalysisIndex) FastReadField1(buf []byte) (int, error) { + offset := 0 + + var _field *string + if v, l, err := thrift.Binary.ReadString(buf[offset:]); err != nil { + return offset, err + } else { + offset += l + _field = &v + } + p.ID = _field + return offset, nil +} + +func (p *ExptInsightAnalysisIndex) FastReadField2(buf []byte) (int, error) { + offset := 0 + + var _field *string + if v, l, err := thrift.Binary.ReadString(buf[offset:]); err != nil { + return offset, err + } else { + offset += l + _field = &v + } + p.Title = _field + return offset, nil +} + +func (p *ExptInsightAnalysisIndex) FastWrite(buf []byte) int { + return p.FastWriteNocopy(buf, nil) +} + +func (p *ExptInsightAnalysisIndex) FastWriteNocopy(buf []byte, w thrift.NocopyWriter) int { + offset := 0 + if p != nil { + offset += p.fastWriteField1(buf[offset:], w) + offset += p.fastWriteField2(buf[offset:], w) + } + offset += thrift.Binary.WriteFieldStop(buf[offset:]) + return offset +} + +func (p *ExptInsightAnalysisIndex) BLength() int { + l := 0 + if p != nil { + l += p.field1Length() + l += p.field2Length() + } + l += thrift.Binary.FieldStopLength() + return l +} + +func (p *ExptInsightAnalysisIndex) fastWriteField1(buf []byte, w thrift.NocopyWriter) int { + offset := 0 + if p.IsSetID() { + offset += thrift.Binary.WriteFieldBegin(buf[offset:], thrift.STRING, 1) + offset += thrift.Binary.WriteStringNocopy(buf[offset:], w, *p.ID) + } + return offset +} + +func (p *ExptInsightAnalysisIndex) fastWriteField2(buf []byte, w thrift.NocopyWriter) int { + offset := 0 + if p.IsSetTitle() { + offset += thrift.Binary.WriteFieldBegin(buf[offset:], thrift.STRING, 2) + offset += thrift.Binary.WriteStringNocopy(buf[offset:], w, *p.Title) + } + return offset +} + +func (p *ExptInsightAnalysisIndex) field1Length() int { + l := 0 + if p.IsSetID() { + l += thrift.Binary.FieldBeginLength() + l += thrift.Binary.StringLengthNocopy(*p.ID) + } + return l +} + +func (p *ExptInsightAnalysisIndex) field2Length() int { + l := 0 + if p.IsSetTitle() { + l += thrift.Binary.FieldBeginLength() + l += thrift.Binary.StringLengthNocopy(*p.Title) + } + return l +} + +func (p *ExptInsightAnalysisIndex) DeepCopy(s interface{}) error { + src, ok := s.(*ExptInsightAnalysisIndex) + if !ok { + return fmt.Errorf("%T's type not matched %T", s, p) + } + + if src.ID != nil { + var tmp string + if *src.ID != "" { + tmp = kutils.StringDeepCopy(*src.ID) + } + p.ID = &tmp + } + + if src.Title != nil { + var tmp string + if *src.Title != "" { + tmp = kutils.StringDeepCopy(*src.Title) + } + p.Title = &tmp + } + return nil } diff --git a/backend/modules/evaluation/application/convertor/experiment/expt_insight_analysis.go b/backend/modules/evaluation/application/convertor/experiment/expt_insight_analysis.go index 249311f85..c4d9da033 100644 --- a/backend/modules/evaluation/application/convertor/experiment/expt_insight_analysis.go +++ b/backend/modules/evaluation/application/convertor/experiment/expt_insight_analysis.go @@ -20,6 +20,7 @@ func ExptInsightAnalysisRecordDO2DTO(do *entity.ExptInsightAnalysisRecord) *doma AnalysisStatus: InsightAnalysisStatus2DTO(do.Status), AnalysisReportID: do.AnalysisReportID, AnalysisReportContent: ptr.Of(do.AnalysisReportContent), + AnalysisReportIndex: AnalysisReportIndex2DTO(do.AnalysisReportIndex), ExptInsightAnalysisFeedback: ExptInsightAnalysisFeedbackDO2DTO(do.ExptInsightAnalysisFeedback), BaseInfo: &domain_common.BaseInfo{ CreatedBy: &domain_common.UserInfo{ @@ -32,6 +33,20 @@ func ExptInsightAnalysisRecordDO2DTO(do *entity.ExptInsightAnalysisRecord) *doma return dto } +func AnalysisReportIndex2DTO(index []*entity.InsightAnalysisReportIndex) []*domain_expt.ExptInsightAnalysisIndex { + if len(index) == 0 { + return nil + } + dto := make([]*domain_expt.ExptInsightAnalysisIndex, 0, len(index)) + for _, item := range index { + dto = append(dto, &domain_expt.ExptInsightAnalysisIndex{ + ID: ptr.Of(item.ID), + Title: ptr.Of(item.Title), + }) + } + return dto +} + func ExptInsightAnalysisFeedbackDO2DTO(do entity.ExptInsightAnalysisFeedback) *domain_expt.ExptInsightAnalysisFeedback { dto := &domain_expt.ExptInsightAnalysisFeedback{ UpvoteCnt: ptr.Of(int32(do.UpvoteCount)), diff --git a/backend/modules/evaluation/application/experiment_app.go b/backend/modules/evaluation/application/experiment_app.go index d3b4505ab..4e2e01202 100644 --- a/backend/modules/evaluation/application/experiment_app.go +++ b/backend/modules/evaluation/application/experiment_app.go @@ -1264,20 +1264,12 @@ func (e *experimentApplication) InsightAnalysisExperiment(ctx context.Context, r return nil, err } - var startTime, endTime *int64 - if got.StartAt != nil { - startTime = gptr.Of(got.StartAt.UnixMilli()) - } - if got.EndAt != nil { - endTime = gptr.Of(got.EndAt.UnixMilli()) - } - recordID, err := e.CreateAnalysisRecord(ctx, &entity.ExptInsightAnalysisRecord{ SpaceID: req.GetWorkspaceID(), ExptID: req.GetExptID(), CreatedBy: session.UserID, Status: entity.InsightAnalysisStatus_Running, - }, session, gptr.Indirect(startTime), gptr.Indirect(endTime)) + }, session) if err != nil { return nil, err } diff --git a/backend/modules/evaluation/domain/component/rpc/mocks/trace_agent.go b/backend/modules/evaluation/domain/component/rpc/mocks/trace_agent.go index 8ba43466c..896f24d82 100644 --- a/backend/modules/evaluation/domain/component/rpc/mocks/trace_agent.go +++ b/backend/modules/evaluation/domain/component/rpc/mocks/trace_agent.go @@ -42,26 +42,26 @@ func (m *MockIAgentAdapter) EXPECT() *MockIAgentAdapterMockRecorder { } // CallTraceAgent mocks base method. -func (m *MockIAgentAdapter) CallTraceAgent(ctx context.Context, spaceID int64, url string, startTime, endTime int64) (int64, error) { +func (m *MockIAgentAdapter) CallTraceAgent(ctx context.Context, spaceID int64, url string, exptId, startTime, endTime int64) (int64, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "CallTraceAgent", ctx, spaceID, url, startTime, endTime) + ret := m.ctrl.Call(m, "CallTraceAgent", ctx, spaceID, url, exptId, startTime, endTime) ret0, _ := ret[0].(int64) ret1, _ := ret[1].(error) return ret0, ret1 } // CallTraceAgent indicates an expected call of CallTraceAgent. -func (mr *MockIAgentAdapterMockRecorder) CallTraceAgent(ctx, spaceID, url, startTime, endTime any) *gomock.Call { +func (mr *MockIAgentAdapterMockRecorder) CallTraceAgent(ctx, spaceID, url, exptId, startTime, endTime any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CallTraceAgent", reflect.TypeOf((*MockIAgentAdapter)(nil).CallTraceAgent), ctx, spaceID, url, startTime, endTime) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CallTraceAgent", reflect.TypeOf((*MockIAgentAdapter)(nil).CallTraceAgent), ctx, spaceID, url, exptId, startTime, endTime) } // GetReport mocks base method. -func (m *MockIAgentAdapter) GetReport(ctx context.Context, spaceID, reportID int64) (string, entity.ReportStatus, error) { +func (m *MockIAgentAdapter) GetReport(ctx context.Context, spaceID, reportID int64) (string, []*entity.InsightAnalysisReportIndex, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetReport", ctx, spaceID, reportID) ret0, _ := ret[0].(string) - ret1, _ := ret[1].(entity.ReportStatus) + ret1, _ := ret[1].([]*entity.InsightAnalysisReportIndex) ret2, _ := ret[2].(error) return ret0, ret1, ret2 } diff --git a/backend/modules/evaluation/domain/component/rpc/trace_agent.go b/backend/modules/evaluation/domain/component/rpc/trace_agent.go index 462271460..66651fef9 100644 --- a/backend/modules/evaluation/domain/component/rpc/trace_agent.go +++ b/backend/modules/evaluation/domain/component/rpc/trace_agent.go @@ -11,6 +11,19 @@ import ( //go:generate mockgen -destination=mocks/trace_agent.go -package=mocks . IAgentAdapter type IAgentAdapter interface { - CallTraceAgent(ctx context.Context, spaceID int64, url string, exptId int64, startTime, endTime int64) (int64, error) - GetReport(ctx context.Context, spaceID, reportID int64) (report string, status entity.ReportStatus, err error) + CallTraceAgent(ctx context.Context, param *CallTraceAgentParam) (int64, error) + GetReport(ctx context.Context, spaceID, reportID int64) (report string, list []*entity.InsightAnalysisReportIndex, status entity.ReportStatus, err error) +} + +type CallTraceAgentParam struct { + SpaceID int64 + ExptID int64 + Url string + + StartTime int64 // in ms + EndTime int64 // in ms + + EvalTargetType entity.EvalTargetType // now support prompt only + EvalTargetID int64 + EvalTargetVersionID int64 } diff --git a/backend/modules/evaluation/domain/entity/event.go b/backend/modules/evaluation/domain/entity/event.go index 3e8b6bc95..05d309766 100644 --- a/backend/modules/evaluation/domain/entity/event.go +++ b/backend/modules/evaluation/domain/entity/event.go @@ -120,11 +120,9 @@ type ExportCSVEvent struct { ExperimentID int64 SpaceID int64 - Session *Session - ExportScene ExportScene - CreatedAt int64 - ExptStartTime int64 // Unix Time - ExptEndTime int64 // Unix Time + Session *Session + ExportScene ExportScene + CreatedAt int64 } type ExportScene int diff --git a/backend/modules/evaluation/domain/entity/expt_insight_analysis_record.go b/backend/modules/evaluation/domain/entity/expt_insight_analysis_record.go index bfb50f901..0403dc27a 100644 --- a/backend/modules/evaluation/domain/entity/expt_insight_analysis_record.go +++ b/backend/modules/evaluation/domain/entity/expt_insight_analysis_record.go @@ -26,6 +26,7 @@ type ExptInsightAnalysisRecord struct { ExptResultFilePath *string AnalysisReportID *int64 AnalysisReportContent string + AnalysisReportIndex []*InsightAnalysisReportIndex CreatedBy string CreatedAt time.Time UpdatedAt time.Time @@ -104,3 +105,8 @@ const ( // 生成失败 ReportStatus_Failed ReportStatus = 3 ) + +type InsightAnalysisReportIndex struct { + ID string + Title string +} diff --git a/backend/modules/evaluation/domain/service/insight_analysis.go b/backend/modules/evaluation/domain/service/insight_analysis.go index 623dca355..e345fd7be 100644 --- a/backend/modules/evaluation/domain/service/insight_analysis.go +++ b/backend/modules/evaluation/domain/service/insight_analysis.go @@ -10,8 +10,8 @@ import ( ) type IExptInsightAnalysisService interface { - CreateAnalysisRecord(ctx context.Context, record *entity.ExptInsightAnalysisRecord, session *entity.Session, startTime, endTime int64) (int64, error) - GenAnalysisReport(ctx context.Context, spaceID, exptID, recordID, CreateAt, startTime, endTime int64) error + CreateAnalysisRecord(ctx context.Context, record *entity.ExptInsightAnalysisRecord, session *entity.Session) (int64, error) + GenAnalysisReport(ctx context.Context, spaceID, exptID, recordID, CreateAt int64) error GetAnalysisRecordByID(ctx context.Context, spaceID, exptID, recordID int64, session *entity.Session) (*entity.ExptInsightAnalysisRecord, error) ListAnalysisRecord(ctx context.Context, spaceID, exptID int64, page entity.Page, session *entity.Session) ([]*entity.ExptInsightAnalysisRecord, int64, error) DeleteAnalysisRecord(ctx context.Context, spaceID, exptID, recordID int64) error diff --git a/backend/modules/evaluation/domain/service/insight_analysis_impl.go b/backend/modules/evaluation/domain/service/insight_analysis_impl.go index 33518a9ab..98ea508ad 100644 --- a/backend/modules/evaluation/domain/service/insight_analysis_impl.go +++ b/backend/modules/evaluation/domain/service/insight_analysis_impl.go @@ -55,20 +55,18 @@ func NewInsightAnalysisService(repo repo.IExptInsightAnalysisRecordRepo, } } -func (e ExptInsightAnalysisServiceImpl) CreateAnalysisRecord(ctx context.Context, record *entity.ExptInsightAnalysisRecord, session *entity.Session, startTime, endTime int64) (int64, error) { +func (e ExptInsightAnalysisServiceImpl) CreateAnalysisRecord(ctx context.Context, record *entity.ExptInsightAnalysisRecord, session *entity.Session) (int64, error) { recordID, err := e.repo.CreateAnalysisRecord(ctx, record) if err != nil { return 0, err } exportEvent := &entity.ExportCSVEvent{ - ExportID: recordID, - ExperimentID: record.ExptID, - SpaceID: record.SpaceID, - ExportScene: entity.ExportSceneInsightAnalysis, - CreatedAt: time.Now().Unix(), - ExptStartTime: startTime, - ExptEndTime: endTime, + ExportID: recordID, + ExperimentID: record.ExptID, + SpaceID: record.SpaceID, + ExportScene: entity.ExportSceneInsightAnalysis, + CreatedAt: time.Now().Unix(), } err = e.exptPublisher.PublishExptExportCSVEvent(ctx, exportEvent, gptr.Of(time.Second*3)) if err != nil { @@ -78,7 +76,7 @@ func (e ExptInsightAnalysisServiceImpl) CreateAnalysisRecord(ctx context.Context return recordID, nil } -func (e ExptInsightAnalysisServiceImpl) GenAnalysisReport(ctx context.Context, spaceID, exptID, recordID, CreateAt, startTime, endTime int64) (err error) { +func (e ExptInsightAnalysisServiceImpl) GenAnalysisReport(ctx context.Context, spaceID, exptID, recordID, CreateAt int64) (err error) { analysisRecord, err := e.repo.GetAnalysisRecordByID(ctx, spaceID, exptID, recordID) if err != nil { return err @@ -127,7 +125,29 @@ func (e ExptInsightAnalysisServiceImpl) GenAnalysisReport(ctx context.Context, s return err } - reportID, err := e.agentAdapter.CallTraceAgent(ctx, spaceID, url, exptID, startTime, endTime) + expt, err := e.exptRepo.GetByID(ctx, exptID, spaceID) + if err != nil { + return err + } + + param := &rpc.CallTraceAgentParam{ + SpaceID: spaceID, + ExptID: exptID, + Url: url, + StartTime: expt.StartAt.UnixMilli(), + EndTime: expt.EndAt.UnixMilli(), + EvalTargetType: expt.TargetType, + } + + // only allow prompt eval target + if param.EvalTargetType == entity.EvalTargetTypeLoopPrompt { + param.EvalTargetID = expt.Target.ID + param.EvalTargetVersionID = expt.TargetVersionID + } else { + return errorx.NewByCode(errno.CommonInvalidParamCode, errorx.WithExtraMsg(fmt.Sprintf("[InsightAgent] Illegal evaltarget type %d for expt %d", param.EvalTargetType, exptID))) + } + + reportID, err := e.agentAdapter.CallTraceAgent(ctx, param) if err != nil { return err } @@ -137,13 +157,11 @@ func (e ExptInsightAnalysisServiceImpl) GenAnalysisReport(ctx context.Context, s // 发送时间检查分析报告生成状态 exportEvent := &entity.ExportCSVEvent{ - ExportID: recordID, - ExperimentID: exptID, - SpaceID: spaceID, - ExportScene: entity.ExportSceneInsightAnalysis, - CreatedAt: CreateAt, - ExptStartTime: startTime, - ExptEndTime: endTime, + ExportID: recordID, + ExperimentID: exptID, + SpaceID: spaceID, + ExportScene: entity.ExportSceneInsightAnalysis, + CreatedAt: CreateAt, } err = e.exptPublisher.PublishExptExportCSVEvent(ctx, exportEvent, gptr.Of(time.Minute*3)) if err != nil { @@ -154,7 +172,7 @@ func (e ExptInsightAnalysisServiceImpl) GenAnalysisReport(ctx context.Context, s } func (e ExptInsightAnalysisServiceImpl) checkAnalysisReportGenStatus(ctx context.Context, record *entity.ExptInsightAnalysisRecord, CreateAt int64) (err error) { - _, status, err := e.agentAdapter.GetReport(ctx, record.SpaceID, ptr.From(record.AnalysisReportID)) + _, _, status, err := e.agentAdapter.GetReport(ctx, record.SpaceID, ptr.From(record.AnalysisReportID)) if err != nil { return err } @@ -214,12 +232,13 @@ func (e ExptInsightAnalysisServiceImpl) GetAnalysisRecordByID(ctx context.Contex return analysisRecord, nil } - report, _, err := e.agentAdapter.GetReport(ctx, spaceID, ptr.From(analysisRecord.AnalysisReportID)) + report, reportIdx, _, err := e.agentAdapter.GetReport(ctx, spaceID, ptr.From(analysisRecord.AnalysisReportID)) if err != nil { return nil, err } analysisRecord.AnalysisReportContent = report + analysisRecord.AnalysisReportIndex = reportIdx upvoteCount, downvoteCount, err := e.repo.CountFeedbackVote(ctx, spaceID, exptID, recordID) if err != nil { diff --git a/backend/modules/evaluation/domain/service/insight_analysis_impl_test.go b/backend/modules/evaluation/domain/service/insight_analysis_impl_test.go index dbf918b6e..1f8d3dee1 100644 --- a/backend/modules/evaluation/domain/service/insight_analysis_impl_test.go +++ b/backend/modules/evaluation/domain/service/insight_analysis_impl_test.go @@ -134,7 +134,7 @@ func TestExptInsightAnalysisServiceImpl_CreateAnalysisRecord(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { tt.setup() - result, err := service.CreateAnalysisRecord(ctx, tt.record, tt.session, 0, 0) + result, err := service.CreateAnalysisRecord(ctx, tt.record, tt.session) if tt.wantErr { assert.Error(t, err) } else { @@ -325,7 +325,7 @@ func TestExptInsightAnalysisServiceImpl_GenAnalysisReport(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { tt.setup() - err := service.GenAnalysisReport(ctx, tt.spaceID, tt.exptID, tt.recordID, tt.createAt, 0, 0) + err := service.GenAnalysisReport(ctx, tt.spaceID, tt.exptID, tt.recordID, tt.createAt) if tt.wantErr { assert.Error(t, err) } else { diff --git a/backend/modules/evaluation/infra/mq/rocket/consumer/expt_export.go b/backend/modules/evaluation/infra/mq/rocket/consumer/expt_export.go index b3a3603b8..07e44f0fa 100644 --- a/backend/modules/evaluation/infra/mq/rocket/consumer/expt_export.go +++ b/backend/modules/evaluation/infra/mq/rocket/consumer/expt_export.go @@ -53,7 +53,7 @@ func (e *ExptExportConsumer) HandleMessage(ctx context.Context, ext *mq.MessageE func (e *ExptExportConsumer) handleEvent(ctx context.Context, event *entity.ExportCSVEvent) (err error) { switch event.ExportScene { case entity.ExportSceneInsightAnalysis: - err = e.exptInsightAnalysisService.GenAnalysisReport(ctx, event.SpaceID, event.ExperimentID, event.ExportID, event.CreatedAt, event.ExptStartTime, event.ExptEndTime) + err = e.exptInsightAnalysisService.GenAnalysisReport(ctx, event.SpaceID, event.ExperimentID, event.ExportID, event.CreatedAt) if err != nil { logs.CtxError(ctx, "ExptExportConsumer GenAnalysisReport fail, expt_id:%v, err: %v", event.ExperimentID, err) return nil diff --git a/backend/modules/evaluation/infra/rpc/agent/agent.go b/backend/modules/evaluation/infra/rpc/agent/agent.go index 659aee2e9..f58c2a9d4 100644 --- a/backend/modules/evaluation/infra/rpc/agent/agent.go +++ b/backend/modules/evaluation/infra/rpc/agent/agent.go @@ -22,6 +22,6 @@ func (a AgentAdapter) CallTraceAgent(ctx context.Context, spaceID int64, url str return 0, errorx.NewByCode(errno.CommonInternalErrorCode, errorx.WithExtraMsg("CallTraceAgent not implement")) } -func (a AgentAdapter) GetReport(ctx context.Context, spaceID, reportID int64) (report string, status entity.ReportStatus, err error) { - return "", 0, errorx.NewByCode(errno.CommonInternalErrorCode, errorx.WithExtraMsg("GetReport not implement")) +func (a AgentAdapter) GetReport(ctx context.Context, spaceID, reportID int64) (report string, list []*entity.InsightAnalysisReportIndex, status entity.ReportStatus, err error) { + return "", nil, entity.ReportStatus_Failed, errorx.NewByCode(errno.CommonInternalErrorCode, errorx.WithExtraMsg("GetReport not implement")) } diff --git a/idl/thrift/coze/loop/evaluation/domain/expt.thrift b/idl/thrift/coze/loop/evaluation/domain/expt.thrift index 20debff4d..2ba8c71af 100644 --- a/idl/thrift/coze/loop/evaluation/domain/expt.thrift +++ b/idl/thrift/coze/loop/evaluation/domain/expt.thrift @@ -481,6 +481,13 @@ struct ExptInsightAnalysisRecord { 6: optional string analysis_report_content 7: optional ExptInsightAnalysisFeedback expt_insight_analysis_feedback 8: optional common.BaseInfo base_info + + 21: optional list analysis_report_index +} + +struct ExptInsightAnalysisIndex { + 1: optional string id + 2: optional string title } // 洞察分析反馈统计 From c2966ba87b589370b529fe1fc89ad0dcdf627baf Mon Sep 17 00:00:00 2001 From: xueyizheng Date: Mon, 1 Dec 2025 16:16:10 +0800 Subject: [PATCH 15/21] fix --- backend/modules/evaluation/infra/rpc/agent/agent.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/modules/evaluation/infra/rpc/agent/agent.go b/backend/modules/evaluation/infra/rpc/agent/agent.go index f58c2a9d4..d7b79d58e 100644 --- a/backend/modules/evaluation/infra/rpc/agent/agent.go +++ b/backend/modules/evaluation/infra/rpc/agent/agent.go @@ -18,7 +18,7 @@ func NewAgentAdapter() rpc.IAgentAdapter { return &AgentAdapter{} } -func (a AgentAdapter) CallTraceAgent(ctx context.Context, spaceID int64, url string, exptId int64, startTime, endTime int64) (int64, error) { +func (a AgentAdapter) CallTraceAgent(ctx context.Context, param *rpc.CallTraceAgentParam) (int64, error) { return 0, errorx.NewByCode(errno.CommonInternalErrorCode, errorx.WithExtraMsg("CallTraceAgent not implement")) } From 3f64823103df265b9ba3799f1cb11401f544ab38 Mon Sep 17 00:00:00 2001 From: xueyizheng Date: Mon, 1 Dec 2025 20:33:43 +0800 Subject: [PATCH 16/21] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=EF=BC=8C=E9=81=BF?= =?UTF-8?q?=E5=85=8Dpanic?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/service/insight_analysis_impl.go | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/backend/modules/evaluation/domain/service/insight_analysis_impl.go b/backend/modules/evaluation/domain/service/insight_analysis_impl.go index 98ea508ad..b5e437849 100644 --- a/backend/modules/evaluation/domain/service/insight_analysis_impl.go +++ b/backend/modules/evaluation/domain/service/insight_analysis_impl.go @@ -129,6 +129,9 @@ func (e ExptInsightAnalysisServiceImpl) GenAnalysisReport(ctx context.Context, s if err != nil { return err } + if expt.StartAt == nil || expt.EndAt == nil { + logs.CtxWarn(ctx, "Experiment %d has no start or end time", exptID) + } param := &rpc.CallTraceAgentParam{ SpaceID: spaceID, @@ -139,12 +142,14 @@ func (e ExptInsightAnalysisServiceImpl) GenAnalysisReport(ctx context.Context, s EvalTargetType: expt.TargetType, } - // only allow prompt eval target - if param.EvalTargetType == entity.EvalTargetTypeLoopPrompt { + // only allow prompt eval target, but not return error here. The task will fail in the CallTraceAgent. + if param.EvalTargetType == entity.EvalTargetTypeLoopPrompt && expt.Target != nil { param.EvalTargetID = expt.Target.ID param.EvalTargetVersionID = expt.TargetVersionID + } else if expt.Target == nil { + logs.CtxWarn(ctx, "Experiment %d has no target", exptID) } else { - return errorx.NewByCode(errno.CommonInvalidParamCode, errorx.WithExtraMsg(fmt.Sprintf("[InsightAgent] Illegal evaltarget type %d for expt %d", param.EvalTargetType, exptID))) + logs.CtxWarn(ctx, "Illegal evaltarget type %d for expt %d", param.EvalTargetType, exptID) } reportID, err := e.agentAdapter.CallTraceAgent(ctx, param) From ea6d613818cc085695580d7f007324b85cee1300 Mon Sep 17 00:00:00 2001 From: xueyizheng Date: Mon, 1 Dec 2025 20:50:07 +0800 Subject: [PATCH 17/21] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E5=A4=84=E7=90=86?= =?UTF-8?q?=E6=96=B9=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/service/insight_analysis_impl.go | 21 ++++++++----------- 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/backend/modules/evaluation/domain/service/insight_analysis_impl.go b/backend/modules/evaluation/domain/service/insight_analysis_impl.go index b5e437849..c10dec8ec 100644 --- a/backend/modules/evaluation/domain/service/insight_analysis_impl.go +++ b/backend/modules/evaluation/domain/service/insight_analysis_impl.go @@ -134,21 +134,18 @@ func (e ExptInsightAnalysisServiceImpl) GenAnalysisReport(ctx context.Context, s } param := &rpc.CallTraceAgentParam{ - SpaceID: spaceID, - ExptID: exptID, - Url: url, - StartTime: expt.StartAt.UnixMilli(), - EndTime: expt.EndAt.UnixMilli(), - EvalTargetType: expt.TargetType, + SpaceID: spaceID, + ExptID: exptID, + Url: url, + StartTime: expt.StartAt.UnixMilli(), + EndTime: expt.EndAt.UnixMilli(), + EvalTargetType: expt.TargetType, + EvalTargetID: expt.TargetID, + EvalTargetVersionID: expt.TargetVersionID, } // only allow prompt eval target, but not return error here. The task will fail in the CallTraceAgent. - if param.EvalTargetType == entity.EvalTargetTypeLoopPrompt && expt.Target != nil { - param.EvalTargetID = expt.Target.ID - param.EvalTargetVersionID = expt.TargetVersionID - } else if expt.Target == nil { - logs.CtxWarn(ctx, "Experiment %d has no target", exptID) - } else { + if param.EvalTargetType != entity.EvalTargetTypeLoopPrompt { logs.CtxWarn(ctx, "Illegal evaltarget type %d for expt %d", param.EvalTargetType, exptID) } From 1be6566eabc6d92dd2c3ec387d3b4e95f82cd09a Mon Sep 17 00:00:00 2001 From: xueyizheng Date: Tue, 2 Dec 2025 15:39:04 +0800 Subject: [PATCH 18/21] fix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fix 增加Evaluator 改动targetVersionID来源 改动targetID来源 --- .../api/handler/coze/loop/apis/wire_gen.go | 1 - .../evaluation/application/wire_gen.go | 4 +- .../domain/component/rpc/trace_agent.go | 4 +- .../domain/service/insight_analysis_impl.go | 40 +++++++++++++++---- .../service/insight_analysis_impl_test.go | 1 + 5 files changed, 38 insertions(+), 12 deletions(-) diff --git a/backend/api/handler/coze/loop/apis/wire_gen.go b/backend/api/handler/coze/loop/apis/wire_gen.go index ab2d3667c..e76d1bcbf 100644 --- a/backend/api/handler/coze/loop/apis/wire_gen.go +++ b/backend/api/handler/coze/loop/apis/wire_gen.go @@ -8,7 +8,6 @@ package apis import ( "context" - "github.com/cloudwego/kitex/pkg/endpoint" "github.com/coze-dev/coze-loop/backend/infra/ck" "github.com/coze-dev/coze-loop/backend/infra/db" diff --git a/backend/modules/evaluation/application/wire_gen.go b/backend/modules/evaluation/application/wire_gen.go index 4237c878a..5180d1364 100644 --- a/backend/modules/evaluation/application/wire_gen.go +++ b/backend/modules/evaluation/application/wire_gen.go @@ -162,7 +162,7 @@ func InitExperimentApplication(ctx context.Context, idgen2 idgen.IIDGenerator, d iExptInsightAnalysisRecordRepo := experiment.NewExptInsightAnalysisRecordRepo(iExptInsightAnalysisRecordDAO, iExptInsightAnalysisFeedbackCommentDAO, iExptInsightAnalysisFeedbackVoteDAO, idgen2, iLatestWriteTracker) iAgentAdapter := agent.NewAgentAdapter() iNotifyRPCAdapter := notify.NewNotifyRPCAdapter() - iExptInsightAnalysisService := service.NewInsightAnalysisService(iExptInsightAnalysisRecordRepo, exptEventPublisher, objectStorage, iAgentAdapter, iExptResultExportService, iNotifyRPCAdapter, iUserProvider, iExperimentRepo) + iExptInsightAnalysisService := service.NewInsightAnalysisService(iExptInsightAnalysisRecordRepo, exptEventPublisher, objectStorage, iAgentAdapter, iExptResultExportService, iNotifyRPCAdapter, iUserProvider, iExperimentRepo, iEvalTargetRepo) iExperimentApplication := NewExperimentApplication(exptAggrResultService, exptResultService, iExptManager, exptSchedulerEvent, exptItemEvalEvent, idgen2, componentIConfiger, iAuthProvider, userInfoService, iEvalTargetService, evaluationSetItemService, iExptAnnotateService, iTagRPCAdapter, iExptResultExportService, iExptInsightAnalysisService, serviceEvaluatorService) return iExperimentApplication, nil } @@ -340,7 +340,7 @@ func InitEvalOpenAPIApplication(ctx context.Context, configFactory conf.IConfigL iExptInsightAnalysisRecordRepo := experiment.NewExptInsightAnalysisRecordRepo(iExptInsightAnalysisRecordDAO, iExptInsightAnalysisFeedbackCommentDAO, iExptInsightAnalysisFeedbackVoteDAO, idgen2, iLatestWriteTracker) iAgentAdapter := agent.NewAgentAdapter() iNotifyRPCAdapter := notify.NewNotifyRPCAdapter() - iExptInsightAnalysisService := service.NewInsightAnalysisService(iExptInsightAnalysisRecordRepo, exptEventPublisher, objectStorage, iAgentAdapter, iExptResultExportService, iNotifyRPCAdapter, iUserProvider, iExperimentRepo) + iExptInsightAnalysisService := service.NewInsightAnalysisService(iExptInsightAnalysisRecordRepo, exptEventPublisher, objectStorage, iAgentAdapter, iExptResultExportService, iNotifyRPCAdapter, iUserProvider, iExperimentRepo, iEvalTargetRepo) iExperimentApplication := NewExperimentApplication(exptAggrResultService, exptResultService, iExptManager, exptSchedulerEvent, exptItemEvalEvent, idgen2, componentIConfiger, iAuthProvider, userInfoService, iEvalTargetService, evaluationSetItemService, iExptAnnotateService, iTagRPCAdapter, iExptResultExportService, iExptInsightAnalysisService, evaluatorService) evalOpenAPIService := NewEvalOpenAPIApplication(iEvalAsyncRepo, exptEventPublisher, iEvalTargetService, iAuthProvider, iEvaluationSetService, evaluationSetVersionService, evaluationSetItemService, evaluationSetSchemaService, openAPIEvaluationMetrics, userInfoService, iExperimentApplication, iExptManager, exptResultService, exptAggrResultService, evaluatorService) return evalOpenAPIService, nil diff --git a/backend/modules/evaluation/domain/component/rpc/trace_agent.go b/backend/modules/evaluation/domain/component/rpc/trace_agent.go index 66651fef9..a309f9c5c 100644 --- a/backend/modules/evaluation/domain/component/rpc/trace_agent.go +++ b/backend/modules/evaluation/domain/component/rpc/trace_agent.go @@ -25,5 +25,7 @@ type CallTraceAgentParam struct { EvalTargetType entity.EvalTargetType // now support prompt only EvalTargetID int64 - EvalTargetVersionID int64 + EvalTargetVersionID string + + Evaluators []*entity.ExptEvaluatorRef } diff --git a/backend/modules/evaluation/domain/service/insight_analysis_impl.go b/backend/modules/evaluation/domain/service/insight_analysis_impl.go index c10dec8ec..4b3f0edac 100644 --- a/backend/modules/evaluation/domain/service/insight_analysis_impl.go +++ b/backend/modules/evaluation/domain/service/insight_analysis_impl.go @@ -32,6 +32,7 @@ type ExptInsightAnalysisServiceImpl struct { notifyRPCAdapter rpc.INotifyRPCAdapter userProvider rpc.IUserProvider exptRepo repo.IExperimentRepo + targetRepo repo.IEvalTargetRepo } func NewInsightAnalysisService(repo repo.IExptInsightAnalysisRecordRepo, @@ -42,6 +43,7 @@ func NewInsightAnalysisService(repo repo.IExptInsightAnalysisRecordRepo, notifyRPCAdapter rpc.INotifyRPCAdapter, userProvider rpc.IUserProvider, exptRepo repo.IExperimentRepo, + targetRepo repo.IEvalTargetRepo, ) IExptInsightAnalysisService { return &ExptInsightAnalysisServiceImpl{ repo: repo, @@ -52,6 +54,7 @@ func NewInsightAnalysisService(repo repo.IExptInsightAnalysisRecordRepo, notifyRPCAdapter: notifyRPCAdapter, userProvider: userProvider, exptRepo: exptRepo, + targetRepo: targetRepo, } } @@ -134,16 +137,37 @@ func (e ExptInsightAnalysisServiceImpl) GenAnalysisReport(ctx context.Context, s } param := &rpc.CallTraceAgentParam{ - SpaceID: spaceID, - ExptID: exptID, - Url: url, - StartTime: expt.StartAt.UnixMilli(), - EndTime: expt.EndAt.UnixMilli(), - EvalTargetType: expt.TargetType, - EvalTargetID: expt.TargetID, - EvalTargetVersionID: expt.TargetVersionID, + SpaceID: spaceID, + ExptID: exptID, + Url: url, + StartTime: expt.StartAt.UnixMilli(), + EndTime: expt.EndAt.UnixMilli(), + EvalTargetType: expt.TargetType, } + target, err := e.targetRepo.GetEvalTargetVersion(ctx, spaceID, expt.TargetVersionID) + if err != nil { + return err + } + if target == nil || target.SourceTargetID == "" { + logs.CtxWarn(ctx, "Experiment %d has no source target %d", exptID, expt.TargetID) + return errorx.NewByCode(errno.CommonInternalErrorCode, errorx.WithExtraMsg(fmt.Sprintf("Experiment %d has no source target %d", exptID, expt.TargetID))) + } + param.EvalTargetID, err = strconv.ParseInt(target.SourceTargetID, 10, 64) + if err != nil { + return err + } + param.EvalTargetVersionID = target.EvalTargetVersion.SourceTargetVersion + if err != nil { + return err + } + + evaluators, err := e.exptRepo.GetEvaluatorRefByExptIDs(ctx, []int64{exptID}, spaceID) + if err != nil { + return err + } + param.Evaluators = evaluators + // only allow prompt eval target, but not return error here. The task will fail in the CallTraceAgent. if param.EvalTargetType != entity.EvalTargetTypeLoopPrompt { logs.CtxWarn(ctx, "Illegal evaltarget type %d for expt %d", param.EvalTargetType, exptID) diff --git a/backend/modules/evaluation/domain/service/insight_analysis_impl_test.go b/backend/modules/evaluation/domain/service/insight_analysis_impl_test.go index 1f8d3dee1..a2eba41fa 100644 --- a/backend/modules/evaluation/domain/service/insight_analysis_impl_test.go +++ b/backend/modules/evaluation/domain/service/insight_analysis_impl_test.go @@ -930,6 +930,7 @@ func TestNewInsightAnalysisService(t *testing.T) { mockNotifyRPCAdapter, mockUserProvider, mockExptRepo, + repoMocks.NewMockIEvalTargetRepo(ctrl), ) assert.NotNil(t, service) From 89bf45a632c315103da0074a29960c5860dfa082 Mon Sep 17 00:00:00 2001 From: xueyizheng Date: Tue, 2 Dec 2025 16:56:51 +0800 Subject: [PATCH 19/21] fix --- .../evaluation/domain/service/insight_analysis_impl.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/backend/modules/evaluation/domain/service/insight_analysis_impl.go b/backend/modules/evaluation/domain/service/insight_analysis_impl.go index 4b3f0edac..44bd1ca8b 100644 --- a/backend/modules/evaluation/domain/service/insight_analysis_impl.go +++ b/backend/modules/evaluation/domain/service/insight_analysis_impl.go @@ -157,6 +157,10 @@ func (e ExptInsightAnalysisServiceImpl) GenAnalysisReport(ctx context.Context, s if err != nil { return err } + if target.EvalTargetVersion == nil || target.EvalTargetVersion.SourceTargetVersion == "" { + logs.CtxWarn(ctx, "Experiment %d has no source target version %s", exptID, expt.TargetVersionID) + return errorx.NewByCode(errno.CommonInternalErrorCode, errorx.WithExtraMsg(fmt.Sprintf("Experiment %d has no source target version %s", exptID, expt.TargetVersionID))) + } param.EvalTargetVersionID = target.EvalTargetVersion.SourceTargetVersion if err != nil { return err From b6f3f4206484059e795ea99428c6340d89f0baae Mon Sep 17 00:00:00 2001 From: xueyizheng Date: Wed, 3 Dec 2025 11:31:30 +0800 Subject: [PATCH 20/21] fix --- .../expt_insight_analysis_feedback_comment.go | 80 ++++++++++--------- 1 file changed, 43 insertions(+), 37 deletions(-) diff --git a/backend/modules/evaluation/infra/repo/experiment/mysql/mocks/expt_insight_analysis_feedback_comment.go b/backend/modules/evaluation/infra/repo/experiment/mysql/mocks/expt_insight_analysis_feedback_comment.go index 187b29441..6e52e80c5 100644 --- a/backend/modules/evaluation/infra/repo/experiment/mysql/mocks/expt_insight_analysis_feedback_comment.go +++ b/backend/modules/evaluation/infra/repo/experiment/mysql/mocks/expt_insight_analysis_feedback_comment.go @@ -1,5 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/coze-dev/coze-loop/backend/modules/evaluation/infra/repo/experiment/mysql (interfaces: IExptInsightAnalysisFeedbackCommentDAO) +// +// Generated by this command: +// +// mockgen -destination=mocks/expt_insight_analysis_feedback_comment.go -package mocks . IExptInsightAnalysisFeedbackCommentDAO +// // Package mocks is a generated GoMock package. package mocks @@ -18,6 +23,7 @@ import ( type MockIExptInsightAnalysisFeedbackCommentDAO struct { ctrl *gomock.Controller recorder *MockIExptInsightAnalysisFeedbackCommentDAOMockRecorder + isgomock struct{} } // MockIExptInsightAnalysisFeedbackCommentDAOMockRecorder is the mock recorder for MockIExptInsightAnalysisFeedbackCommentDAO. @@ -38,10 +44,10 @@ func (m *MockIExptInsightAnalysisFeedbackCommentDAO) EXPECT() *MockIExptInsightA } // Create mocks base method. -func (m *MockIExptInsightAnalysisFeedbackCommentDAO) Create(arg0 context.Context, arg1 *model.ExptInsightAnalysisFeedbackComment, arg2 ...db.Option) error { +func (m *MockIExptInsightAnalysisFeedbackCommentDAO) Create(ctx context.Context, feedbackComment *model.ExptInsightAnalysisFeedbackComment, opts ...db.Option) error { m.ctrl.T.Helper() - varargs := []interface{}{arg0, arg1} - for _, a := range arg2 { + varargs := []any{ctx, feedbackComment} + for _, a := range opts { varargs = append(varargs, a) } ret := m.ctrl.Call(m, "Create", varargs...) @@ -50,71 +56,71 @@ func (m *MockIExptInsightAnalysisFeedbackCommentDAO) Create(arg0 context.Context } // Create indicates an expected call of Create. -func (mr *MockIExptInsightAnalysisFeedbackCommentDAOMockRecorder) Create(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { +func (mr *MockIExptInsightAnalysisFeedbackCommentDAOMockRecorder) Create(ctx, feedbackComment any, opts ...any) *gomock.Call { mr.mock.ctrl.T.Helper() - varargs := append([]interface{}{arg0, arg1}, arg2...) + varargs := append([]any{ctx, feedbackComment}, opts...) return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Create", reflect.TypeOf((*MockIExptInsightAnalysisFeedbackCommentDAO)(nil).Create), varargs...) } // Delete mocks base method. -func (m *MockIExptInsightAnalysisFeedbackCommentDAO) Delete(arg0 context.Context, arg1, arg2, arg3 int64) error { +func (m *MockIExptInsightAnalysisFeedbackCommentDAO) Delete(ctx context.Context, spaceID, exptID, commentID int64) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Delete", arg0, arg1, arg2, arg3) + ret := m.ctrl.Call(m, "Delete", ctx, spaceID, exptID, commentID) ret0, _ := ret[0].(error) return ret0 } // Delete indicates an expected call of Delete. -func (mr *MockIExptInsightAnalysisFeedbackCommentDAOMockRecorder) Delete(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { +func (mr *MockIExptInsightAnalysisFeedbackCommentDAOMockRecorder) Delete(ctx, spaceID, exptID, commentID any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Delete", reflect.TypeOf((*MockIExptInsightAnalysisFeedbackCommentDAO)(nil).Delete), arg0, arg1, arg2, arg3) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Delete", reflect.TypeOf((*MockIExptInsightAnalysisFeedbackCommentDAO)(nil).Delete), ctx, spaceID, exptID, commentID) } -// GetByRecordID mocks base method. -func (m *MockIExptInsightAnalysisFeedbackCommentDAO) GetByRecordID(arg0 context.Context, arg1, arg2, arg3 int64, arg4 ...db.Option) (*model.ExptInsightAnalysisFeedbackComment, error) { +// GetByID mocks base method. +func (m *MockIExptInsightAnalysisFeedbackCommentDAO) GetByID(ctx context.Context, spaceID, exptID, commentID int64, opts ...db.Option) (*model.ExptInsightAnalysisFeedbackComment, error) { m.ctrl.T.Helper() - varargs := []interface{}{arg0, arg1, arg2, arg3} - for _, a := range arg4 { + varargs := []any{ctx, spaceID, exptID, commentID} + for _, a := range opts { varargs = append(varargs, a) } - ret := m.ctrl.Call(m, "GetByRecordID", varargs...) + ret := m.ctrl.Call(m, "GetByID", varargs...) ret0, _ := ret[0].(*model.ExptInsightAnalysisFeedbackComment) ret1, _ := ret[1].(error) return ret0, ret1 } -// GetByRecordID indicates an expected call of GetByRecordID. -func (mr *MockIExptInsightAnalysisFeedbackCommentDAOMockRecorder) GetByRecordID(arg0, arg1, arg2, arg3 interface{}, arg4 ...interface{}) *gomock.Call { +// GetByID indicates an expected call of GetByID. +func (mr *MockIExptInsightAnalysisFeedbackCommentDAOMockRecorder) GetByID(ctx, spaceID, exptID, commentID any, opts ...any) *gomock.Call { mr.mock.ctrl.T.Helper() - varargs := append([]interface{}{arg0, arg1, arg2, arg3}, arg4...) - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetByRecordID", reflect.TypeOf((*MockIExptInsightAnalysisFeedbackCommentDAO)(nil).GetByRecordID), varargs...) + varargs := append([]any{ctx, spaceID, exptID, commentID}, opts...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetByID", reflect.TypeOf((*MockIExptInsightAnalysisFeedbackCommentDAO)(nil).GetByID), varargs...) } -// GetByID mocks base method. -func (m *MockIExptInsightAnalysisFeedbackCommentDAO) GetByID(arg0 context.Context, arg1, arg2, arg3 int64, arg4 ...db.Option) (*model.ExptInsightAnalysisFeedbackComment, error) { +// GetByRecordID mocks base method. +func (m *MockIExptInsightAnalysisFeedbackCommentDAO) GetByRecordID(ctx context.Context, spaceID, exptID, recordID int64, opts ...db.Option) (*model.ExptInsightAnalysisFeedbackComment, error) { m.ctrl.T.Helper() - varargs := []interface{}{arg0, arg1, arg2, arg3} - for _, a := range arg4 { + varargs := []any{ctx, spaceID, exptID, recordID} + for _, a := range opts { varargs = append(varargs, a) } - ret := m.ctrl.Call(m, "GetByID", varargs...) + ret := m.ctrl.Call(m, "GetByRecordID", varargs...) ret0, _ := ret[0].(*model.ExptInsightAnalysisFeedbackComment) ret1, _ := ret[1].(error) return ret0, ret1 } -// GetByID indicates an expected call of GetByID. -func (mr *MockIExptInsightAnalysisFeedbackCommentDAOMockRecorder) GetByID(arg0, arg1, arg2, arg3 interface{}, arg4 ...interface{}) *gomock.Call { +// GetByRecordID indicates an expected call of GetByRecordID. +func (mr *MockIExptInsightAnalysisFeedbackCommentDAOMockRecorder) GetByRecordID(ctx, spaceID, exptID, recordID any, opts ...any) *gomock.Call { mr.mock.ctrl.T.Helper() - varargs := append([]interface{}{arg0, arg1, arg2, arg3}, arg4...) - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetByID", reflect.TypeOf((*MockIExptInsightAnalysisFeedbackCommentDAO)(nil).GetByID), varargs...) + varargs := append([]any{ctx, spaceID, exptID, recordID}, opts...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetByRecordID", reflect.TypeOf((*MockIExptInsightAnalysisFeedbackCommentDAO)(nil).GetByRecordID), varargs...) } // List mocks base method. -func (m *MockIExptInsightAnalysisFeedbackCommentDAO) List(arg0 context.Context, arg1, arg2, arg3 int64, arg4 entity.Page, arg5 ...db.Option) ([]*model.ExptInsightAnalysisFeedbackComment, int64, error) { +func (m *MockIExptInsightAnalysisFeedbackCommentDAO) List(ctx context.Context, spaceID, exptID, recordID int64, page entity.Page, opts ...db.Option) ([]*model.ExptInsightAnalysisFeedbackComment, int64, error) { m.ctrl.T.Helper() - varargs := []interface{}{arg0, arg1, arg2, arg3, arg4} - for _, a := range arg5 { + varargs := []any{ctx, spaceID, exptID, recordID, page} + for _, a := range opts { varargs = append(varargs, a) } ret := m.ctrl.Call(m, "List", varargs...) @@ -125,17 +131,17 @@ func (m *MockIExptInsightAnalysisFeedbackCommentDAO) List(arg0 context.Context, } // List indicates an expected call of List. -func (mr *MockIExptInsightAnalysisFeedbackCommentDAOMockRecorder) List(arg0, arg1, arg2, arg3, arg4 interface{}, arg5 ...interface{}) *gomock.Call { +func (mr *MockIExptInsightAnalysisFeedbackCommentDAOMockRecorder) List(ctx, spaceID, exptID, recordID, page any, opts ...any) *gomock.Call { mr.mock.ctrl.T.Helper() - varargs := append([]interface{}{arg0, arg1, arg2, arg3, arg4}, arg5...) + varargs := append([]any{ctx, spaceID, exptID, recordID, page}, opts...) return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "List", reflect.TypeOf((*MockIExptInsightAnalysisFeedbackCommentDAO)(nil).List), varargs...) } // Update mocks base method. -func (m *MockIExptInsightAnalysisFeedbackCommentDAO) Update(arg0 context.Context, arg1 *model.ExptInsightAnalysisFeedbackComment, arg2 ...db.Option) error { +func (m *MockIExptInsightAnalysisFeedbackCommentDAO) Update(ctx context.Context, feedbackComment *model.ExptInsightAnalysisFeedbackComment, opts ...db.Option) error { m.ctrl.T.Helper() - varargs := []interface{}{arg0, arg1} - for _, a := range arg2 { + varargs := []any{ctx, feedbackComment} + for _, a := range opts { varargs = append(varargs, a) } ret := m.ctrl.Call(m, "Update", varargs...) @@ -144,8 +150,8 @@ func (m *MockIExptInsightAnalysisFeedbackCommentDAO) Update(arg0 context.Context } // Update indicates an expected call of Update. -func (mr *MockIExptInsightAnalysisFeedbackCommentDAOMockRecorder) Update(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { +func (mr *MockIExptInsightAnalysisFeedbackCommentDAOMockRecorder) Update(ctx, feedbackComment any, opts ...any) *gomock.Call { mr.mock.ctrl.T.Helper() - varargs := append([]interface{}{arg0, arg1}, arg2...) + varargs := append([]any{ctx, feedbackComment}, opts...) return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Update", reflect.TypeOf((*MockIExptInsightAnalysisFeedbackCommentDAO)(nil).Update), varargs...) } From 008c2a641396d7cf66259c4db6cecdcd88fa10b7 Mon Sep 17 00:00:00 2001 From: xueyizheng Date: Wed, 3 Dec 2025 15:28:05 +0800 Subject: [PATCH 21/21] fix version --- .../modules/evaluation/domain/component/rpc/trace_agent.go | 6 +++--- .../evaluation/domain/service/insight_analysis_impl.go | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/backend/modules/evaluation/domain/component/rpc/trace_agent.go b/backend/modules/evaluation/domain/component/rpc/trace_agent.go index a309f9c5c..a0b1b0443 100644 --- a/backend/modules/evaluation/domain/component/rpc/trace_agent.go +++ b/backend/modules/evaluation/domain/component/rpc/trace_agent.go @@ -23,9 +23,9 @@ type CallTraceAgentParam struct { StartTime int64 // in ms EndTime int64 // in ms - EvalTargetType entity.EvalTargetType // now support prompt only - EvalTargetID int64 - EvalTargetVersionID string + EvalTargetType entity.EvalTargetType // now support prompt only + EvalTargetID int64 + EvalTargetVersion string // like 1.2.3 Evaluators []*entity.ExptEvaluatorRef } diff --git a/backend/modules/evaluation/domain/service/insight_analysis_impl.go b/backend/modules/evaluation/domain/service/insight_analysis_impl.go index 44bd1ca8b..575154952 100644 --- a/backend/modules/evaluation/domain/service/insight_analysis_impl.go +++ b/backend/modules/evaluation/domain/service/insight_analysis_impl.go @@ -161,7 +161,7 @@ func (e ExptInsightAnalysisServiceImpl) GenAnalysisReport(ctx context.Context, s logs.CtxWarn(ctx, "Experiment %d has no source target version %s", exptID, expt.TargetVersionID) return errorx.NewByCode(errno.CommonInternalErrorCode, errorx.WithExtraMsg(fmt.Sprintf("Experiment %d has no source target version %s", exptID, expt.TargetVersionID))) } - param.EvalTargetVersionID = target.EvalTargetVersion.SourceTargetVersion + param.EvalTargetVersion = target.EvalTargetVersion.SourceTargetVersion if err != nil { return err }