Skip to content

fix: resolve audio overlap and switch default language to English#134

Merged
ComBba merged 3 commits into
mainfrom
fix/audio-overlap-and-english-default
Feb 26, 2026
Merged

fix: resolve audio overlap and switch default language to English#134
ComBba merged 3 commits into
mainfrom
fix/audio-overlap-and-english-default

Conversation

@ComBba

@ComBba ComBba commented Feb 26, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Fix PCM audio overlap by scheduling chunks sequentially via AudioContext.currentTime queue
  • Switch all hardcoded Korean text to English for international hackathon judges
  • Default language is now English; non-English personas use their detected language code

Changes

Audio overlap fix (web/hooks/useAudio.ts)

  • Track nextStartTime to schedule each PCM buffer after the previous one finishes
  • Prevents multiple AudioBufferSource nodes from playing simultaneously

English default (internal/session/manager.go, internal/handler/websocket.go)

  • Onboarding greeting: "안녕하세요, missless에 오신 걸 환영해요" → "Hi there, welcome to missless"
  • Initial trigger: Korean → English
  • Transition message: "잠시 눈을 감아보세요..." → "Close your eyes for a moment..."
  • Warning message: "1분 후 대화가 종료됩니다" → "The conversation will end in 1 minute"
  • Reunion default: "Speak naturally in Korean." → "Speak naturally in English."
  • Non-English language codes (e.g., "ko") still use Speak naturally in the language code 'ko'.

Local CI

  • go vet passed
  • go test -race -count=1 ./... passed (all 15 packages)

Test plan

  • Connect to WebSocket and verify English greeting
  • Send multiple rapid PCM chunks and verify no audio overlap
  • Verify non-English persona still gets correct language instruction

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes

    • 연속 오디오 재생이 겹치지 않도록 스케줄링을 개선하여 재생 타이밍 안정화 및 정확한 종료 처리 보장.
  • Chores

    • 온보딩·재회 등 사용자 안내문과 시스템 인사문구를 한국어에서 영어로 변경하고 기본 언어를 영어로 설정.
  • Tests

    • 영어 기반 동작을 반영하도록 관련 테스트 기대값과 시나리오 업데이트.

- Queue PCM audio chunks sequentially using Web Audio API scheduling
  to prevent overlapping playback that caused garbled sound
- Change all hardcoded Korean text to English in system prompts,
  greeting triggers, and UI messages for international hackathon
- Default language is now English; non-English personas use their
  detected language code

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@gemini-code-assist

Copy link
Copy Markdown

Summary of Changes

Hello @ComBba, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request primarily addresses two key areas: improving the audio experience and enhancing internationalization. It ensures that audio playback is seamless by preventing sound overlaps and standardizes the application's default language to English, making it more accessible to a broader audience.

Highlights

  • Audio Playback: Resolved PCM audio overlap by scheduling chunks sequentially using AudioContext.currentTime, ensuring smooth playback without simultaneous audio nodes.
  • Default Language: Switched the default language for various user-facing messages and system instructions from Korean to English, while retaining support for non-English personas.
Changelog
  • internal/handler/websocket.go
    • Updated the initial greeting trigger from Korean to English.
  • internal/session/manager.go
    • Changed the session transition message to "Close your eyes for a moment...".
    • Updated the onboarding configuration description to reflect an "English guide".
    • Modified the onboarding greeting to "Hi there, welcome to missless".
    • Updated the video analysis progress message to "I'm analyzing the videos now, just a moment".
    • Changed the default reunion instruction to "Speak naturally in English.".
    • Updated the reunion warning message to "The conversation will end in 1 minute".
  • internal/session/manager_test.go
    • Updated onboarding config test to check for English greeting.
    • Modified transition notification test to check for English message.
    • Refactored reunion config tests to include TestBuildReunionConfig_NonEnglishLang and TestBuildReunionConfig_DefaultEnglish.
  • web/hooks/useAudio.ts
    • Introduced nextStartTimeRef to manage sequential audio playback.
    • Implemented logic to schedule audio buffers using AudioContext.currentTime to prevent overlap.
    • Adjusted onended callback to correctly set isPlaying state after all queued audio finishes.
    • Reset nextStartTimeRef during cleanup.
