Files
Agent-System/internal/coordinator/engine_docgov_comments.go
T
weichen b5a782bb38 feat(chat): dialogue triggers for comments/reopen/pending-supplements with mistouch guards
Wire intent→coordinator DocResolver confirm cards→action_executor kinds for comment, reopen, pending-supplements query, and real submit-review execution.
2026-09-25 20:14:10 +00:00

108 lines
4.0 KiB
Go

package coordinator
import (
"context"
"fmt"
"strings"
"chat-agent-system/internal/contracts/vocabulary"
"chat-agent-system/internal/intent"
)
// handleDocGovCommentAdd 解析门 → 批注矩阵剪枝 → CONFIRMATION 卡(含内容预览)
func (e *CoordinatorEngine) handleDocGovCommentAdd(ctx context.Context, cand *intent.CandidateIntent, userCtx *UserProjectContext) (*CoordinationResult, error) {
doc, gate := e.resolveTargetDocGate(ctx, cand, userCtx)
if gate != nil {
return gate, nil
}
content := strings.TrimSpace(cand.FilledSlots[intent.SlotCommentContent])
section := strings.TrimSpace(cand.FilledSlots[intent.SlotTargetSection])
cType := strings.TrimSpace(cand.FilledSlots[intent.SlotCommentType])
if cType == "" {
cType = "suggestion"
}
if content == "" {
return &CoordinationResult{
Status: StatusClarificationRequired,
Intent: cand.Intent,
Branch: cand.Branch,
ClarificationPrompt: "请补充批注内容后再确认添加。",
NaturalReply: "已定位文档,但缺少批注正文。请说明要添加的意见内容。",
UpdatedContext: userCtx,
}, nil
}
role := effectiveDocRole(userCtx)
if userCtx != nil && userCtx.ToSnapshot() != nil && userCtx.ToSnapshot().UserDocRole != "" {
role = userCtx.ToSnapshot().UserDocRole
}
state := doc.State
if state == "" && userCtx != nil && userCtx.ToSnapshot() != nil {
state = vocabulary.DocumentState(userCtx.ToSnapshot().DocLifecycleState)
}
if state != "" && role != "" && !commentRoleAllowed(role, state) {
return &CoordinationResult{
Status: StatusRejected,
Intent: cand.Intent,
Branch: cand.Branch,
RejectReason: "COMMENT_MATRIX_DENIED",
NaturalReply: fmt.Sprintf("按批注矩阵,角色「%s」在「%s」阶段不可添加批注。", role, state),
UpdatedContext: userCtx,
}, nil
}
title := displayDocTitle(doc)
preview := content
if section != "" {
preview = fmt.Sprintf("[%s] %s", section, content)
}
card, exp := buildConfirmCard(
"添加受控文档批注确认",
doc.DocID, title, section, preview,
"确认后将写入文档批注;服务端会按角色×阶段矩阵二次校验。",
"confirm_comment_add", "确认添加批注",
map[string]string{
"role": role,
"comment_content": content,
"comment_type": cType,
"target_section": section,
},
)
userCtx.applyCard(card)
userCtx.applyPending(exp)
reply := fmt.Sprintf("已为《%s》起草批注确认单。预览:%s。请确认或回复「确认」。", title, preview)
return &CoordinationResult{
Status: StatusAccepted, Intent: cand.Intent, Branch: cand.Branch,
NaturalReply: reply, InteractiveCard: card, NextExpectation: exp, UpdatedContext: userCtx,
}, nil
}
// handleDocGovCommentResolve 解析门 → CONFIRMATION 卡 → PendingAction
func (e *CoordinatorEngine) handleDocGovCommentResolve(ctx context.Context, cand *intent.CandidateIntent, userCtx *UserProjectContext) (*CoordinationResult, error) {
doc, gate := e.resolveTargetDocGate(ctx, cand, userCtx)
if gate != nil {
return gate, nil
}
section := strings.TrimSpace(cand.FilledSlots[intent.SlotTargetSection])
role := effectiveDocRole(userCtx)
title := displayDocTitle(doc)
proposed := "将匹配的未解决批注标记为已处理"
if section != "" {
proposed = fmt.Sprintf("将章节「%s」下未解决批注标记为已处理", section)
}
card, exp := buildConfirmCard(
"解决受控文档批注确认",
doc.DocID, title, section, proposed,
"确认后由服务端按角色权限二次校验并更新批注状态。",
"confirm_comment_resolve", "确认解决批注",
map[string]string{"role": role, "target_section": section},
)
userCtx.applyCard(card)
userCtx.applyPending(exp)
return &CoordinationResult{
Status: StatusAccepted, Intent: cand.Intent, Branch: cand.Branch,
NaturalReply: fmt.Sprintf("已为《%s》起草解决批注确认单。请确认后执行。", title),
InteractiveCard: card, NextExpectation: exp, UpdatedContext: userCtx,
}, nil
}