myagent-ai 1.15.98 → 1.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/web/tts_handler.py +32 -20
- package/web/ui/chat/chat.css +2 -0
- package/web/ui/chat/chat.js +30 -1
- package/web/ui/chat/chat_container.html +1 -1
package/package.json
CHANGED
package/web/tts_handler.py
CHANGED
|
@@ -152,28 +152,40 @@ async def synthesize(
|
|
|
152
152
|
all_audio += cache_path.read_bytes()
|
|
153
153
|
continue
|
|
154
154
|
|
|
155
|
-
# 调用 edge-tts
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
audio_data = b""
|
|
159
|
-
async for chunk_data in communicate.stream():
|
|
160
|
-
if chunk_data["type"] == "audio":
|
|
161
|
-
audio_data += chunk_data["data"]
|
|
162
|
-
|
|
163
|
-
if not audio_data:
|
|
164
|
-
logger.warning(f"TTS 块 {i} 生成空音频")
|
|
165
|
-
continue
|
|
166
|
-
|
|
167
|
-
# 写入缓存
|
|
155
|
+
# 调用 edge-tts(最多重试 2 次)
|
|
156
|
+
max_retries = 2
|
|
157
|
+
for attempt in range(max_retries):
|
|
168
158
|
try:
|
|
169
|
-
|
|
159
|
+
communicate = edge_tts.Communicate(chunk, voice, rate=speed)
|
|
160
|
+
audio_data = b""
|
|
161
|
+
async for chunk_data in communicate.stream():
|
|
162
|
+
if chunk_data["type"] == "audio":
|
|
163
|
+
audio_data += chunk_data["data"]
|
|
164
|
+
|
|
165
|
+
if not audio_data:
|
|
166
|
+
logger.warning(f"TTS 块 {i} 生成空音频 (重试 {attempt + 1}/{max_retries})")
|
|
167
|
+
if attempt < max_retries - 1:
|
|
168
|
+
await asyncio.sleep(0.5)
|
|
169
|
+
continue
|
|
170
|
+
else:
|
|
171
|
+
break
|
|
172
|
+
|
|
173
|
+
# 写入缓存
|
|
174
|
+
try:
|
|
175
|
+
cache_path.write_bytes(audio_data)
|
|
176
|
+
except Exception as e:
|
|
177
|
+
logger.debug(f"TTS 缓存写入失败: {e}")
|
|
178
|
+
|
|
179
|
+
all_audio += audio_data
|
|
180
|
+
break
|
|
170
181
|
except Exception as e:
|
|
171
|
-
logger.
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
182
|
+
logger.warning(f"TTS 合成失败 (块 {i}, 重试 {attempt + 1}/{max_retries}): {e}")
|
|
183
|
+
if attempt < max_retries - 1:
|
|
184
|
+
await asyncio.sleep(0.5)
|
|
185
|
+
else:
|
|
186
|
+
logger.error(f"TTS 合成最终失败 (块 {i}): {e}")
|
|
187
|
+
# 不 raise,跳过这个块继续合成后面的
|
|
188
|
+
break
|
|
177
189
|
|
|
178
190
|
if not all_audio:
|
|
179
191
|
raise RuntimeError("语音合成结果为空")
|
package/web/ui/chat/chat.css
CHANGED
|
@@ -2145,12 +2145,14 @@ body.popout-mode #popoutBtn{display:none !important}
|
|
|
2145
2145
|
/* ── Input Area ── */
|
|
2146
2146
|
.input-area{
|
|
2147
2147
|
padding:10px 12px;
|
|
2148
|
+
padding-bottom: max(10px, env(safe-area-inset-bottom));
|
|
2148
2149
|
}
|
|
2149
2150
|
.input-wrapper{
|
|
2150
2151
|
max-width:100%;
|
|
2151
2152
|
}
|
|
2152
2153
|
.input-box textarea{
|
|
2153
2154
|
min-height:60px;
|
|
2155
|
+
max-height:120px;
|
|
2154
2156
|
}
|
|
2155
2157
|
|
|
2156
2158
|
/* ── Modals ── */
|
package/web/ui/chat/chat.js
CHANGED
|
@@ -11,7 +11,10 @@
|
|
|
11
11
|
];
|
|
12
12
|
var idx = 0;
|
|
13
13
|
function loadNext() {
|
|
14
|
-
if (idx >= scripts.length)
|
|
14
|
+
if (idx >= scripts.length) {
|
|
15
|
+
onAllScriptsLoaded();
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
15
18
|
var s = document.createElement('script');
|
|
16
19
|
s.src = base + scripts[idx] + v;
|
|
17
20
|
s.onload = function() { idx++; loadNext(); };
|
|
@@ -20,3 +23,29 @@
|
|
|
20
23
|
}
|
|
21
24
|
loadNext();
|
|
22
25
|
})();
|
|
26
|
+
|
|
27
|
+
// ── Mobile keyboard / visualViewport handling ──
|
|
28
|
+
function onAllScriptsLoaded() {
|
|
29
|
+
if (!window.visualViewport) return;
|
|
30
|
+
|
|
31
|
+
var inputArea = document.getElementById('inputBox');
|
|
32
|
+
if (!inputArea) return;
|
|
33
|
+
|
|
34
|
+
var vv = window.visualViewport;
|
|
35
|
+
|
|
36
|
+
// When the virtual keyboard appears (viewport shrinks), the input area
|
|
37
|
+
// needs extra bottom padding so the send button stays above the keyboard.
|
|
38
|
+
function onViewportResize() {
|
|
39
|
+
var diff = window.innerHeight - vv.height;
|
|
40
|
+
if (diff > 100) {
|
|
41
|
+
// Keyboard is open — add padding equal to keyboard height
|
|
42
|
+
inputArea.style.marginBottom = diff + 'px';
|
|
43
|
+
} else {
|
|
44
|
+
// Keyboard is closed
|
|
45
|
+
inputArea.style.marginBottom = '0px';
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
vv.addEventListener('resize', onViewportResize);
|
|
50
|
+
vv.addEventListener('scroll', onViewportResize);
|
|
51
|
+
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
<html lang="zh-CN">
|
|
3
3
|
<head>
|
|
4
4
|
<meta charset="UTF-8">
|
|
5
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
|
|
6
6
|
<title>MyAgent - AI 助手</title>
|
|
7
7
|
<link rel="stylesheet" href="chat.css?v=7">
|
|
8
8
|
</head>
|