75 lines
2.6 KiB
Python
75 lines
2.6 KiB
Python
|
|
"""Long-term memory page — list facts, add new ones, search, forget."""
|
||
|
|
|
||
|
|
import flet as ft
|
||
|
|
|
||
|
|
from gui import services as svc
|
||
|
|
|
||
|
|
|
||
|
|
def build(page: ft.Page) -> ft.Control:
|
||
|
|
key_input = ft.TextField(label="Ключ", expand=True)
|
||
|
|
val_input = ft.TextField(label="Значение", expand=True)
|
||
|
|
search_input = ft.TextField(label="Поиск", expand=True)
|
||
|
|
|
||
|
|
list_view = ft.Column(spacing=6, expand=True, scroll=ft.ScrollMode.AUTO)
|
||
|
|
|
||
|
|
def render(query: str = ""):
|
||
|
|
list_view.controls.clear()
|
||
|
|
facts = svc.memory_search(query, limit=100) if query.strip() else svc.memory_all()
|
||
|
|
if not facts:
|
||
|
|
list_view.controls.append(ft.Text("Нет фактов. Скажи «Запомни что моя любимая еда — суши».",
|
||
|
|
color="#8aa0a8"))
|
||
|
|
for f in sorted(facts, key=lambda x: x.get("key", "")):
|
||
|
|
list_view.controls.append(_fact_row(f, on_forget=lambda k=f["key"]: do_forget(k)))
|
||
|
|
page.update()
|
||
|
|
|
||
|
|
def do_add(_):
|
||
|
|
k = key_input.value.strip()
|
||
|
|
v = val_input.value.strip()
|
||
|
|
if not k or not v:
|
||
|
|
return
|
||
|
|
svc.memory_remember(k, v)
|
||
|
|
key_input.value = ""
|
||
|
|
val_input.value = ""
|
||
|
|
render(search_input.value or "")
|
||
|
|
|
||
|
|
def do_forget(k: str):
|
||
|
|
svc.memory_forget(k)
|
||
|
|
render(search_input.value or "")
|
||
|
|
|
||
|
|
search_input.on_change = lambda e: render(e.control.value)
|
||
|
|
render()
|
||
|
|
|
||
|
|
return ft.Column(
|
||
|
|
[
|
||
|
|
ft.Text("Долговременная память", size=24, weight=ft.FontWeight.W_700),
|
||
|
|
ft.Text(
|
||
|
|
"Ключ-значение, которые Jarvis передаёт LLM как контекст пользователя.",
|
||
|
|
color="#8aa0a8", size=12,
|
||
|
|
),
|
||
|
|
ft.Row([key_input, val_input, ft.FilledButton(text="Добавить", on_click=do_add)]),
|
||
|
|
search_input,
|
||
|
|
list_view,
|
||
|
|
],
|
||
|
|
spacing=10,
|
||
|
|
expand=True,
|
||
|
|
)
|
||
|
|
|
||
|
|
|
||
|
|
def _fact_row(f: dict, on_forget) -> ft.Control:
|
||
|
|
return ft.Container(
|
||
|
|
content=ft.Row([
|
||
|
|
ft.Column([
|
||
|
|
ft.Text(f.get("key", ""), weight=ft.FontWeight.W_600, size=13),
|
||
|
|
ft.Text(f.get("value", ""), size=12, color="#a8b8c0"),
|
||
|
|
], spacing=2, expand=True),
|
||
|
|
ft.IconButton(
|
||
|
|
icon=ft.Icons.DELETE_FOREVER,
|
||
|
|
tooltip="Забыть",
|
||
|
|
on_click=lambda e: on_forget(),
|
||
|
|
),
|
||
|
|
]),
|
||
|
|
bgcolor="#15252b",
|
||
|
|
border_radius=8,
|
||
|
|
padding=ft.padding.symmetric(horizontal=12, vertical=8),
|
||
|
|
)
|