Add voice dictation to chat panel and global stop generation button

This commit is contained in:
dimitrievgs 2026-05-23 00:59:56 +03:00
parent 867acd9443
commit b3edb45fab
3 changed files with 21 additions and 7 deletions

View File

@ -199,14 +199,15 @@ def get_available_models():
def send_user_message(): def send_user_message():
"""API endpoint для создания узла пользователя с вложениями.""" """API endpoint для создания узла пользователя с вложениями."""
data = request.get_json() data = request.get_json()
message = data.get("message") message = data.get("message", "")
graph_id = data.get("graph_id") graph_id = data.get("graph_id")
parent_node_id = data.get("parent_node_id") parent_node_id = data.get("parent_node_id")
attachments = data.get("attachments", []) attachments = data.get("attachments", [])
cache_folder = data.get("cache_folder") cache_folder = data.get("cache_folder")
if not message: # Блокируем только если нет и текста, и вложений
return jsonify({"error": "Сообщение не может быть пустым."}, 400) if not message and not attachments:
return jsonify({"error": "Сообщение или вложение не могут быть пустыми."}), 400
try: try:
result = graph_history_manager.create_user_node( result = graph_history_manager.create_user_node(
@ -387,8 +388,11 @@ obsidian_settings_fetched = False
@api.route('/api/voice/status', methods=['GET']) @api.route('/api/voice/status', methods=['GET'])
def get_voice_status(): def get_voice_status():
# 2. Вызываем метод у экземпляра voice_inst, а не у модуля # 2. Вызываем метод у экземпляра voice_inst, а не у модуля
pure_gm_text, session_id = voice_inst.get_pure_gm_text()
return jsonify({ return jsonify({
"transcription": voice_inst.get_context_by_limit(current_obsidian_settings.get('voiceDisplayLimit', 0), order='reversed'), "transcription": voice_inst.get_context_by_limit(current_obsidian_settings.get('voiceDisplayLimit', 0), order='reversed'),
"pure_gm_text": pure_gm_text,
"session_id": session_id,
"response1": list(voice_inst.responses["regular"]), "response1": list(voice_inst.responses["regular"]),
"response2": list(voice_inst.responses["commands"]), "response2": list(voice_inst.responses["commands"]),
"metrics": voice_inst.metrics_data, "metrics": voice_inst.metrics_data,

View File

@ -541,14 +541,17 @@ class GraphHistoryManager:
with self._get_connection() as conn: with self._get_connection() as conn:
try: try:
# Формируем заголовок для узла, учитывая вложения
display_label = message[:30] + "..." if len(message) > 30 else message
if not display_label and attachments:
display_label = "📎 Вложение"
node_data = { node_data = {
"label": "label": display_label,
message[:30] + "..." if len(message) > 30 else message,
"message": { "message": {
"role": "user", "role": "user",
"content": message, "content": message,
"node_id": user_node_id "node_id": user_node_id
# УДАЛЕНО: "attachments": attachments or []
} }
} }

View File

@ -381,4 +381,11 @@ class VoiceService:
print("✅ Аналитика (сдвоенные графики) обновлена.") print("✅ Аналитика (сдвоенные графики) обновлена.")
except Exception as e: except Exception as e:
print(f"❌ Ошибка генерации графиков: {e}") print(f"❌ Ошибка генерации графиков: {e}")
def get_pure_gm_text(self):
"""Возвращает идентификатор сессии и чистый склеенный текст GM."""
with self.history_lock:
session_id = os.path.basename(self.current_file) if self.current_file else "none"
gm_text = " ".join([item['text'] for item in self.history if item['role'] == 'GM'])
return gm_text, session_id