아바타 v3 세션 연결 — P1 서연 리노컷 아바타와 음성 립싱크
Some checks are pending
API contract / OpenAPI type drift (push) Waiting to run

- ClientAvatar가 리그 레지스트리(v3/rigs)로 P1을 판정해 그림 영역을 ClientAvatarV3로 그린다(로드 중·실패 시 기존 SVG, VITE_AVATAR_V3=0이면 끔)
- 발화 구동 공용 모듈 speechDriver: Lab과 세션이 함께 쓰고, TTS AudioBuffer를 오디오 시계로 표본해 립싱크·발화 동반층·지문 cue를 돌린다
- Session: TTS 재생 시작 시 발화(원문·버퍼·시작 시각) 전달, 음성 실패 시 텍스트 타이밍 발화, 정지 경로에서 해제, 개방도·겉표정 강도 전달
- 정지 화면(시작 전·썸네일)도 한 프레임을 그리고, 박스 실측 폭으로 상반신/얼굴 크롭을 고른다
- 세션 발화 E2E(오디오·실패 경로), P1 레이아웃 게이트, P1 표정 시험을 v3 기대로 갱신
This commit is contained in:
Yun Chan 2026-10-01 16:12:24 +09:00
parent ecb36d123f
commit 613bcb603e
14 changed files with 1000 additions and 182 deletions

View file

@ -337,15 +337,16 @@ test.describe("persona avatar expression rig", () => {
await expect(page.locator(".sx-stage__now")).toContainText("온화함");
});
test("uses the original SVG parameter rig for P1 Seoyeon", async ({ page }) => {
test("uses the v3 linocut avatar for P1 Seoyeon", async ({ page }) => {
await page.goto("/learn/session/P1");
const avatar = page.locator('.vg-avatar[data-persona-code="P1"]').first();
await expect(avatar).toBeVisible();
await expect(avatar).toHaveAttribute("data-render-mode", "svg");
await expect(avatar).toHaveAttribute("data-affect", "sad");
await expect(avatar.locator(".vg-raster")).toHaveCount(0);
await expect(avatar.locator(".vg-avatar__svg")).toBeVisible();
await expect(avatar.locator('[data-avatar-neck="true"]')).toBeVisible();
const v3 = avatar.locator('[data-avatar-renderer="linocut"]');
await expect(v3).toHaveAttribute("data-load-state", "ready", { timeout: 15_000 });
await expect(v3.locator(".linocut-avatar")).toBeVisible();
await expect(v3).toHaveAttribute("data-viseme", "X");
});
});