Spaces:
Sleeping
Sleeping
File size: 7,111 Bytes
79df050 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 | def test_typewriter_avoids_interval_and_full_markdown_rerender_per_tick():
source = open("static/frontend/js/ui.js", encoding="utf-8").read()
start = source.index("function typewriterEffect")
block = source[start:source.index("const agentProgressSteps")]
assert "setInterval(" not in block
assert "requestAnimationFrame(" in block
assert "renderAgentMarkdown(text.slice(0, index))" not in block
assert "typewriterTextNode" in source
assert "typewriterFrameId" in source
assert "setTypewriterContent" in source
def test_streaming_output_skips_redundant_full_repaint_when_text_unchanged():
source = open("static/frontend/js/ui.js", encoding="utf-8").read()
assert "let lastRenderedAgentText = '';" in source
assert "if (lastRenderedAgentText === nextText)" in source
assert "lastRenderedAgentText = nextText;" in source
def test_final_typewriter_waits_for_speech_completion_before_idle():
ui_source = open("static/frontend/js/ui.js", encoding="utf-8").read()
tts_source = open("static/frontend/js/tts.js", encoding="utf-8").read()
assert "const awaitSpeechCompletion = options.awaitSpeechCompletion === true || !!enableTTS;" in ui_source
assert "window.agentOutputAwaitingSpeechCompletion = awaitSpeechCompletion;" in ui_source
assert "if (window.agentOutputAwaitingSpeechCompletion) {" in ui_source
assert "function maybeFinalizeSpeechPlayback()" in tts_source
assert "window.agentOutputAwaitingSpeechCompletion = false;" in tts_source
assert "maybeFinalizeSpeechPlayback();" in tts_source
def test_progress_updates_do_not_override_active_answer_stream():
ui_source = open("static/frontend/js/ui.js", encoding="utf-8").read()
ws_source = open("static/frontend/js/websocket.js", encoding="utf-8").read()
assert "window.agentOutputHasAnswerStream = false;" in ui_source
assert "if (options.progress === true && window.agentOutputHasAnswerStream) {" in ui_source
assert "window.agentOutputHasAnswerStream = true;" in ui_source
assert "if (typeof currentState !== 'undefined' && currentState === 'speaking') {" in ws_source
assert "setState('speaking');" in ws_source
def test_stt_idle_does_not_reset_agent_while_speaking():
ws_source = open("static/frontend/js/websocket.js", encoding="utf-8").read()
assert "else if (data.status === 'idle' || data.status === 'error') {" in ws_source
assert "if (typeof currentState !== 'undefined' && currentState === 'speaking') {" in ws_source
assert "resetAgent();" in ws_source
def test_final_output_can_wait_for_streaming_speech_completion_without_full_tts():
ui_source = open("static/frontend/js/ui.js", encoding="utf-8").read()
tts_source = open("static/frontend/js/tts.js", encoding="utf-8").read()
ws_source = open("static/frontend/js/websocket.js", encoding="utf-8").read()
assert "const awaitSpeechCompletion = options.awaitSpeechCompletion === true || !!enableTTS;" in ui_source
assert "function hasPendingStreamingSpeech()" in tts_source
assert "|| !!ttsStreamSocket || _ttsActiveSources.length > 0" in tts_source
assert "hasPendingStreamingSpeech() || useFullTtsFallback" in ws_source
assert "finishAgentOutput(data.message, useFullTtsFallback, {" in ws_source
def test_tts_debug_logging_and_stop_reason_contracts_exist():
tts_source = open("static/frontend/js/tts.js", encoding="utf-8").read()
agent_source = open("static/frontend/js/agent.js", encoding="utf-8").read()
assert "function logTtsDebug(event, extra = {})" in tts_source
assert "if (!window.DEBUG_MODE) {" in tts_source
assert "logTtsDebug('socket_close'" in tts_source
assert "function stopSpeaking(clearPending = true, reason = 'unspecified')" in tts_source
assert "stopSpeaking(true, 'state_idle');" in agent_source
assert "stopSpeaking(true, 'reset_agent');" in agent_source
def test_complete_typewriter_refuses_idle_while_streaming_speech_still_pending():
ui_source = open("static/frontend/js/ui.js", encoding="utf-8").read()
assert "if (typeof hasPendingStreamingSpeech === 'function' && hasPendingStreamingSpeech()) {" in ui_source
assert "window.agentOutputAwaitingSpeechCompletion = true;" in ui_source
def test_tool_cards_container_is_an_interactive_fixed_overlay():
source = open("static/frontend/index.html", encoding="utf-8").read()
assert "#tool-cards-container {" in source
assert "position: fixed;" in source
assert "pointer-events: none;" in source
assert "#tool-cards-container .voice-tool-card {" in source
assert "pointer-events: auto;" in source
def test_tool_card_visual_dividers_and_scrollbar_are_refined():
source = open("static/frontend/index.html", encoding="utf-8").read()
assert "border: 1px solid rgba(15, 23, 42, 0.06);" in source
assert "border-bottom: 1px solid rgba(15, 23, 42, 0.05);" in source
assert ".tool-drawer-content::-webkit-scrollbar {" in source
assert "width: 3px;" in source
assert "background: rgba(15, 23, 42, 0.12);" in source
def test_speaking_petals_reuse_idle_rotation_and_layer_interleave():
source = open("static/frontend/index.html", encoding="utf-8").read()
assert ".voice-mic-container.speaking .bloom-petal-group.upper .bloom-petal:nth-child(1)" in source
assert "animation: petalBloom 1.6s ease-in-out infinite 0s;" in source
assert ".voice-mic-container.speaking .bloom-petal-group.lower .bloom-petal:nth-child(1)" in source
assert "animation: petalBloomInner 1.6s ease-in-out infinite 0.1s;" in source
assert "--speaking-angle" not in source
assert "speakingPetalFloat" not in source
assert "speakingPetalFloatInner" not in source
def test_websocket_updates_conversation_language_from_bot_messages():
ws_source = open("static/frontend/js/websocket.js", encoding="utf-8").read()
assert "if (data.language) {" in ws_source
assert "window.currentConversationLanguage = data.language;" in ws_source
assert "window.currentSpeechLanguage = data.language;" in ws_source
def test_new_thinking_cycle_clears_stale_tts_language_before_next_stream():
ws_source = open("static/frontend/js/websocket.js", encoding="utf-8").read()
assert "window.currentConversationLanguage = null;" in ws_source
assert "window.currentSpeechLanguage = null;" in ws_source
def test_bot_delta_carries_language_for_streaming_tts_switch():
source = open("app.py", encoding="utf-8").read()
assert "\"language\": _preferred_language_from_text(stream_accumulator[\"text\"]) or resolved_language" in source
def test_frontend_preloads_conversation_language_on_initial_input():
ws_source = open("static/frontend/js/websocket.js", encoding="utf-8").read()
assert "function inferConversationLanguage(text, fallback = null)" in ws_source
assert "const inferredLanguage = window.inferConversationLanguage(text, navigator.language || 'zh-TW');" in ws_source
assert "window.currentConversationLanguage = inferredLanguage;" in ws_source
assert "window.currentSpeechLanguage = inferredLanguage;" in ws_source
|