diff --git a/cmd/enums/generator.go b/cmd/enums/generator.go index 7cf1cb7..2eb51e6 100644 --- a/cmd/enums/generator.go +++ b/cmd/enums/generator.go @@ -17,7 +17,7 @@ import ( const ( enumsPkgName = "enums" enumsDir = "internal/pkg/enums" - outputPath = "web/lib/generated/enums.ts" + outputPath = "dashboard/lib/generated/enums.ts" ) type enumValueType string diff --git a/cmd/testdata/aiagent/init.go b/cmd/testdata/aiagent/init.go index 9f0ee77..4eda9d2 100644 --- a/cmd/testdata/aiagent/init.go +++ b/cmd/testdata/aiagent/init.go @@ -87,6 +87,7 @@ func buildSeedItems(aiConfigID int64, knowledgeIDs []int64, defaultTeamIDs strin ReplyTimeoutSeconds: 180, TeamIDs: defaultTeamIDs, HandoffMode: enums.AIAgentHandoffModeWaitPool, + FallbackMode: enums.AIAgentFallbackModeSuggestRetry, FallbackMessage: "我暂时没有找到足够准确的信息。你可以补充具体的问题,我再继续帮你查。", KnowledgeIDs: utils.JoinInt64s(knowledgeIDs), SkillIDs: defaultSkillIDs, diff --git a/cmd/testdata/kb/kb.go b/cmd/testdata/kb/kb.go index a11428e..26c16c8 100644 --- a/cmd/testdata/kb/kb.go +++ b/cmd/testdata/kb/kb.go @@ -118,7 +118,6 @@ func ensureKnowledgeBase(db *gorm.DB) (*models.KnowledgeBase, error) { ChunkMaxTokens: 400, ChunkOverlapTokens: 40, AnswerMode: int(enums.KnowledgeAnswerModeStrict), - FallbackMode: int(enums.KnowledgeFallbackModeNoAnswer), AuditFields: models.AuditFields{ CreatedAt: now, CreateUserID: constants.SystemAuditUserID, @@ -168,7 +167,6 @@ func ensureFAQKnowledgeBase(db *gorm.DB) (*models.KnowledgeBase, error) { ChunkMaxTokens: 0, ChunkOverlapTokens: 0, AnswerMode: int(enums.KnowledgeAnswerModeStrict), - FallbackMode: int(enums.KnowledgeFallbackModeNoAnswer), Remark: "测试数据初始化自动生成", AuditFields: models.AuditFields{ CreatedAt: now, @@ -197,7 +195,6 @@ func ensureFAQKnowledgeBase(db *gorm.DB) (*models.KnowledgeBase, error) { "chunk_max_tokens": 0, "chunk_overlap_tokens": 0, "answer_mode": int(enums.KnowledgeAnswerModeStrict), - "fallback_mode": int(enums.KnowledgeFallbackModeNoAnswer), "remark": "测试数据初始化自动生成", "update_user_id": constants.SystemAuditUserID, "update_user_name": constants.SystemAuditUserName, diff --git a/dashboard/app/(dashboard)/ai-agents/_components/edit.tsx b/dashboard/app/(dashboard)/ai-agents/_components/edit.tsx index f31ab4c..6f44729 100644 --- a/dashboard/app/(dashboard)/ai-agents/_components/edit.tsx +++ b/dashboard/app/(dashboard)/ai-agents/_components/edit.tsx @@ -50,6 +50,8 @@ import { } from "@/lib/api/admin"; import { getEnumOptions } from "@/lib/enums"; import { + AIAgentFallbackMode, + AIAgentFallbackModeLabels, AIAgentHandoffMode, AIAgentHandoffModeLabels, AIModelType, @@ -93,6 +95,7 @@ const schema = z.object({ .number() .min(0, "回复超时秒数必须是大于等于 0 的整数"), handoffMode: z.string().trim().min(1, "请选择转人工模式"), + fallbackMode: z.string().trim().min(1, "请选择兜底策略"), fallbackMessage: z.string().trim(), }); @@ -118,6 +121,13 @@ const handoffModeOptions = getEnumOptions(AIAgentHandoffModeLabels).map( }), ); +const fallbackModeOptions = getEnumOptions(AIAgentFallbackModeLabels).map( + (option) => ({ + value: String(option.value), + label: option.label, + }), +); + function buildForm(item: AIAgent | null): EditForm { if (!item) { return { @@ -129,6 +139,7 @@ function buildForm(item: AIAgent | null): EditForm { welcomeMessage: "", replyTimeoutSeconds: 180, handoffMode: String(AIAgentHandoffMode.WaitPool), + fallbackMode: String(AIAgentFallbackMode.NoAnswer), fallbackMessage: "", }; } @@ -141,6 +152,7 @@ function buildForm(item: AIAgent | null): EditForm { welcomeMessage: item.welcomeMessage || "", replyTimeoutSeconds: item.replyTimeoutSeconds ?? 180, handoffMode: String(item.handoffMode), + fallbackMode: String(item.fallbackMode), fallbackMessage: item.fallbackMessage || "", }; } @@ -163,6 +175,7 @@ function buildPayload( replyTimeoutSeconds: Number(form.replyTimeoutSeconds), teamIds, handoffMode: Number(form.handoffMode), + fallbackMode: Number(form.fallbackMode), fallbackMessage: form.fallbackMessage.trim(), knowledgeIds, skillIds, @@ -737,13 +750,34 @@ function EditDialogBody({ + + 知识库兜底策略 + + ( + + )} + /> + + + + 兜底文案
- 仅在兜底模式为“直接声明无答案”或“引导补充信息”时使用。转人工已统一改为 AI Graph Tool,不再通过兜底模式直接触发。 + 知识库未命中或命中证据不足时,会按这里的策略和文案进行兜底回复。转人工请通过 Graph Tool 配合转人工模式实现。