mirror of
https://github.com/R0m1k3/Loki.git
synced 2026-10-22 22:48:11 +02:00
Mémoire en notes Markdown + presets de configuration (repris d'AJEAN)
Les deux dernières idées d'AJEAN (github.com/nathaninline/jean). 1. Mémoire en notes Markdown ($DATA_DIR/MEMORY), écrites par l'agent via deux outils (memory_search / memory_save). Trois modes : off, ondemand (défaut) et always. Face au RAG vectoriel : aucun modèle d'embedding requis, notes lisibles et éditables à la main, et rien de mémorisé à l'insu — la recherche par mots-clés ne rappelle que du pertinent, là où le RAG ressortait une demande sans rapport. Le RAG disparaît de l'UI : un seul concept de mémoire. En mode Plan, seule la consultation est proposée, pas l'écriture. 2. Presets : jeux de réglages nommés, enregistrés et rappelés en un clic (sélecteur + « + Preset » dans l'en-tête des Réglages). Au passage, un vrai bug : ConfigPatch ne déclarait ni keep_alive, ni skills_enabled, ni ponytail — Pydantic ignore les champs non déclarés, donc ces trois réglages ne se sauvegardaient JAMAIS. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SVay7z3y7q2gEe54ByAE6N
This commit is contained in:
7 files changed
+463
-5
No files matched your search
@@ -331,6 +331,30 @@ def edit_file(path: str, search: str, replace: str) -> dict:
|
||||
return result
|
||||
|
||||
|
||||
def memory_search(query: str) -> dict:
|
||||
"""Cherche dans les notes que l'agent a lui-même enregistrées."""
|
||||
from . import memory_notes
|
||||
|
||||
hits = memory_notes.search_notes(query, limit=3)
|
||||
if not hits:
|
||||
return {"ok": True, "notes": [], "summary": "aucune note correspondante"}
|
||||
return {
|
||||
"ok": True,
|
||||
"notes": hits,
|
||||
"summary": f"{len(hits)} note(s) trouvée(s)",
|
||||
}
|
||||
|
||||
|
||||
def memory_save(title: str, content: str) -> dict:
|
||||
"""Enregistre une note durable (préférence, décision, fait à retenir)."""
|
||||
from . import memory_notes
|
||||
|
||||
result = memory_notes.save_note(title, content)
|
||||
if not result["ok"]:
|
||||
raise ToolError(result["summary"])
|
||||
return result
|
||||
|
||||
|
||||
_GREP_SKIP_DIRS = {".git", "node_modules", "__pycache__", ".venv", "dist"}
|
||||
_MAX_GREP_MATCHES = 50
|
||||
|
||||
@@ -645,6 +669,8 @@ TOOL_IMPL = {
|
||||
"web_search": web_search,
|
||||
"run_shell": run_shell,
|
||||
"run_check": run_check,
|
||||
"memory_search": memory_search,
|
||||
"memory_save": memory_save,
|
||||
}
|
||||
|
||||
TOOL_DEFINITIONS = [
|
||||
@@ -823,6 +849,43 @@ TOOL_DEFINITIONS = [
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
"type": "function",
|
||||
"function": {
|
||||
"name": "memory_search",
|
||||
"description": (
|
||||
"Chercher dans tes notes durables (préférences de l'utilisateur, "
|
||||
"décisions, faits appris lors d'anciennes discussions)."
|
||||
),
|
||||
"parameters": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"query": {"type": "string", "description": "Ce que tu cherches"}
|
||||
},
|
||||
"required": ["query"],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
"type": "function",
|
||||
"function": {
|
||||
"name": "memory_save",
|
||||
"description": (
|
||||
"Enregistrer une note durable, réutilisable dans les prochaines "
|
||||
"discussions. À réserver aux informations stables et utiles "
|
||||
"(préférence, choix technique, contrainte). Jamais le détail "
|
||||
"d'une tâche en cours."
|
||||
),
|
||||
"parameters": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"title": {"type": "string", "description": "Titre court et parlant"},
|
||||
"content": {"type": "string", "description": "La note, concise"},
|
||||
},
|
||||
"required": ["title", "content"],
|
||||
},
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
|
||||
Reference in new issue
Block a user