74 lines
2.6 KiB
Python
74 lines
2.6 KiB
Python
"""Handler for ``manual_edit`` events (T25, §6.4 final paragraph).
|
|
|
|
A ``manual_edit`` event captures a user override of a projected field — its
|
|
payload snapshots both the prior value and the new value so any edit can
|
|
be reversed by emitting an inverse ``manual_edit`` later. This module
|
|
applies the new value to the appropriate target table; the snapshot of
|
|
``prior_value`` is taken by the route handler before this fires.
|
|
|
|
Phase 1 covers three target kinds:
|
|
- ``edge_affinity`` and ``edge_trust`` — slider edits on a specific edge,
|
|
clamped to 0..100.
|
|
- ``memory_significance`` — dropdown edit, clamped to 0..3.
|
|
- ``memory_pov_summary`` — textarea edit (string).
|
|
|
|
Other §6.4 editable fields (activity verb / attention / posture, edge
|
|
summary, knowledge_facts list manipulation) are deferred to Phase 1.5.
|
|
|
|
Pin toggles intentionally use the existing ``memory_pin_changed`` event
|
|
(registered in :mod:`chat.state.memory`) rather than ``manual_edit`` so
|
|
the projection writes both ``pinned`` and ``auto_pinned`` atomically.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from sqlite3 import Connection
|
|
|
|
from chat.eventlog.log import Event
|
|
from chat.eventlog.projector import on
|
|
|
|
|
|
def _clamp(value: int, lo: int, hi: int) -> int:
|
|
return max(lo, min(hi, value))
|
|
|
|
|
|
@on("manual_edit")
|
|
def _apply_manual_edit(conn: Connection, e: Event) -> None:
|
|
p = e.payload
|
|
kind = p["target_kind"]
|
|
target_id = p["target_id"]
|
|
new_value = p["new_value"]
|
|
|
|
if kind == "edge_affinity":
|
|
conn.execute(
|
|
"UPDATE edges SET affinity = ? "
|
|
"WHERE source_id = ? AND target_id = ?",
|
|
(
|
|
_clamp(int(new_value), 0, 100),
|
|
target_id["source_id"],
|
|
target_id["target_id"],
|
|
),
|
|
)
|
|
elif kind == "edge_trust":
|
|
conn.execute(
|
|
"UPDATE edges SET trust = ? "
|
|
"WHERE source_id = ? AND target_id = ?",
|
|
(
|
|
_clamp(int(new_value), 0, 100),
|
|
target_id["source_id"],
|
|
target_id["target_id"],
|
|
),
|
|
)
|
|
elif kind == "memory_significance":
|
|
conn.execute(
|
|
"UPDATE memories SET significance = ? WHERE id = ?",
|
|
(_clamp(int(new_value), 0, 3), int(target_id)),
|
|
)
|
|
elif kind == "memory_pov_summary":
|
|
conn.execute(
|
|
"UPDATE memories SET pov_summary = ? WHERE id = ?",
|
|
(str(new_value), int(target_id)),
|
|
)
|
|
# Unknown target_kind: silently no-op for v1. Future kinds (activity
|
|
# fields, edge summary, knowledge_facts) extend the dispatch above.
|