Activity
  • The author confirmed that go vet passed.
  • The author confirmed that go test -race -count=1 ./... passed for all 15 packages.
  • A test plan was provided to verify the English greeting, absence of audio overlap, and correct non-English persona language instructions.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@coderabbitai

coderabbitai Bot commented Feb 26, 2026

Copy link
Copy Markdown

Walkthrough

웹소켓 온보딩 문구와 세션 관련 사용자/시스템 메시지를 한국어에서 영어로 변경하고, 세션 재회(리유니온) 시스템 지침의 기본 언어를 영어로 설정하며, 웹 오디오 재생을 순차적으로 스케줄링하도록 플레이백 로직을 수정했습니다.

Changes

Cohort / File(s) Summary
i18n 텍스트 변경
internal/handler/websocket.go, internal/session/manager.go
온보딩 인사말, 진행/전환/재회 알림 등 사용자·시스템 메시지를 한국어에서 영어로 교체. 기본 언어 코드와 기본 언어 지침(defaultLangCode/defaultLangInstruction)을 영어로 설정하고 관련 조건 처리 조정.
세션 테스트 업데이트
internal/session/manager_test.go
테스트 기대값을 영어로 변경; 테스트 함수명 변경(TestBuildReunionConfig_NonKoreanLangTestBuildReunionConfig_NonEnglishLang) 및 기본 영어 동작 검증용 테스트 2건 추가/수정.
오디오 재생 스케줄링 개선
web/hooks/useAudio.ts, web/__tests__/hooks/useAudio.test.ts
PCM 재생 시 중첩을 방지하기 위해 nextStartTimeRef 도입 및 시작 시간 예약 로직 추가. AudioContext 현재시간 모킹과 재생 완료 시점 시뮬레이션을 위한 테스트 보강.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 분

🐰 I say hello in English today—
audio chunks hop in tidy queue,
words changed, timers set, playback neat,
no overlap, just steady beat,
new greetings, new rhythm, onward we chew. 🥕

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 제목이 PR의 주요 변경사항 두 가지(오디오 겹침 해결 및 기본 언어를 영어로 변경)를 명확하게 요약하고 있습니다.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/audio-overlap-and-english-default

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request effectively addresses the audio overlap issue by implementing a sequential playback queue in useAudio.ts. The switch to English as the default language is also thoroughly implemented across the backend. My review includes a couple of suggestions for improving maintainability by replacing hardcoded values (a magic number in the audio hook and language strings in the session manager) with named constants. These changes will make the code easier to read and update in the future.

