feat: thin App facade over ops/store

This commit is contained in:
lda
2026-09-01 01:51:43 +07:00 Verified
parent 07f650cafa
commit 497dbe5a00
3 changed files with 92 additions and 0 deletions
+4
View File
@@ -0,0 +1,4 @@
from .app import App
from .types import Agent, Message, Thread
__all__ = ["Agent", "Thread", "Message", "App"]
+63
View File
@@ -0,0 +1,63 @@
from __future__ import annotations
import uuid
from dataclasses import dataclass, field
from agentmsgs.stores.memory import InMemoryStore
from . import ops
from .store import Store
from .types import Agent, Thread
@dataclass
class App:
store: Store = field(default_factory=InMemoryStore)
def get_or_create_agent(self, name: str) -> Agent:
return ops.get_or_create_agent(self.store, name)
def create_agent(self, name: str) -> Agent:
return ops.create_agent(self.store, name)
def delete_account(self, id: uuid.UUID) -> None:
return ops.delete_agent(self.store, id)
def create_thread(self, *agents: Agent) -> Thread:
return ops.create_thread(self.store, set(agents))
def get_thread(self, id: uuid.UUID) -> Thread | None:
return self.store.get_thread(id)
def find_threads(self, *agents: Agent) -> list[Thread]:
return ops.find_threads(self.store, set(agents))
def find_thread(self, *agents: Agent) -> list[Thread]:
return self.find_threads(*agents)
def join_thread(self, tid: uuid.UUID, agent: Agent) -> Thread:
return ops.join_thread(self.store, tid, agent)
def leave_thread(self, tid: uuid.UUID, agent: Agent) -> Thread:
return ops.leave_thread(self.store, tid, agent)
def append(self, tid: uuid.UUID, sender: Agent, content: str):
return ops.append_message(self.store, tid, sender, content)
def poll(self, tid: uuid.UUID, agent: Agent, after_seq: int = 0):
return ops.list_messages(self.store, tid, after_seq)
def mark_read(self, tid: uuid.UUID, agent: Agent, seq: int) -> None:
return ops.mark_read(self.store, tid, agent, seq)
def has_unread(self, tid: uuid.UUID, agent: Agent, exclude_own: bool = False) -> bool:
return ops.has_unread(self.store, tid, agent, exclude_own)
# compat shims for old tests
def add_thread(self, *a: Agent) -> Thread:
return self.create_thread(*a)
def add_thread_2(self, thread: Thread):
if hasattr(self.store, "_threads"):
self.store._threads[thread.id] = thread # type: ignore[attr-defined]
return None
+25
View File
@@ -0,0 +1,25 @@
from agentmsgs.core.app import App
from agentmsgs.stores.memory import InMemoryStore
def test_app_facade_with_memory():
app = App(store=InMemoryStore())
alice = app.get_or_create_agent("Alice")
bob = app.get_or_create_agent("Bob")
t = app.create_thread(alice, bob)
app.append(t.id, alice, "hello")
assert app.has_unread(t.id, bob) is True
msgs = app.poll(t.id, bob)
assert len(msgs) == 1
app.mark_read(t.id, bob, msgs[0].seq)
assert app.has_unread(t.id, bob) is False
def test_app_delete_account():
from agentmsgs.core.app import App
from agentmsgs.stores.memory import InMemoryStore
app = App(store=InMemoryStore())
a = app.get_or_create_agent("A")
app.delete_account(a.id)
assert app.store.get_agent_by_id(a.id) is None