43bc8bbc2b
Expose shadow/canary router policy in ops admin, add FAQ rule fast-path, and tighten router defaults (1200ms timeout, 0.65 confidence). Includes verify-h5-llm-router-shadow for production canary rollout. Co-authored-by: Cursor <cursoragent@cursor.com>
77 lines
2.5 KiB
JavaScript
77 lines
2.5 KiB
JavaScript
export const GOAL_RUN_INTENT_PATTERNS = [
|
|
/(?:长期目标|当前目标|目标是|计划要|正在建设|准备实现|希望长期)/i,
|
|
/(?:分阶段|多步骤|长期任务|持续跟进|帮我规划并执行)/i,
|
|
];
|
|
|
|
export function isGoalRunIntent(text) {
|
|
const normalized = String(text ?? '').trim();
|
|
if (!normalized) return false;
|
|
return GOAL_RUN_INTENT_PATTERNS.some((pattern) => pattern.test(normalized));
|
|
}
|
|
|
|
function envFlag(value, fallback = false) {
|
|
const raw = String(value ?? '').trim().toLowerCase();
|
|
if (!raw) return fallback;
|
|
return ['1', 'true', 'yes', 'on'].includes(raw);
|
|
}
|
|
|
|
function parseUserIdSet(raw) {
|
|
return new Set(
|
|
String(raw ?? '')
|
|
.split(/[,;\s]+/)
|
|
.map((item) => item.trim())
|
|
.filter(Boolean),
|
|
);
|
|
}
|
|
|
|
export function isGoalRunEnabledForUser(userId, env = process.env) {
|
|
if (!envFlag(env.GOAL_RUN_ENABLED, false)) return false;
|
|
const canaryUserIds = parseUserIdSet(env.GOAL_RUN_CANARY_USER_IDS);
|
|
if (!canaryUserIds.size) return true;
|
|
return canaryUserIds.has(String(userId ?? '').trim());
|
|
}
|
|
|
|
export function extractUserMessageDisplayText(userMessage) {
|
|
if (!userMessage) return '';
|
|
if (typeof userMessage === 'string') return userMessage.trim();
|
|
const metadataText = String(userMessage?.metadata?.displayText ?? '').trim();
|
|
if (metadataText) return metadataText;
|
|
const content = userMessage?.content;
|
|
if (typeof content === 'string') return content.trim();
|
|
if (Array.isArray(content)) {
|
|
for (const item of content) {
|
|
if (typeof item === 'string' && item.trim()) return item.trim();
|
|
if (item?.type === 'text' && String(item.text ?? '').trim()) {
|
|
return String(item.text).trim();
|
|
}
|
|
}
|
|
}
|
|
return '';
|
|
}
|
|
|
|
export function deriveGoalTitleFromText(text, maxLength = 80) {
|
|
const normalized = String(text ?? '').replace(/\s+/g, ' ').trim();
|
|
if (!normalized) return '长期任务';
|
|
return normalized.length <= maxLength
|
|
? normalized
|
|
: `${normalized.slice(0, Math.max(0, maxLength - 1))}…`;
|
|
}
|
|
|
|
export function buildGoalContinueUserMessage(feedback = null, { id = null } = {}) {
|
|
const displayText = String(feedback ?? '').trim()
|
|
? `继续下一阶段。补充说明:${String(feedback).trim()}`
|
|
: '继续执行下一阶段';
|
|
const messageId = id ?? (typeof crypto !== 'undefined' && crypto.randomUUID
|
|
? crypto.randomUUID()
|
|
: `goal-continue-${Date.now()}`);
|
|
return {
|
|
id: messageId,
|
|
role: 'user',
|
|
content: [{ type: 'text', text: displayText }],
|
|
metadata: {
|
|
userVisible: true,
|
|
displayText,
|
|
},
|
|
};
|
|
}
|