feat: add ASR provider support for voice co-creation
This commit is contained in:
@@ -6,6 +6,7 @@ BACKEND_URL="${BACKEND_URL:-http://localhost:52000}"
|
||||
ADMIN_BACKEND_URL="${ADMIN_BACKEND_URL:-http://localhost:52800}"
|
||||
ADMIN_AUTH="${ADMIN_AUTH:-admin:admin}"
|
||||
SMOKE_AUDIO="${SMOKE_AUDIO:-0}"
|
||||
SMOKE_VOICE="${SMOKE_VOICE:-0}"
|
||||
|
||||
COOKIE_JAR="$(mktemp "${TMPDIR:-/tmp}/dreamweaver-cookie.XXXXXX")"
|
||||
cleanup() {
|
||||
@@ -33,6 +34,12 @@ post_json() {
|
||||
curl -fsS -b "$COOKIE_JAR" -H 'Content-Type: application/json' -d "$payload" "$url"
|
||||
}
|
||||
|
||||
post_form() {
|
||||
local url="$1"
|
||||
shift
|
||||
curl -fsS -b "$COOKIE_JAR" "$@" "$url"
|
||||
}
|
||||
|
||||
get_json() {
|
||||
local url="$1"
|
||||
curl -fsS -b "$COOKIE_JAR" "$url"
|
||||
@@ -86,7 +93,7 @@ assert_jq "$session_json" '.user.id == "github:dev_user_001"' "dev session shoul
|
||||
|
||||
say "Checking provider capability policy"
|
||||
capabilities_json="$(curl -fsS -u "$ADMIN_AUTH" "$ADMIN_BACKEND_URL/admin/providers/capabilities")"
|
||||
assert_jq "$capabilities_json" 'map(.capability) | sort == ["image","storybook","text","tts"]' "capabilities should include text/image/tts/storybook"
|
||||
assert_jq "$capabilities_json" 'map(.capability) | sort == ["asr","image","storybook","text","tts"]' "capabilities should include text/image/tts/storybook/asr"
|
||||
|
||||
say "Generating text story without assets"
|
||||
story_json="$(post_json "$APP_URL/api/generations" '{
|
||||
@@ -149,6 +156,67 @@ else
|
||||
say "Skipping audio smoke; set SMOKE_AUDIO=1 to include TTS"
|
||||
fi
|
||||
|
||||
if [[ "$SMOKE_VOICE" == "1" ]]; then
|
||||
say "Creating voice co-creation session"
|
||||
voice_session_json="$(post_json "$APP_URL/api/voice-sessions" '{}')"
|
||||
voice_session_id="$(jq -r '.id' <<<"$voice_session_json")"
|
||||
assert_jq "$voice_session_json" '.status == "draft" and .target_mode == "story" and .can_continue == true' "voice session should be created as a resumable draft"
|
||||
echo "$voice_session_json" | jq '{id,status,target_mode,current_turn_index,can_continue,can_finalize,transcription_mode_hint}'
|
||||
|
||||
say "Submitting voice text fallback turn"
|
||||
voice_turn_json="$(post_json "$APP_URL/api/voice-sessions/$voice_session_id/turns/fallback" '{
|
||||
"transcript_text": "我想听一个小熊和星星一起找家的故事",
|
||||
"duration_ms": 1200
|
||||
}')"
|
||||
voice_turn_id="$(jq -r '.turn_id' <<<"$voice_turn_json")"
|
||||
assert_jq "$voice_turn_json" '.status != "failed" and .turn_id != null and .turn_id != ""' "voice fallback turn should be accepted"
|
||||
|
||||
voice_turn_detail_json="$(get_json "$APP_URL/api/voice-sessions/$voice_session_id/turns/$voice_turn_id")"
|
||||
assert_jq "$voice_turn_detail_json" '.user_transcript | contains("小熊")' "voice fallback turn should keep user transcript"
|
||||
assert_jq "$voice_turn_detail_json" '.assistant_text != null and .assistant_text != ""' "voice fallback turn should return assistant text"
|
||||
assert_jq "$voice_turn_detail_json" '.detected_intent == "start" and .requires_confirmation == false' "first voice turn should start the story without confirmation"
|
||||
echo "$voice_turn_detail_json" | jq '{id,status,detected_intent,requires_confirmation,assistant_audio_ready,assistant_text}'
|
||||
|
||||
say "Submitting voice uploaded turn with demo transcript hint"
|
||||
voice_upload_json="$(post_form "$APP_URL/api/voice-sessions/$voice_session_id/turns" \
|
||||
-F 'audio_file=@/dev/null;filename=turn.webm;type=audio/webm' \
|
||||
-F 'duration_ms=900' \
|
||||
-F 'transcript_hint=不要让小熊害怕,让月亮姐姐帮它')"
|
||||
voice_upload_turn_id="$(jq -r '.turn_id' <<<"$voice_upload_json")"
|
||||
assert_jq "$voice_upload_json" '.status != "failed" and .transcription_provider == "demo"' "voice upload turn should use demo transcript hint"
|
||||
|
||||
voice_upload_detail_json="$(get_json "$APP_URL/api/voice-sessions/$voice_session_id/turns/$voice_upload_turn_id")"
|
||||
assert_jq "$voice_upload_detail_json" '.user_transcript | contains("月亮姐姐")' "voice upload turn should expose hinted transcript"
|
||||
assert_jq "$voice_upload_detail_json" '.detected_intent == "correct" and .assistant_text != null' "voice upload correction should continue the narrative"
|
||||
echo "$voice_upload_detail_json" | jq '{id,status,transcription_provider,detected_intent,requires_confirmation,assistant_audio_ready,assistant_text}'
|
||||
|
||||
say "Checking voice session detail and analytics"
|
||||
voice_detail_json="$(get_json "$APP_URL/api/voice-sessions/$voice_session_id")"
|
||||
assert_jq "$voice_detail_json" '.current_turn_index >= 2 and (.recent_turns | length) >= 2 and (.events | length) >= 2 and .can_finalize == true' "voice session should include turns/events and be finalizable"
|
||||
assert_jq "$voice_detail_json" '([.events[].event_type] | index("turn_transcribed")) != null and ([.events[].event_type] | index("turn_narrative_ready")) != null' "voice session should record key turn events"
|
||||
echo "$voice_detail_json" | jq '{id,status,current_turn_index,can_finalize,latest_detected_intent,events:([.events[].event_type] | unique)}'
|
||||
|
||||
voice_analytics_json="$(get_json "$APP_URL/api/voice-sessions/analytics?days=7")"
|
||||
assert_jq "$voice_analytics_json" '.window_days == 7 and .total_sessions >= 1 and .total_turns >= 2 and .successful_turns >= 2' "voice analytics should include the smoke session"
|
||||
echo "$voice_analytics_json" | jq '{window_days,total_sessions,total_turns,successful_turns,failed_turns,turn_success_rate,finalize_conversion_rate}'
|
||||
|
||||
say "Finalizing voice session into story"
|
||||
voice_finalize_json="$(post_json "$APP_URL/api/voice-sessions/$voice_session_id/finalize" '{
|
||||
"save_story": true,
|
||||
"generate_cover": true,
|
||||
"generate_final_audio": false
|
||||
}')"
|
||||
voice_story_id="$(jq -r '.story_id' <<<"$voice_finalize_json")"
|
||||
assert_jq "$voice_finalize_json" '.status == "completed" and .story_id != null' "voice session should finalize into a story"
|
||||
echo "$voice_finalize_json" | jq '{session_id,status,story_id,generation_job_id}'
|
||||
|
||||
voice_story_json="$(get_json "$APP_URL/api/generations/$voice_story_id")"
|
||||
assert_jq "$voice_story_json" '.mode == "generated" and .generation_status != "failed" and .text_status == "ready"' "voice finalized story should be readable"
|
||||
echo "$voice_story_json" | jq '{id,title,mode,generation_status,text_status,image_status,audio_status,retryable_assets}'
|
||||
else
|
||||
say "Skipping voice co-creation smoke; set SMOKE_VOICE=1 to include Voice Studio Alpha"
|
||||
fi
|
||||
|
||||
say "Generating storybook without images"
|
||||
storybook_json="$(post_json "$APP_URL/api/generations" '{
|
||||
"output_mode": "storybook",
|
||||
|
||||
Reference in New Issue
Block a user