From b90769882992790d2f28c6d0a3f7f09626033980 Mon Sep 17 00:00:00 2001 From: Shivering Ocelot Date: Sat, 5 Jul 2025 05:51:03 -0500 Subject: [PATCH] Improve message schema, assign or create main agent chat automatically --- backend/app.py | 43 ++++++++++++++++++++++++++++++------------- backend/database.py | 34 +++++++++++++++------------------- backend/server.py | 3 ++- 3 files changed, 47 insertions(+), 33 deletions(-) diff --git a/backend/app.py b/backend/app.py index 286fa0e..3ecbce7 100644 --- a/backend/app.py +++ b/backend/app.py @@ -73,12 +73,22 @@ class App: user_connections[remotename] = [] user_connections[remotename].append(channel) - def create_agent(self, user_id, name, agentname, description, picture, kind, data): + def create_agent(self, user_id, name, agentname, description, picture, kind, data, main_chat_id=None): with self.sql_session() as session: + if main_chat_id is None: + chat = db.Chat() + chat.user_id = user_id + chat.name = name + + session.add(chat) + session.commit() + main_chat_id = chat.id + agent = db.Agent() agent.user_id = user_id agent.name = name agent.agentname = agentname + agent.main_chat_id = main_chat_id agent.description = description agent.picture = picture agent.kind = kind @@ -87,6 +97,13 @@ class App: session.add(agent) session.commit() print(f"Created agent #{agent.id}: {agent.name}") + + membership = db.Membership() + membership.chat_id = main_chat_id + membership.agent_id = agent.id + session.add(membership) + session.commit() + return agent.id def create_chat(self, user_id, name, description, picture, members=[]): @@ -368,22 +385,22 @@ class App: asyncio.create_task(control.received_message(message)) def generate_default_user_data(self, user_id): - agent_id = self.create_agent( - user_id=user_id, - name="Intro", - description="Introduces you to the application.", - picture=None, - kind="basic", # Should be 'intro' - data={} - ) - - # Create a chat with that agent in it chat_id = self.create_chat( user_id=user_id, name="Initial Chat", - description=None, + description="First user chat with Intro.", picture=None, - members=[agent_id], + members=[], + ) + agent_id = self.create_agent( + user_id=user_id, + name="Intro", + agentname="intro", + main_chat_id=chat_id, + description="Introduces you to the application.", + picture=None, + kind="conversation", # Should be 'intro' + data={} ) def create_chat_thread(self, chat_id, name=None): diff --git a/backend/database.py b/backend/database.py index 1c4daf8..7eb2acd 100644 --- a/backend/database.py +++ b/backend/database.py @@ -33,6 +33,7 @@ class Agent(Base): visibility: Mapped[int] = mapped_column(default=0) # Comma separated list of permission symbols permissions: Mapped[str] = mapped_column(default="") + main_chat_id: Mapped[int] = mapped_column(ForeignKey("chats.id")) name: Mapped[str] description: Mapped[Optional[str]] @@ -77,19 +78,27 @@ class Message(Base): id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True) chat_id: Mapped[int] = mapped_column(ForeignKey("chats.id")) + thread_id: Mapped[Optional[int]] = mapped_column(ForeignKey("threads.id")) # Timestamp of this message time: Mapped[int] - # Identifier of the sender: user / system / $AGENT_ID + # Identifier of the sender: user / system / user-$ID / agent-$ID sender: Mapped[str] - # Predefined set of message types, interpreted as 'text' when empty. + # Predefined set of message types: + # message, log, memory, file, note kind: Mapped[str] + # Each kind has a set of subkinds, and a default for empty values + # message: (empty) + # log: debug, info + # memory: (depends on the agent) + # file: (empty) + # note: public, private, pinned + subkind: Mapped[Optional[str]] + # For the kinds message, log and note, a format can be specified, + # empty defaults to 'text' and can also be 'markdown', 'csv' + format: Mapped[Optional[str]] content: Mapped[str] - # Tells whether this message continues in the chat after the session when it was sent. - persistent: Mapped[bool] = mapped_column(default=False) - - thread_id: Mapped[Optional[int]] = mapped_column(ForeignKey("threads.id")) # Represents a temporary topic or stage in a conversation class Thread(Base): @@ -118,16 +127,3 @@ class AgentResource(Base): key: Mapped[str] value = mapped_column(JSON, default=None) -# A log entry of an agent, the use and meaning depends on the agent class -class AgentLog(Base): - __modelname__ = 'agent_log' - __tablename__ = 'agent_logs' - - id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True) - agent_id: Mapped[int] = mapped_column(ForeignKey("agents.id")) - - # Kind is the class of the resource - # Key is the specific identifier within the class - # Multiple resources can share key - value: Mapped[str] - diff --git a/backend/server.py b/backend/server.py index 24b682d..9392cd3 100644 --- a/backend/server.py +++ b/backend/server.py @@ -119,9 +119,10 @@ def start_server(app): await send({'message': "pong"}) elif action == "create-agent": + name = body['name'] agent_id = app.create_agent( user_id=user_id, - name=body['name'], + name=name, agentname=body.get('agentname'), description=body.get('description'), picture=body.get('picture'),