Files
Agent-System/internal/coordinator/upload_followup_test.go
T
weichen 457e870330 fix(chat): 只上传文档时给出梳理或追问,不再裸报 HTTP 400
空消息加附件可以进入回合。无文字时按解析状态引导或回退审阅,有文字但未处理文档时先回答再追问。4xx 信封不再被前端丢弃。
2026-09-28 02:00:24 +00:00

111 lines
3.6 KiB
Go

package coordinator
import (
"context"
"strings"
"testing"
"chat-agent-system/internal/intent"
)
func TestHandleUploadIntake_PendingDoesNotError(t *testing.T) {
engine := NewCoordinatorEngine(nil)
userCtx := &UserProjectContext{
AttachmentOnlyTurn: true,
PendingTurnAttachments: []TurnAttachmentRef{{
Filename: "F-030-PIR.pdf",
ParseState: "pending",
}},
BlackboardFacts: map[string]string{},
Project: ProjectInfo{Name: "内廷元"},
}
rec := &intent.IntentRecognitionResult{
RawInput: "已上传文档:《F-030-PIR.pdf》",
TopIntent: &intent.CandidateIntent{
Intent: intent.IntentCasualChat,
},
}
res, err := engine.ProcessIntent(context.Background(), rec, userCtx)
if err != nil {
t.Fatal(err)
}
if !strings.Contains(res.NaturalReply, "解析") {
t.Fatalf("reply=%s", res.NaturalReply)
}
if res.NextExpectation == nil || len(res.NextExpectation.Options) != 3 {
t.Fatalf("expectation=%+v", res.NextExpectation)
}
if userCtx.AttachmentOnlyTurn || len(userCtx.PendingTurnAttachments) != 0 {
t.Fatal("upload flags must be cleared after intake")
}
}
func TestHandleUploadIntake_ReadableFallbackReview(t *testing.T) {
engine := NewCoordinatorEngine(nil)
userCtx := &UserProjectContext{
AttachmentOnlyTurn: true,
PendingTurnAttachments: []TurnAttachmentRef{{
Filename: "F-030-PIR.pdf",
AssetID: 4,
ParseState: "done",
}},
DocumentSummaryReader: func(_ context.Context, target string) (*ReadableDocument, error) {
if target != intent.TargetDocLatestUpload {
t.Fatalf("target=%s", target)
}
return &ReadableDocument{
Title: "F-030-PIR 项目初始要求申请表",
Markdown: "预期用途:白天 TEAS 改善打鼾。适应症:轻度 OSAHS。",
}, nil
},
BlackboardFacts: map[string]string{},
Project: ProjectInfo{Name: "内廷元"},
}
rec := &intent.IntentRecognitionResult{
RawInput: "已上传文档:《F-030-PIR.pdf》",
TopIntent: &intent.CandidateIntent{Intent: intent.IntentCasualChat},
}
res, err := engine.ProcessIntent(context.Background(), rec, userCtx)
if err != nil {
t.Fatal(err)
}
if !strings.Contains(res.NaturalReply, "OSAHS") || !strings.Contains(res.NaturalReply, "1.") {
t.Fatalf("reply=%s", res.NaturalReply)
}
}
func TestAnnotateUnrelatedUploads_AppendsAsk(t *testing.T) {
engine := NewCoordinatorEngine(nil)
userCtx := &UserProjectContext{
PendingTurnAttachments: []TurnAttachmentRef{{Filename: "说明书.pdf", ParseState: "done"}},
BlackboardFacts: map[string]string{},
Project: ProjectInfo{Name: "项目", CurrentStage: ""},
}
rec := &intent.IntentRecognitionResult{
RawInput: "今天会议改到三点",
TopIntent: &intent.CandidateIntent{Intent: intent.IntentCasualChat, Confidence: 0.9},
}
res, err := engine.ProcessIntent(context.Background(), rec, userCtx)
if err != nil {
t.Fatal(err)
}
res = AnnotateUnrelatedUploads(userCtx, rec.RawInput, rec, res)
if !strings.Contains(res.NaturalReply, "另外已收到") || !strings.Contains(res.NaturalReply, "说明书.pdf") {
t.Fatalf("reply=%s", res.NaturalReply)
}
}
func TestAnnotateUnrelatedUploads_SkipsSummaryIntent(t *testing.T) {
userCtx := &UserProjectContext{
PendingTurnAttachments: []TurnAttachmentRef{{Filename: "说明书.pdf"}},
}
rec := &intent.IntentRecognitionResult{
RawInput: "总结刚上传的说明书",
TopIntent: &intent.CandidateIntent{Intent: intent.IntentQueryDocStatus},
}
res := AnnotateUnrelatedUploads(userCtx, rec.RawInput, rec, &CoordinationResult{NaturalReply: "摘要"})
if strings.Contains(res.NaturalReply, "另外已收到") {
t.Fatalf("should not ask again: %s", res.NaturalReply)
}
}