From 37c06db6be508083d299ee19ba9cafc26e6a1098 Mon Sep 17 00:00:00 2001 From: hobokenchicken Date: Fri, 5 Jun 2026 14:19:59 -0400 Subject: [PATCH] fix(expressions): use full expression names with .exp3.json suffix Epsilon model registers expressions as 'Smile.exp3.json' not 'Smile'. Added EXPR_MAP to map friendly names to full registered names. Fixes expression buttons and idle cycling. --- frontend/src/components/KiraAvatar.tsx | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/frontend/src/components/KiraAvatar.tsx b/frontend/src/components/KiraAvatar.tsx index fa9eda2..784d1c7 100644 --- a/frontend/src/components/KiraAvatar.tsx +++ b/frontend/src/components/KiraAvatar.tsx @@ -18,6 +18,16 @@ type ExpressionName = 'Normal' | 'Smile' | 'Sad' | 'Angry' | 'Surprised' | 'Blus const EXPRESSIONS: ExpressionName[] = ['Normal', 'Smile', 'Sad', 'Angry', 'Surprised', 'Blushing']; const IDLE_EXPRESSIONS: ExpressionName[] = ['Normal', 'Smile', 'Blushing']; +// The Epsilon model registers expressions with the .exp3.json suffix +const EXPR_MAP: Record = { + Normal: 'Normal.exp3.json', + Smile: 'Smile.exp3.json', + Sad: 'Sad.exp3.json', + Angry: 'Angry.exp3.json', + Surprised: 'Surprised.exp3.json', + Blushing: 'Blushing.exp3.json', +}; + export default function KiraAvatar(props: Props) { const lipSyncRef = useRef(0); const idleExprRef = useRef | null>(null); @@ -29,7 +39,7 @@ export default function KiraAvatar(props: Props) { idleExprRef.current = setInterval(() => { if (props.isSpeaking) return; const expr = IDLE_EXPRESSIONS[Math.floor(Math.random() * IDLE_EXPRESSIONS.length)]; - try { props.kiraModel.expression(expr); } catch {} + try { props.kiraModel.expression(EXPR_MAP[expr]); } catch {} setCurrentExpression(expr); }, 8000 + Math.random() * 7000); return () => clearInterval(idleExprRef.current ?? undefined); @@ -106,7 +116,7 @@ export default function KiraAvatar(props: Props) {