Intègre un chat IA capable de manipuler la scène via les mêmes fonctions que l'éditeur manuel (objets, variables, déclencheurs, images générées), avec conversations multiples par écran façon Claude. Corrige au passage le rafraîchissement pjax hors-ordre, l'onglet IA/déclencheurs vide après sélection d'un objet, la comparaison de booléens dans les conditions, et le blocage du glisser-déposer hors du cadre caméra après un redimensionnement de fond par l'IA. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
86 lines
4.0 KiB
Python
86 lines
4.0 KiB
Python
from flask import g, jsonify, request
|
|
|
|
import ai
|
|
import screens
|
|
|
|
from core.flask_app import app
|
|
|
|
_CONVERSATION_NOT_FOUND = {"error": "conversation introuvable"}
|
|
|
|
|
|
def _get_owned_conversation(slug, conversation_id):
|
|
"""La portée par SLUG (db.connect(slug), voir screens/ia/) suffit
|
|
déjà à isoler les conversations d'un jeu à l'autre — un id d'une
|
|
autre base n'existe simplement pas ici, même patron que
|
|
screens.get_scene_object. Renvoie None si absente."""
|
|
return screens.get_ia_conversation(slug, conversation_id)
|
|
|
|
|
|
@app.route("/game/<slug>/screens/<int:screen_id>/ia-conversations", methods=["GET"])
|
|
def ia_conversations_list(slug, screen_id):
|
|
"""Colonne de gauche de l'onglet "Générer avec l'IA" — toutes les
|
|
conversations de cet écran, plus récente en premier."""
|
|
return jsonify(screens.list_ia_conversations(slug, screen_id))
|
|
|
|
|
|
@app.route("/game/<slug>/screens/<int:screen_id>/ia-conversations", methods=["POST"])
|
|
def ia_conversations_create(slug, screen_id):
|
|
""""+ Nouvelle conversation" — créée immédiatement, vide."""
|
|
conversation_id = screens.create_ia_conversation(slug, screen_id)
|
|
conversation = screens.get_ia_conversation(slug, conversation_id)
|
|
return jsonify(conversation)
|
|
|
|
|
|
@app.route("/game/<slug>/ia-conversations/<int:conversation_id>", methods=["DELETE"])
|
|
def ia_conversation_delete(slug, conversation_id):
|
|
if not _get_owned_conversation(slug, conversation_id):
|
|
return jsonify(_CONVERSATION_NOT_FOUND), 404
|
|
screens.delete_ia_conversation(slug, conversation_id)
|
|
return jsonify({"ok": True})
|
|
|
|
|
|
@app.route("/game/<slug>/ia-conversations/<int:conversation_id>/messages", methods=["GET"])
|
|
def ia_conversation_messages(slug, conversation_id):
|
|
"""Historique complet d'UNE conversation — chargé par
|
|
static/js/ia/ia-chat.js à sa sélection dans la colonne."""
|
|
if not _get_owned_conversation(slug, conversation_id):
|
|
return jsonify(_CONVERSATION_NOT_FOUND), 404
|
|
return jsonify(screens.list_ia_chat_messages(slug, conversation_id))
|
|
|
|
|
|
@app.route("/game/<slug>/ia-conversations/<int:conversation_id>/messages", methods=["POST"])
|
|
def ia_conversation_send(slug, conversation_id):
|
|
"""Envoie un message dans une conversation — body {message}. Persiste
|
|
le message du créateur et la réponse, renvoie les deux.
|
|
|
|
ai.run_chat_turn lit l'historique déjà persisté et y ajoute le
|
|
message courant EN MÉMOIRE seulement — persisté ici, APRÈS l'appel,
|
|
jamais avant (sinon il apparaîtrait deux fois dans l'historique que
|
|
la boucle envoie à Claude)."""
|
|
conversation = _get_owned_conversation(slug, conversation_id)
|
|
if not conversation:
|
|
return jsonify(_CONVERSATION_NOT_FOUND), 404
|
|
|
|
message = (request.get_json(silent=True) or {}).get("message", "")
|
|
message = message.strip() if isinstance(message, str) else ""
|
|
if not message:
|
|
return jsonify({"error": "message vide"}), 400
|
|
|
|
try:
|
|
reply = ai.run_chat_turn(slug, conversation["screen_id"], conversation_id, g.current_user["id"], message)
|
|
except (ai.AnthropicNotConfiguredError, ai.ScenarioNotConfiguredError, ai.ScenarioGenerationError) as e:
|
|
reply = f"Configuration IA incomplète : {e}"
|
|
except Exception:
|
|
# Jamais le détail brut d'une erreur inattendue au créateur (même
|
|
# politique que auth/send_email.py) — journalisée côté serveur
|
|
# par le logger par défaut de Flask (DEBUG/erreur non interceptée).
|
|
app.logger.exception("Erreur inattendue dans ai.run_chat_turn (%s, conversation %s)", slug, conversation_id)
|
|
reply = "Une erreur inattendue est survenue — réessaie dans un instant."
|
|
|
|
user_message_id = screens.add_ia_chat_message(slug, conversation_id, "user", message)
|
|
assistant_message_id = screens.add_ia_chat_message(slug, conversation_id, "assistant", reply)
|
|
return jsonify({
|
|
"user_message": {"id": user_message_id, "role": "user", "content": message},
|
|
"assistant_message": {"id": assistant_message_id, "role": "assistant", "content": reply},
|
|
})
|