fix(identity): 重构 agent 命名检测正则 — 覆盖"名称改为小芳"等表达
Some checks failed
CI / Lint & TypeCheck (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
CI / Build Frontend (push) Has been cancelled
CI / Rust Check (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled
Some checks failed
CI / Lint & TypeCheck (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
CI / Build Frontend (push) Has been cancelled
CI / Rust Check (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled
detectAgentNameSuggestion 从固定正则改为 trigger+extract 两步法, 10 个 trigger 模式覆盖中文/英文常见命名表达,stopWords 过滤误匹配。 同时修复 streamStore content 类型处理和 RightPanel 重复事件监听。
This commit is contained in:
@@ -181,20 +181,21 @@ export function RightPanel({ simpleMode = false }: RightPanelProps) {
|
|||||||
}, [currentAgent?.id]);
|
}, [currentAgent?.id]);
|
||||||
|
|
||||||
// Listen for profile updates after conversations (fired after memory extraction completes)
|
// Listen for profile updates after conversations (fired after memory extraction completes)
|
||||||
|
// This single handler handles both userProfile refresh and clone name refresh
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const handler = (e: Event) => {
|
const handler = async (e: Event) => {
|
||||||
const detail = (e as CustomEvent).detail;
|
const detail = (e as CustomEvent).detail;
|
||||||
if (detail?.agentId === currentAgent?.id && currentAgent?.id) {
|
if (detail?.agentId === currentAgent?.id && currentAgent?.id) {
|
||||||
invoke<AgentInfo | null>('agent_get', { agentId: currentAgent.id })
|
invoke<AgentInfo | null>('agent_get', { agentId: currentAgent.id })
|
||||||
.then(data => setUserProfile(data?.userProfile ?? null))
|
.then(data => setUserProfile(data?.userProfile ?? null))
|
||||||
.catch(() => {});
|
.catch(() => {});
|
||||||
// Refresh clones data so selectedClone (name, role, nickname, etc.) stays current
|
// Refresh clones data so selectedClone (name, role, nickname, etc.) stays current
|
||||||
loadClones();
|
await loadClones();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
window.addEventListener('zclaw:agent-profile-updated', handler);
|
window.addEventListener('zclaw:agent-profile-updated', handler);
|
||||||
return () => window.removeEventListener('zclaw:agent-profile-updated', handler);
|
return () => window.removeEventListener('zclaw:agent-profile-updated', handler);
|
||||||
}, [currentAgent?.id]);
|
}, [currentAgent?.id, clones]);
|
||||||
|
|
||||||
// Listen for Tauri identity update events (from Rust post_conversation_hook)
|
// Listen for Tauri identity update events (from Rust post_conversation_hook)
|
||||||
// When agent name changes in soul.md, update AgentConfig.name and refresh panel
|
// When agent name changes in soul.md, update AgentConfig.name and refresh panel
|
||||||
|
|||||||
@@ -147,25 +147,41 @@ export function detectNameSuggestion(message: string): string | undefined {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Detect if user gives the agent a name (e.g., "叫你小马", "以后叫你小马", "你的名字是小马").
|
* Detect if user gives the agent a name.
|
||||||
* Returns the detected agent name or undefined.
|
* Covers: "叫你小马", "你就叫小芳", "名称改为小芳", "名字叫小马",
|
||||||
|
* "改名为X", "起名X", "称呼你为X", English patterns, etc.
|
||||||
*/
|
*/
|
||||||
export function detectAgentNameSuggestion(message: string): string | undefined {
|
export function detectAgentNameSuggestion(message: string): string | undefined {
|
||||||
if (!message) return undefined;
|
if (!message || typeof message !== 'string') return undefined;
|
||||||
const patterns = [
|
// Trigger phrases: the name appears RIGHT AFTER the matched trigger
|
||||||
/叫你[""''「」]?(\S{1,8})[""''「」]?[吧。!]?/,
|
const triggers = [
|
||||||
/你的名字[是为][""''「」]?(\S{1,8})[""''「」]?[。!]?/,
|
/叫你\s*[""''「」]?/, // "叫你小马"
|
||||||
/以后叫你[""''「」]?(\S{1,8})[""''「」]?[吧。!]?/,
|
/你就叫\s*[""''「」]?/, // "你就叫小芳"
|
||||||
/给你起[个]?名[字]?(?:叫)?[""''「」]?(\S{1,8})[""''「」]?/,
|
/你(?:以後|以后)?叫\s*[""''「」]?/, // "你叫小马" / "你以后叫小马"
|
||||||
/name you (\S{1,15})/i,
|
/[名].{0,2}[为是叫成]\s*[""''「」]?/, // "名称改为" / "名字是" / "名称改成"
|
||||||
/call you (\S{1,15})/i,
|
/改[名为称叫]\s*[""''「」]?/, // "改名为X" / "改名X" / "改称X"
|
||||||
|
/起[个]?名[字]?(?:叫)?\s*[""''「」]?/, // "起名X" / "起名叫X"
|
||||||
|
/称呼[你你].{0,2}[为是]\s*[""''「」]?/, // "称呼你为X"
|
||||||
|
/\bname you\s+/i,
|
||||||
|
/\bcall you\s+/i,
|
||||||
|
/\byour name\s+(?:is|should be)\s+/i,
|
||||||
];
|
];
|
||||||
for (const pattern of patterns) {
|
const stopWords = new Set([
|
||||||
const match = message.match(pattern);
|
'你', '我', '他', '她', '它', '的', '了', '是', '在', '有', '不',
|
||||||
if (match && match[1]) {
|
'也', '都', '还', '又', '这', '那', '什么', '怎么', '为什么', '可以',
|
||||||
const name = match[1].replace(/[吧。!,、]/g, '').trim();
|
'能', '会', '要', '想', '去', '来', '做', '说', '看', '好', '吧',
|
||||||
if (name.length >= 1 && name.length <= 8) {
|
'呢', '啊', '哦', '嗯', '哈', '呀', '嘛',
|
||||||
return name;
|
]);
|
||||||
|
for (const trigger of triggers) {
|
||||||
|
const m = message.match(trigger);
|
||||||
|
if (!m) continue;
|
||||||
|
// Extract 1-6 Chinese characters or word chars after the trigger
|
||||||
|
const rest = message.slice(m.index! + m[0].length);
|
||||||
|
const nameMatch = rest.match(/^[""''「」]?([一-鿿]{1,6}|\w{1,10})/);
|
||||||
|
if (nameMatch && nameMatch[1]) {
|
||||||
|
const raw = nameMatch[1].replace(/[吧。!,、呢啊了]+$/g, '').trim();
|
||||||
|
if (raw.length >= 1 && raw.length <= 8 && !stopWords.has(raw)) {
|
||||||
|
return raw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -386,8 +386,9 @@ function createCompleteHandler(
|
|||||||
log.warn('Failed to persist detected userName:', e);
|
log.warn('Failed to persist detected userName:', e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Detect agent name change (e.g. "叫你小马", "以后叫你小马")
|
// Detect agent name change (e.g. "叫你小马", "以后叫你小马", "你就叫小马吧")
|
||||||
const detectedAgentName = lastUserMsg ? detectAgentNameSuggestion(lastUserMsg.content) : undefined;
|
const lastContent = typeof lastUserMsg?.content === 'string' ? lastUserMsg.content : '';
|
||||||
|
const detectedAgentName = lastContent ? detectAgentNameSuggestion(lastContent) : undefined;
|
||||||
if (detectedAgentName && agentId) {
|
if (detectedAgentName && agentId) {
|
||||||
try {
|
try {
|
||||||
const { useAgentStore } = await import('../agentStore');
|
const { useAgentStore } = await import('../agentStore');
|
||||||
|
|||||||
Reference in New Issue
Block a user