- Le moteur n'envoie jamais l'historique (system + objectif courant seulement) : chaque run repartait de zéro. Nouveau service app/services/agent_memory.py — une ligne résumé par conversation (table agent_memory, migration 31), écrite en fin de run et ré-injectée au contexte du run suivant. - context_for() : bloc « ## Mémoire de la conversation », budget 4000 car. (troncature gauche + marqueur). remember() : 1 note/échange (180 → 700 car.), 20 notes max, upsert, erreurs journalisées — un run ne peut pas échouer à cause de la mémoire. Toggle OFF = ni lecture ni écriture. - Toggle « Mémoire » dans le menu + : entrée racine à l'état réel (🧠/💭 + libellé), PATCH /api/agent/conversations/{id} avec memory_enabled ajouté au whitelist, état lu à l'ouverture et à la création, défaut AGENT_MEMORY_DEFAULT (settings.agent_memory_default) + memory_enabled dans la réponse de création. - Décision : mémoire d'espace (lignes workspace_id NULL) remise — YAGNI, rien ne l'écrivait ; noté ponytail: dans le service avec le chemin de montée. - Tests : tests/test_v754_memory.py (8) dont 2 runs réels du moteur (FakeLLM capture le prompt : mémoire présente ON / absente OFF) ; test_v751 et test_v753 adaptés (2 sections « bientôt » restantes). Suite complète 1293 verts (-n auto, 2e run ; 1 échec intermittent sur test_v56_import URL au 1er run, vert isolé + vert au run suivant = flake préexistant), ruff 0, eslint 0 problème. OpenAPI 516 chemins / 7.54.0.
74 lines
3.1 KiB
Python
74 lines
3.1 KiB
Python
"""v7.53.0 — Menu + : Design System – Canevas (créer / insérer / enregistrer)."""
|
||
|
||
import json
|
||
from pathlib import Path
|
||
|
||
from app.db import get_conn
|
||
|
||
ROOT = Path(__file__).resolve().parent.parent
|
||
JS_PATH = ROOT / "static" / "js" / "agent_panel_2.js"
|
||
|
||
|
||
def test_canvases_list_includes_design_system(client):
|
||
tpl = {t["key"]: t for t in client.get("/board/api/page-templates").json()["templates"] if t.get("builtin")}
|
||
assert "design_system" in tpl
|
||
assert tpl["design_system"]["name"] == "Design System"
|
||
assert tpl["design_system"]["icon"] == "🎨"
|
||
|
||
|
||
def test_blocks_route_builtin(client):
|
||
r = client.get("/board/api/page-templates/0/blocks", params={"key": "design_system"})
|
||
assert r.status_code == 200, r.text
|
||
blocks = r.json()["blocks"]
|
||
assert isinstance(blocks, list) and blocks
|
||
assert blocks[0]["type"] == "heading_1" and blocks[0]["content"] == "Design System"
|
||
# les builtins sont livrés sans id : le front appelle ensureBlockIds()
|
||
assert "id" not in blocks[0]
|
||
|
||
assert client.get("/board/api/page-templates/0/blocks", params={"key": "nope"}).status_code == 404
|
||
empty = client.get("/board/api/page-templates/0/blocks", params={"key": "empty"})
|
||
assert empty.status_code == 200 and empty.json()["blocks"]
|
||
|
||
|
||
def test_blocks_route_user_template(client):
|
||
blocks = [{"type": "heading_1", "content": "Mon canevas"},
|
||
{"type": "paragraph", "content": "Contenu."}]
|
||
created = client.post("/board/api/page-templates", json={"name": "Mon canevas", "blocks": blocks})
|
||
assert created.status_code == 200, created.text
|
||
tid = created.json()["id"]
|
||
|
||
got = client.get(f"/board/api/page-templates/{tid}/blocks")
|
||
assert got.status_code == 200
|
||
assert [b["content"] for b in got.json()["blocks"]] == ["Mon canevas", "Contenu."]
|
||
|
||
assert client.get("/board/api/page-templates/999999/blocks").status_code == 404
|
||
|
||
|
||
def test_use_design_system_creates_page(client):
|
||
r = client.post("/board/api/page-templates/0/use", json={"key": "design_system"})
|
||
assert r.status_code == 200, r.text
|
||
page_id = r.json()["id"]
|
||
with get_conn() as conn:
|
||
row = conn.execute(
|
||
"SELECT content, content_format FROM pages WHERE id=?", (page_id,)
|
||
).fetchone()
|
||
assert row["content_format"] == "blocks"
|
||
blocks = json.loads(row["content"])
|
||
texts = [b.get("content", "") for b in blocks]
|
||
assert "Design System" in texts
|
||
# les ids sont assignés côté serveur (_ensure_block_ids)
|
||
assert all(b.get("id") for b in blocks)
|
||
|
||
|
||
def test_canvases_menu_wired(client):
|
||
src = JS_PATH.read_text(encoding="utf-8")
|
||
root = src.split("var FD_PLUS_MENU = [", 1)[1].split("];", 1)[0]
|
||
assert "action:'canvases'" in root
|
||
# phases 1-4 livrées → 2 sections « bientôt » restantes (connecteurs, plugins)
|
||
assert root.count("disabled:true") == 2
|
||
for action in ("'canvas'", "'canvas-create'", "'canvas-insert'", "'canvas-save'"):
|
||
assert action in src, action
|
||
# piège /use : la clé builtin part DANS LE BODY, pas en query string
|
||
assert "body: JSON.stringify(c.builtin ? {key: c.key} : {})" in src
|
||
assert "ensureBlockIds" in src
|