Server side implementation for interactive entry edits
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
from typing import List, Optional
|
||||
from typing import List, Optional, Callable, Set
|
||||
import xml.etree.ElementTree as ET
|
||||
|
||||
from .entry import Entry
|
||||
@@ -10,11 +10,34 @@ class WorkingMemory:
|
||||
The working memory stores different types of entries (scripts, reasoning, errors, etc.)
|
||||
and provides methods to add, remove, and update them. It also generates XML context
|
||||
representing the current state.
|
||||
|
||||
Notifies observers of entry additions, deletions and changes. During update(),
|
||||
changes are batched and a single notification is sent after completion.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
"""Initialize an empty working memory."""
|
||||
self._entries: List[Entry] = []
|
||||
self._change_handlers: List[Callable[[], None]] = []
|
||||
self._updating = False
|
||||
self._changed_during_update: Set[Entry] = set()
|
||||
|
||||
def add_change_handler(self, handler: Callable[[], None]) -> None:
|
||||
"""Add a callback for working memory changes."""
|
||||
if handler not in self._change_handlers:
|
||||
self._change_handlers.append(handler)
|
||||
|
||||
def _notify_change(self) -> None:
|
||||
"""Notify all handlers of working memory changes."""
|
||||
for handler in self._change_handlers:
|
||||
handler()
|
||||
|
||||
def _handle_entry_change(self, entry: Entry) -> None:
|
||||
"""Handle changes from individual entries."""
|
||||
if self._updating:
|
||||
self._changed_during_update.add(entry)
|
||||
else:
|
||||
self._notify_change()
|
||||
|
||||
def add_entry(self, entry: Entry) -> None:
|
||||
"""
|
||||
@@ -25,7 +48,9 @@ class WorkingMemory:
|
||||
"""
|
||||
if not isinstance(entry, Entry):
|
||||
raise TypeError("Entry must be an instance of Entry class")
|
||||
entry.add_change_handler(self._handle_entry_change)
|
||||
self._entries.append(entry)
|
||||
self._notify_change()
|
||||
|
||||
def remove_entry(self, id: str) -> None:
|
||||
"""
|
||||
@@ -39,6 +64,7 @@ class WorkingMemory:
|
||||
if entry is not None:
|
||||
entry.cleanup()
|
||||
self._entries = [e for e in self._entries if e.id != id]
|
||||
self._notify_change()
|
||||
|
||||
def clear(self) -> None:
|
||||
"""
|
||||
@@ -48,12 +74,11 @@ class WorkingMemory:
|
||||
for entry in self._entries:
|
||||
entry.cleanup()
|
||||
self._entries.clear()
|
||||
self._notify_change()
|
||||
|
||||
def __del__(self):
|
||||
"""
|
||||
Clean up all entries when memory is deleted.
|
||||
"""
|
||||
if hasattr(self, '_entries'): # Check in case of partial initialization
|
||||
"""Clean up all entries when memory is deleted."""
|
||||
if hasattr(self, '_entries'):
|
||||
self.clear()
|
||||
|
||||
def get_entry(self, id: str) -> Optional[Entry]:
|
||||
@@ -78,7 +103,7 @@ class WorkingMemory:
|
||||
Returns:
|
||||
List[Entry]: List of all entries
|
||||
"""
|
||||
return self._entries.copy() # Return a copy to prevent external modification
|
||||
return self._entries.copy()
|
||||
|
||||
def get_entries_count(self) -> int:
|
||||
"""
|
||||
@@ -88,24 +113,22 @@ class WorkingMemory:
|
||||
int: Number of entries in working memory
|
||||
"""
|
||||
return len(self._entries)
|
||||
|
||||
def get_entries_by_type(self, entry_type: type) -> List[Entry]:
|
||||
"""
|
||||
Get all entries of a specific type.
|
||||
|
||||
Args:
|
||||
entry_type: Type of entries to retrieve
|
||||
|
||||
Returns:
|
||||
List[Entry]: List of entries matching the specified type
|
||||
"""
|
||||
return [e for e in self._entries if isinstance(e, entry_type)]
|
||||
|
||||
def update(self) -> None:
|
||||
"""Update all entries in working memory."""
|
||||
"""
|
||||
Update all entries in working memory.
|
||||
Batches change notifications and sends single update after completion.
|
||||
"""
|
||||
self._updating = True
|
||||
self._changed_during_update.clear()
|
||||
|
||||
for entry in self._entries:
|
||||
entry.update()
|
||||
|
||||
self._updating = False
|
||||
if self._changed_during_update:
|
||||
self._notify_change()
|
||||
|
||||
def generate_context(self) -> List[ET.Element]:
|
||||
"""
|
||||
Generate XML Elements representing all entries.
|
||||
@@ -113,4 +136,4 @@ class WorkingMemory:
|
||||
Returns:
|
||||
List[ET.Element]: List of XML elements for each entry
|
||||
"""
|
||||
return [entry.generate_context() for entry in self._entries]
|
||||
return [entry.generate_context() for entry in self._entries]
|
||||
|
||||
Reference in New Issue
Block a user