doc: документ прогресса и план рефакторинга архитектуры
This commit is contained in:
@@ -131,6 +131,89 @@ def register(app):
|
||||
"llm_success": llm_success,
|
||||
})
|
||||
|
||||
@app.route("/api/v1/chat", methods=["POST"])
|
||||
def chat():
|
||||
"""Свободный вопрос к LLM (без ELM)."""
|
||||
from flask import request, jsonify
|
||||
from elmer.config import load
|
||||
from elmer.diagnose import Diagnoser
|
||||
|
||||
data = request.get_json(silent=True)
|
||||
if not data or "question" not in data:
|
||||
return jsonify({"error": "missing 'question'"}), 400
|
||||
|
||||
question = data["question"].strip()
|
||||
if not question:
|
||||
return jsonify({"answer": "Пустой вопрос."})
|
||||
|
||||
# История диалога
|
||||
history = data.get("history", [])
|
||||
history_text = ""
|
||||
if history:
|
||||
history_text = "## История диалога\n"
|
||||
for m in history[-10:]: # последние 10 сообщений
|
||||
role = "Водитель" if m.get("role") == "user" else "Автоэксперт"
|
||||
history_text += f"{role}: {m.get('content', '')}\n"
|
||||
history_text += "\n"
|
||||
|
||||
cfg = load()
|
||||
api_key = cfg["llm"]["api_key"]
|
||||
if not api_key:
|
||||
return jsonify({"answer": "LLM не настроен."})
|
||||
|
||||
prompt = (
|
||||
f"{history_text}"
|
||||
f"Ты — автоэксперт. Помни контекст диалога выше. "
|
||||
f"Отвечай КРАТКО, не более 20 строк. Без воды, только по делу.\n\n"
|
||||
f"Вопрос: {question}"
|
||||
)
|
||||
|
||||
try:
|
||||
diagnoser = Diagnoser(
|
||||
api_key=api_key,
|
||||
model=cfg["llm"].get("model", "gpt-oss-120b"),
|
||||
base_url=cfg["llm"].get("base_url", "https://api.aillm.ru/v1"),
|
||||
)
|
||||
answer = diagnoser.diagnose(
|
||||
"Ты — лаконичный автоэксперт. Помни контекст диалога. Отвечай кратко, максимум 20 строк.",
|
||||
prompt,
|
||||
)
|
||||
except Exception as e:
|
||||
answer = f"LLM недоступен: {e}"
|
||||
|
||||
return jsonify({"answer": answer})
|
||||
|
||||
@app.route("/api/v1/ping", methods=["GET"])
|
||||
def ping():
|
||||
"""Быстрая проверка доступности сервера."""
|
||||
return {"ok": True}
|
||||
|
||||
@app.route("/api/v1/ping-llm", methods=["GET"])
|
||||
def ping_llm():
|
||||
"""Быстрая проверка доступности LLM."""
|
||||
from flask import jsonify
|
||||
from elmer.config import load
|
||||
from elmer.diagnose import Diagnoser
|
||||
|
||||
cfg = load()
|
||||
api_key = cfg["llm"]["api_key"]
|
||||
if not api_key:
|
||||
return jsonify({"ok": False, "error": "no API key"})
|
||||
|
||||
t0 = time.time()
|
||||
try:
|
||||
diagnoser = Diagnoser(
|
||||
api_key=api_key,
|
||||
model=cfg["llm"].get("model", "gpt-oss-120b"),
|
||||
base_url=cfg["llm"].get("base_url", "https://api.aillm.ru/v1"),
|
||||
)
|
||||
diagnoser.diagnose("Отвечай одним словом.", "OK")
|
||||
ms = int((time.time() - t0) * 1000)
|
||||
return jsonify({"ok": True, "ms": ms})
|
||||
except Exception as e:
|
||||
ms = int((time.time() - t0) * 1000)
|
||||
return jsonify({"ok": False, "ms": ms, "error": str(e)[:100]})
|
||||
|
||||
|
||||
def _summary(p: dict) -> dict:
|
||||
return {
|
||||
|
||||
@@ -12,14 +12,14 @@
|
||||
<div class="container">
|
||||
<h1>🔧 elmAI</h1>
|
||||
<p class="subtitle">Диагностика авто через ELM327 + ИИ</p>
|
||||
<p class="subtitle" style="font-size:12px;opacity:0.7;">v0.18.0-dev — 28 мая 2026</p>
|
||||
<p class="subtitle" style="font-size:12px;opacity:0.7;">v0.27.0-dev — 29 мая 2026</p>
|
||||
|
||||
<div class="card" style="text-align:center;margin-bottom:20px;">
|
||||
<p style="margin:0 0 10px 0;">📱 Скачай приложение на телефон:</p>
|
||||
<a href="/static/app-debug.apk" style="color:#ff6b35;font-size:18px;font-weight:bold;text-decoration:none;">
|
||||
⬇️ Скачать elmAI APK
|
||||
</a>
|
||||
<p style="font-size:11px;opacity:0.6;margin:4px 0 0 0;">v0.18.0-dev • нажмите чтобы скачать</p>
|
||||
<p style="font-size:11px;opacity:0.6;margin:4px 0 0 0;">v0.27.0-dev • нажмите чтобы скачать</p>
|
||||
</div>
|
||||
|
||||
<!-- Кнопка десктоп-диагностики скрыта — только для разработчика с прямым ELM327 -->
|
||||
|
||||
Reference in New Issue
Block a user