Agent/utils/masking-validator.ts
2026-08-06 22:17:39 +08:00

83 lines
2.8 KiB
TypeScript

// @ts-nocheck
export const EMP_RE = /emp_[a-z0-9]+/i;
const CN_NUM_MAP = {
'一': 1, '二': 2, '三': 3, '四': 4, '五': 5,
'六': 6, '七': 7, '八': 8, '九': 9, '十': 10,
};
const INDEX_RE = /(?:第\s*|选\s*|选第\s*)?([一二三四五六七八九十\d]+)\s*[号个]?\s*/;
export function validateCandidateSelection(aiResponse, candidates) {
if (!aiResponse || typeof aiResponse !== 'string') {
return { valid: false, reason: 'NO_AI_RESPONSE' };
}
if (!Array.isArray(candidates) || candidates.length === 0) {
return { valid: false, reason: 'NO_CANDIDATES' };
}
const validIds = candidates
.map(c => (typeof c === 'string' ? c : c?.employeeId))
.filter(Boolean)
.map(id => id.toLowerCase());
const empMatch = aiResponse.match(EMP_RE);
if (empMatch) {
const empId = empMatch[0].toLowerCase();
if (validIds.includes(empId)) {
return { valid: true, employeeId: empId };
}
return {
valid: false,
reason: 'EMP_NOT_IN_CANDIDATES',
attempted: empId,
validIds,
};
}
const numMatch = aiResponse.match(INDEX_RE);
if (numMatch) {
const raw = numMatch[1];
const idx = /^\d+$/.test(raw)
? parseInt(raw, 10)
: CN_NUM_MAP[raw];
if (idx == null) {
return { valid: false, reason: 'UNRECOGNIZED_FORMAT' };
}
if (idx >= 1 && idx <= validIds.length) {
return { valid: true, employeeId: validIds[idx - 1] };
}
return {
valid: false,
reason: 'INDEX_OUT_OF_RANGE',
index: idx,
total: validIds.length,
};
}
return { valid: false, reason: 'UNRECOGNIZED_FORMAT' };
}
export function formatValidationFailure(result) {
if (!result || result.valid) return '';
switch (result.reason) {
case 'INDEX_OUT_OF_RANGE':
return `序号 ${result.index} 越界(共 ${result.total} 个候选)。请用户从 1-${result.total} 中选择,或在候选表里指出特征(如「乘务二组那个」)。`;
case 'EMP_NOT_IN_CANDIDATES':
return `引用的员工 ID「${result.attempted}」不在当前候选列表内。请用户从候选列表中重新选择(候选:${result.validIds?.join(', ')})。`;
case 'UNRECOGNIZED_FORMAT':
return `未识别用户的选择。请用户回复「序号」(如「1 号」),或直接说班组/岗位特征(如「乘务二组那个」)。`;
case 'NO_CANDIDATES':
return `当前没有候选列表,请用户先重新发起查询。`;
case 'NO_AI_RESPONSE':
return `AI 回复为空,无法识别选择。`;
default:
return `选择无效,请用户重新选择。`;
}
}