Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/android-apk-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ permissions:

on:
push:
branches: [main, develop]
branches: [main, dev]
paths: ['app/**']
pull_request:
branches: [main]
branches: [main, dev]
paths: ['app/**']
workflow_dispatch:

Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/ios-ipa-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ permissions:

on:
push:
branches: [main, develop]
branches: [main, dev]
paths: ['app/**']
pull_request:
branches: [main]
branches: [main, dev]
paths: ['app/**']
workflow_dispatch:

Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/speaker-recognition-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: Speaker Recognition Tests

on:
push:
branches: [ main, develop ]
branches: [ main, dev ]
paths:
- 'extras/speaker-recognition/src/**'
- 'extras/speaker-recognition/tests/**'
Expand All @@ -13,7 +13,7 @@ on:
- 'extras/speaker-recognition/run-test.sh'
- '.github/workflows/speaker-recognition-tests.yml'
pull_request:
branches: [ main, develop ]
branches: [ main, dev ]
paths:
- 'extras/speaker-recognition/src/**'
- 'extras/speaker-recognition/tests/**'
Expand Down
12 changes: 8 additions & 4 deletions extras/speaker-recognition/run-test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -134,18 +134,22 @@ docker compose -f docker-compose-test.yml down -v || true

# Run speaker recognition integration tests
print_info "Running speaker recognition integration tests..."
print_info "Disabling BuildKit for integration tests (DOCKER_BUILDKIT=0)"
print_info "Building with BuildKit, plain progress output (BUILDKIT_PROGRESS=plain)"

# Set environment variables for the test
export DOCKER_BUILDKIT=0
# BuildKit is required: the Dockerfile uses `RUN --mount=type=cache` for the uv
# cache, which the legacy builder rejects outright ("the --mount option requires
# BuildKit"). Plain progress keeps the unrolled, greppable build log that the
# legacy builder used to give us.
export BUILDKIT_PROGRESS=plain

# Run the integration test with timeout (speaker recognition models need time)
print_info "Starting speaker recognition test (timeout: 30 minutes)..."

# Run test with proper signal forwarding and output handling
{
timeout --foreground --kill-after=60 1800 \
uv run pytest tests/test_speaker_service_integration.py -v -s --tb=short --log-cli-level=INFO
uv run --extra cpu --group test \
pytest tests/test_speaker_service_integration.py -v -s --tb=short --log-cli-level=INFO
} || {
exit_code=$?
if [ $exit_code -eq 124 ]; then
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -391,39 +391,28 @@ def test_speaker_recognition_pipeline(speaker_service):
assert total_segments > 0, "No segments produced"
print("✅ Conversation processing API works correctly")

# Phase 7: Word-Level Data Validation
print("📝 Phase 7: Validating word-level timestamp data in segments...")
segments_with_words = 0
total_words_found = 0

# Phase 7: Segment Structure Validation
print("📝 Phase 7: Validating segment structure...")
# /diarize-and-identify only diarizes and identifies speakers - it does not
# transcribe, so its segments carry no word-level data. Word-level timestamps
# are validated in Phase 8 against /v1/diarize-identify-match, which is handed
# a transcript to match against.
for seg in result["segments"]:
# Each segment should have a words array (empty segments might have empty array)
assert "words" in seg, f"Segment missing 'words' field: {seg}"
words = seg.get("words", [])

if len(words) > 0:
segments_with_words += 1
total_words_found += len(words)

# Validate word structure
for word in words[:3]: # Check first 3 words of each segment
assert "word" in word, f"Word missing 'word' field: {word}"
assert "start" in word, f"Word missing 'start' field: {word}"
assert "end" in word, f"Word missing 'end' field: {word}"
# confidence is optional
assert isinstance(
word["start"], (int, float)
), f"Word 'start' should be numeric: {word}"
assert isinstance(
word["end"], (int, float)
), f"Word 'end' should be numeric: {word}"

print(
f" ✅ Word-level data: {segments_with_words}/{total_segments} segments have words ({total_words_found} total words)"
)
assert segments_with_words > 0, "No segments contain word-level timestamp data"
assert total_words_found > 0, "No words found across all segments"
print("✅ Word-level timestamp data validated successfully")
assert isinstance(
seg["start"], (int, float)
), f"Segment 'start' should be numeric: {seg}"
assert isinstance(
seg["end"], (int, float)
), f"Segment 'end' should be numeric: {seg}"
assert seg["end"] >= seg["start"], f"Segment ends before it starts: {seg}"
assert seg.get("status") in {
"identified",
"unknown",
"error",
}, f"Unexpected segment status: {seg}"

print(f" ✅ All {total_segments} segments have a valid structure")
print("✅ Segment structure validated successfully")

# Phase 8: Diarize-Identify-Match Endpoint (Backend Integration Mode)
print(
Expand Down Expand Up @@ -512,9 +501,7 @@ def test_speaker_recognition_pipeline(speaker_service):
print(
f"✅ Conversation processing: PASS ({total_segments} segments, {identified_segments} identified)"
)
print(
f"✅ Word-level timestamps: PASS ({total_words_found} words in {segments_with_words} segments)"
)
print(f"✅ Segment structure: PASS ({total_segments} segments)")
print(
f"✅ Diarize-identify-match: PASS ({match_total_words} matched words in {match_segments_with_words} segments)"
)
Expand Down
Loading