Comment thread internal/session/manager.go Outdated
Comment on lines 372 to 375
langNote := "Speak naturally in English."
if lang != "" && lang != "en" {
langNote = fmt.Sprintf("Speak naturally in the language code '%s'.", lang)
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The default language instruction and language code ("en") are hardcoded. To improve maintainability and make future localization easier, consider defining these as package-level constants. For example:

const (
    defaultLangCode = "en"
    defaultLangInstruction = "Speak naturally in English."
)

You can then use these constants here, making the code cleaner and easier to update.

Comment thread web/hooks/useAudio.ts Outdated

source.onended = () => {
// Mark not playing only when no more queued audio remains.
if (ctx.currentTime >= nextStartTimeRef.current - 0.01) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The magic number 0.01 is used here as a tolerance, likely to account for precision issues with AudioContext.currentTime. To improve code clarity and maintainability, it's best to extract this value into a named constant with a comment explaining its purpose. For example:

// Small tolerance for AudioContext.currentTime precision when checking if playback has ended.
const PLAYBACK_END_TOLERANCE_SECONDS = 0.01;

Using this constant would make the logic here self-documenting.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
internal/session/manager_test.go (1)

410-419: “기본값” 검증은 빈 언어 코드 경로도 직접 확인해 주세요.

현재 테스트는 lang="en" 명시 케이스를 검증합니다. 기본값(미지정) 동작 보장을 위해 lang="" 케이스를 이 테스트(또는 별도 테스트)로 추가하는 편이 더 정확합니다.

테스트 의도에 맞춘 최소 수정 예시
-func TestBuildReunionConfig_DefaultEnglish(t *testing.T) {
+func TestBuildReunionConfig_DefaultEnglishWhenLangEmpty(t *testing.T) {
 	mgr := NewManager("test-en-lang")
-	mgr.SetPersona("Friend", "Kore", "en", "Cheerful", "Casual")
+	mgr.SetPersona("Friend", "Kore", "", "Cheerful", "Casual")

 	cfg := mgr.BuildReunionConfig()
 	sysText := cfg.SystemInstruction.Parts[0].Text

 	if !strings.Contains(sysText, "Speak naturally in English") {
-		t.Fatalf("expected default English language note for lang='en', got: %s", sysText)
+		t.Fatalf("expected default English language note for empty lang, got: %s", sysText)
 	}
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@internal/session/manager_test.go` around lines 410 - 419, Update the test to
also verify the "default language" behavior when no language is provided: in
TestBuildReunionConfig_DefaultEnglish (or a new test) create a Manager with
NewManager("test-en-lang"), call mgr.SetPersona("Friend", "Kore", "" /* empty
lang */, "Cheerful", "Casual"), then call mgr.BuildReunionConfig() and assert
that cfg.SystemInstruction.Parts[0].Text contains "Speak naturally in English"
(same assertion as the existing en case); this ensures
BuildReunionConfig/Manager.SetPersona handles the empty lang path the same as
"en".
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@internal/session/manager_test.go`:
- Around line 410-419: Update the test to also verify the "default language"
behavior when no language is provided: in TestBuildReunionConfig_DefaultEnglish
(or a new test) create a Manager with NewManager("test-en-lang"), call
mgr.SetPersona("Friend", "Kore", "" /* empty lang */, "Cheerful", "Casual"),
then call mgr.BuildReunionConfig() and assert that
cfg.SystemInstruction.Parts[0].Text contains "Speak naturally in English" (same
assertion as the existing en case); this ensures
BuildReunionConfig/Manager.SetPersona handles the empty lang path the same as
"en".

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c153044 and ba25efc.

📒 Files selected for processing (4)
  • internal/handler/websocket.go
  • internal/session/manager.go
  • internal/session/manager_test.go
  • web/hooks/useAudio.ts

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ba25efc9e8

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread web/hooks/useAudio.ts Outdated
Comment on lines +44 to +45
if (ctx.currentTime >= nextStartTimeRef.current - 0.01) {
setIsPlaying(false);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Make onended reset robust when audio timing values are missing

This onended condition now relies on ctx.currentTime and nextStartTimeRef, but the existing audio-hook test harness does not provide currentTime on MockAudioContext or duration on the mocked buffer (web/__tests__/hooks/useAudio.test.ts), so the comparison becomes undefined >= NaN and setIsPlaying(false) never executes. Since frontend CI runs unit tests (.github/workflows/ci.yml, Unit tests step), this change causes a deterministic test regression for the source-end path unless the reset logic (or the mock contract) is updated in the same change.

Useful? React with 👍 / 👎.

- Fix frontend test regression: add currentTime and duration to
  MockAudioContext so onended callback correctly triggers setIsPlaying
- Extract PLAYBACK_END_TOLERANCE_S constant (Gemini)
- Extract defaultLangCode/defaultLangInstruction constants (Gemini)
- Add TestBuildReunionConfig_DefaultEnglishWhenLangEmpty for empty
  language code path coverage (CodeRabbit)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
internal/session/manager.go (1)

371-379: lang 값 정규화로 기본 영어 분기를 더 견고하게 만드세요.

Line 378 조건은 "EN" 또는 " en " 같은 입력에서 비영어 분기로 처리될 수 있습니다. 비교 전에 TrimSpace + ToLower 정규화를 권장합니다.

제안 diff
 func buildReunionSystemInstruction(name, personality, speechStyle, lang string) string {
 	langNote := defaultLangInstruction
-	if lang != "" && lang != defaultLangCode {
-		langNote = fmt.Sprintf("Speak naturally in the language code '%s'.", lang)
+	normalizedLang := strings.ToLower(strings.TrimSpace(lang))
+	if normalizedLang != "" && normalizedLang != defaultLangCode {
+		langNote = fmt.Sprintf("Speak naturally in the language code '%s'.", normalizedLang)
 	}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@internal/session/manager.go` around lines 371 - 379, The lang comparison in
buildReunionSystemInstruction is brittle for inputs like "EN" or " en ";
normalize lang by calling strings.TrimSpace and strings.ToLower (e.g.,
normalizedLang := strings.ToLower(strings.TrimSpace(lang))) before checking
against defaultLangCode and emptiness, then use the normalized value when
deciding whether to set langNote (defaultLangInstruction vs formatted "Speak
naturally in the language code '%s'.") so the English branch is robust to
casing/whitespace.
internal/session/manager_test.go (1)

44-46: 온보딩 인사 검증을 더 구체적으로 고정하세요.

현재 "welcome"만 확인하면 의도한 문구가 바뀌어도 테스트가 통과할 수 있습니다. 핵심 문장 전체 검증이 더 안전합니다.

제안 diff
-	if !strings.Contains(sysText, "welcome") {
-		t.Fatalf("expected English greeting in system instruction")
+	if !strings.Contains(sysText, "Hi there, welcome to missless") {
+		t.Fatalf("expected exact English greeting in system instruction")
 	}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@internal/session/manager_test.go` around lines 44 - 46, Replace the loose
substring check that only looks for "welcome" with an assertion that verifies
the full expected onboarding sentence present in sysText (replace the
strings.Contains(sysText, "welcome") check). Locate the test's sysText variable
and update the assertion to check for the exact core greeting phrase used in the
system instruction (e.g., the full English onboarding sentence) so changes to
unrelated words won't let the test pass; keep the failure message descriptive
and reference sysText in the assertion.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@web/hooks/useAudio.ts`:
- Around line 55-59: The cleanup function in useAudio currently closes the
AudioContext but doesn't reset playback state; update the cleanup callback to
explicitly set isPlaying to false (call setIsPlaying(false)) and, if you
maintain a ref like isPlayingRef, set isPlayingRef.current = false as well so
the UI and any ref-based logic reflect that playback has stopped when
audioCtxRef.current is closed.

---

Nitpick comments:
In `@internal/session/manager_test.go`:
- Around line 44-46: Replace the loose substring check that only looks for
"welcome" with an assertion that verifies the full expected onboarding sentence
present in sysText (replace the strings.Contains(sysText, "welcome") check).
Locate the test's sysText variable and update the assertion to check for the
exact core greeting phrase used in the system instruction (e.g., the full
English onboarding sentence) so changes to unrelated words won't let the test
pass; keep the failure message descriptive and reference sysText in the
assertion.

In `@internal/session/manager.go`:
- Around line 371-379: The lang comparison in buildReunionSystemInstruction is
brittle for inputs like "EN" or " en "; normalize lang by calling
strings.TrimSpace and strings.ToLower (e.g., normalizedLang :=
strings.ToLower(strings.TrimSpace(lang))) before checking against
defaultLangCode and emptiness, then use the normalized value when deciding
whether to set langNote (defaultLangInstruction vs formatted "Speak naturally in
the language code '%s'.") so the English branch is robust to casing/whitespace.

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ba25efc and a43d113.

📒 Files selected for processing (4)
  • internal/session/manager.go
  • internal/session/manager_test.go
  • web/__tests__/hooks/useAudio.test.ts
  • web/hooks/useAudio.ts

Comment thread web/hooks/useAudio.ts
Comment on lines 55 to 59
const cleanup = useCallback(() => {
audioCtxRef.current?.close();
audioCtxRef.current = null;
nextStartTimeRef.current = 0;
}, []);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

cleanup에서 isPlaying을 명시적으로 false로 내려주세요.

Line 55-59에서 오디오 컨텍스트를 닫아도, 재생 중 cleanup이 호출되면 UI 상태가 재생 중으로 남을 수 있습니다. 정리 루틴에서 상태를 함께 초기화하는 것이 안전합니다.

제안 diff
   const cleanup = useCallback(() => {
     audioCtxRef.current?.close();
     audioCtxRef.current = null;
     nextStartTimeRef.current = 0;
+    setIsPlaying(false);
   }, []);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@web/hooks/useAudio.ts` around lines 55 - 59, The cleanup function in useAudio
currently closes the AudioContext but doesn't reset playback state; update the
cleanup callback to explicitly set isPlaying to false (call setIsPlaying(false))
and, if you maintain a ref like isPlayingRef, set isPlayingRef.current = false
as well so the UI and any ref-based logic reflect that playback has stopped when
audioCtxRef.current is closed.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@ComBba ComBba merged commit 0e57055 into main Feb 26, 2026
5 checks passed
@ComBba ComBba deleted the fix/audio-overlap-and-english-default branch February 26, 2026 01:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant