Chat Threads, ConversationAgent (WIP)

This commit is contained in:
Shivering Ocelot committed 2025-06-16 19:59:37 -05:00
1 parent 22fe5619d8
commit e8d80c5495
6 files changed
+519 -46

No files matched your search

+91
View File
@@ -53,6 +53,90 @@ class Agent:
if inspect.isawaitable(result):
result = await result
return result
# Returns all resource values matching the kind and key
def get_resources(self, kind, key):
self.app
class DebugAgent(Agent):
identifier = "debug"
schema_fields = []
tools = []
async def received_message(self, message):
chat_view = self.app.get_chat_view(message.chat_id)
response = chat_view.debug_string()
self.app.send_chat_message(
chat_id=message.chat_id,
sender=self.id,
content=response,
thread_id=chat_view.current_thread_id,
)
class ConversationAgent(Agent):
identifier = "conversation"
schema_fields = []
tools = []
def __init__(self, app, data):
Agent.__init__(self, app, data)
# Constant system prompt for developing purposes
self.system_prompt = "You are a friendly AI having a casual conversation with the user."
async def prompt(self, content):
# TODO: Advanced features
messages = [
LlamaMessage("system", self.system_prompt),
LlamaMessage("user", content)
]
response = await replicate_llama_completion(self.app, messages)
return response
async def received_message(self, message):
def sender_name(message):
sender = message.sender
is_digit = isinstance(sender, (int, str)) and str(sender).isdigit()
is_self = is_digit and str(sender) == str(self.id)
return self.name if is_self else sender
# TODO: before retrieving the chat context, acquire a lock for it
saved_context = ThreadContext(self.app.get_agent_resource(self.id, 'last-thread-context', message.chat_id))
chat_view = self.app.get_chat_view(message.chat_id)
if message.thread_id != saved_context.current_thread_id:
# the incoming message is not from the same thread that the agent was last aware of
# store details about the old thread in the agent's long term memory
old_thread = chat_view.thread_map.get(message.thread_id)
self.process_thread(old_thread)
# TODO: This is a good place to store the new context, its fine that the agent hasnt responded
current_thread = chat_view.thread_map.get(message.thread_id)
chat_summary = "\n".join(f"[{sender_name(message)}]: {message.content}" for message in current_thread.messages)
messages = [
LlamaMessage("system", f"{self.system_prompt}\nYou are given the context of the conversation, respond with your next message in the conversation."),
LlamaMessage("user", f"Recent Messages:\n{chat_summary}")
]
response = await replicate_llama_completion(self.app, messages)
self.app.send_chat_message(
chat_id=message.chat_id,
sender=self.id,
content=response,
)
# TODO: drop the chat context lock
# Compute thread summnary and concrete memories, then save the progress done
def process_thread(self, thread):
# TODO: extract memories from the thread messages, then store them in the agent's vector memory db
# TODO: somewhere here it must be known if the thread was seen before, the same memory should not be stored multiple times
pass
class ToolUsingAgent:
identifier = "tool-using"
@@ -245,6 +329,13 @@ class CoderV1Agent(Llama8bAgent):
async def gral_update_file(self, message_history: list, filepath: str, file_content: str):
return await gral.gral_update_file(self.app, self.config['system_prompt'], message_history, filepath, file_content)
# Used by ConversationAgent to keep track of the last chat thread it participated in
class ThreadContext:
def __init__(self, data):
if data:
self.current_thread_id = data.get('current_thread_id')
else:
self.current_thread_id = None
class ParsedResponse:
def __init__(self):