test(bizdev): drain pending confirmations in full-link stage E2E

Stage chain now stops on high-risk candidates; full-link mirrors the
product path of confirm + re-run until success or DocGov proposal intercept.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
weichen
2026-09-13 10:00:45 +00:00
co-authored by Cursor
parent b5a3b72756
commit 9ed5987104
+70 -13
View File
@@ -9,9 +9,75 @@ import (
"chat-agent-system/internal/bizdev"
"chat-agent-system/internal/config"
"chat-agent-system/internal/docgov"
"chat-agent-system/internal/docrevision"
"chat-agent-system/internal/stream"
)
// executeStageDrainingPending runs ExecuteStage, confirming high-risk agent candidates
// (and projecting fact source) until the stage succeeds or stops on a DocGov proposal intercept.
// This mirrors the product path: confirm on the page, then re-run the stage.
func executeStageDrainingPending(
t *testing.T,
ctx context.Context,
svc *bizdev.Service,
req bizdev.StageRunRequest,
authorID int64,
dataRoot string,
) *bizdev.StageRunResult {
t.Helper()
for attempt := 0; attempt < 16; attempt++ {
res, err := svc.ExecuteStage(ctx, req)
if err != nil {
t.Fatalf("ExecuteStage attempt %d: %v", attempt, err)
}
if res.Success {
return res
}
for _, sub := range res.SubArtifacts {
if sub != nil && sub.IsProposalIntercept() {
return res
}
}
if res.PendingAgentCandidateID <= 0 {
t.Fatalf("stage failed without pending/proposal: %s", res.ErrorReason)
}
var pending *bizdev.TaskRunResult
for _, sub := range res.SubArtifacts {
if sub != nil && sub.AwaitsAgentConfirmation() {
pending = sub
break
}
}
if pending == nil || pending.DocRecord == nil || pending.DocRecord.DocID == "" {
t.Fatalf("pending stage missing DocRecord: %+v", res)
}
docID := pending.DocRecord.DocID
st, err := svc.DocRevision().GetRevisionState(ctx, docID)
if err != nil {
t.Fatalf("GetRevisionState(%s): %v", docID, err)
}
st2, err := svc.DocRevision().CommitAgentVersion(ctx, docID, pending.PendingAgentCandidateID, docrevision.CommitAgentDecision{
Decision: "commit", Confirmed: true, ActorUserID: authorID,
ExpectedInputSHA: st.HeadSHA256,
})
if err != nil {
t.Fatalf("CommitAgentVersion(%s,#%d): %v", docID, pending.PendingAgentCandidateID, err)
}
if err := svc.DocRevision().ProjectOutputMarkdown(docID, dataRoot); err != nil {
t.Fatalf("ProjectOutputMarkdown(%s): %v", docID, err)
}
if st2 != nil && st2.HeadSHA256 != "" {
if err := svc.DocGov().MarkDocumentContentUpdated(ctx, docID, st2.HeadSHA256, false); err != nil {
t.Fatalf("MarkDocumentContentUpdated: %v", err)
}
}
t.Logf("confirmed pending candidate #%d on %s; re-running stage (attempt %d)",
pending.PendingAgentCandidateID, docID, attempt+1)
}
t.Fatal("stage still unresolved after max pending confirm/retry loops")
return nil
}
func TestBizDev_FullLink_V01_V05_V10_E2E(t *testing.T) {
cfg := &config.Config{
DataDir: t.TempDir(),
@@ -114,12 +180,9 @@ func TestBizDev_FullLink_V01_V05_V10_E2E(t *testing.T) {
ApproverName: approverName,
}
resV05, err := svc.ExecuteStage(ctx, stageReqV05)
if err != nil {
t.Fatalf("Stage V0.5 execution failed: %v", err)
}
resV05 := executeStageDrainingPending(t, ctx, svc, stageReqV05, authorID, cfg.DataDir)
if !resV05.Success {
t.Fatalf("Stage V0.5 should succeed, got error: %s", resV05.ErrorReason)
t.Fatalf("Stage V0.5 should succeed after confirming pendings, got error: %s", resV05.ErrorReason)
}
if len(resV05.SubArtifacts) != 5 {
t.Fatalf("Stage V0.5 should produce 5 sub-artifacts, got %d", len(resV05.SubArtifacts))
@@ -167,10 +230,7 @@ func TestBizDev_FullLink_V01_V05_V10_E2E(t *testing.T) {
stageReqV05Modified := stageReqV05
stageReqV05Modified.TargetMarket = "中国NMPA二类 + 欧盟CE MDR"
resV05Intercepted, err := svc.ExecuteStage(ctx, stageReqV05Modified)
if err != nil {
t.Fatalf("ExecuteStage returned unexpected runtime error: %v", err)
}
resV05Intercepted := executeStageDrainingPending(t, ctx, svc, stageReqV05Modified, authorID, cfg.DataDir)
if resV05Intercepted.Success {
t.Fatalf("Stage V0.5 re-run on claimed document should be intercepted (Success=false)")
}
@@ -217,10 +277,7 @@ func TestBizDev_FullLink_V01_V05_V10_E2E(t *testing.T) {
stageReqV05Force := stageReqV05Modified
stageReqV05Force.ForceDirectEdit = true
resV05Updated, err := svc.ExecuteStage(ctx, stageReqV05Force)
if err != nil {
t.Fatalf("Stage V0.5 force re-run failed: %v", err)
}
resV05Updated := executeStageDrainingPending(t, ctx, svc, stageReqV05Force, authorID, cfg.DataDir)
if !resV05Updated.Success {
t.Fatalf("Stage V0.5 force re-run should succeed, error: %s", resV05Updated.ErrorReason)
}