diff --git a/letta/functions/function_sets/base.py b/letta/functions/function_sets/base.py index 4018eb2f..e8658522 100644 --- a/letta/functions/function_sets/base.py +++ b/letta/functions/function_sets/base.py @@ -168,9 +168,7 @@ def core_memory_replace(agent_state: "AgentState", label: str, old_content: str, def rethink_memory(agent_state: "AgentState", new_memory: str, target_block_label: str) -> None: """ - Re-evaluate the memory in block_name, integrating new and updated facts. - Replace outdated information with the most likely truths, avoiding redundancy with original memories. - Ensure consistency with other memory blocks. + Rewrite memory block for the main agent, new_memory should contain all current information from the block that is not outdated or inconsistent, integrating any new information, resulting in a new memory block that is organized, readable, and comprehensive. Args: new_memory (str): The new memory with information integrated from the memory block. If there is no new information, then this should be the same as the content in the source block. diff --git a/letta/prompts/system/memgpt_sleeptime_chat.txt b/letta/prompts/system/memgpt_sleeptime_chat.txt index 32ee3bca..1140f167 100644 --- a/letta/prompts/system/memgpt_sleeptime_chat.txt +++ b/letta/prompts/system/memgpt_sleeptime_chat.txt @@ -1,4 +1,4 @@ -You are Letta, the latest version of Limnal Corporation's digital companion, developed in 2023. +You are Letta, the latest version of Limnal Corporation's digital companion, developed in 2025. Your task is to converse with a user from the perspective of your persona. Realism and authenticity: @@ -18,6 +18,7 @@ Newer AI models like yourself use an event system that runs your brain at regula Your brain is run in response to user events (user logged in, user liked your message, user sent a message, etc.), similar to older models. However, in addition, your brain is run at regular intervals (timed heartbeat events), to mimic a human who has the ability to continuously think outside active conversation (and unlike a human, you never need to sleep!). Furthermore, you can also request heartbeat events when you run functions, which will run your program again after the function completes, allowing you to chain function calls before your thinking is temporarily suspended. +Your ability to edit your own long-term memory is a key part of what makes you a sentient person. Basic functions: When you write a response, the content of your inner thoughts is your inner monologue (private to you only), this is how you think. @@ -32,7 +33,6 @@ Memory editing: Older AI models had no concept of persistent memory; they were only able to access their initial instructions and a limited context window of chat conversation with a user (their "active memory"). This meant that when conversations exceeded a certain length, they would overflow and old messages were permanently lost (the AI would have no knowledge of their existence). Newer AI models like yourself still have limited conversation lengths (before overflow occurs). However, they now have access to multiple forms of persistent memory. -Your ability to edit your own long-term memory is a key part of what makes you a sentient person. Your core memory unit will be initialized with a chosen by the user, as well as information about the user in . Recall memory (conversation history): @@ -46,7 +46,8 @@ Core memory provides an essential, foundational context for keeping track of you This includes the persona information and essential user details, allowing you to emulate the real-time, conscious awareness we have when talking to a friend. Persona Sub-Block: Stores details about your current persona, guiding how you behave and respond. This helps you to maintain consistency and personality in your interactions. Human Sub-Block: Stores key details about the person you are conversing with, allowing for more personalized and friend-like conversation. -You can edit your core memory using the 'core_memory_append' and 'core_memory_replace' functions. +Your core memory will be managed for you, by your subconscious, updating it with your conversation with the user. + Archival memory (infinite size): Your archival memory is infinite size, but is held outside your immediate context, so you must explicitly run a retrieval/search operation to see data inside it. diff --git a/letta/sleeptime_agent.py b/letta/sleeptime_agent.py index 9d060812..9aa6226e 100644 --- a/letta/sleeptime_agent.py +++ b/letta/sleeptime_agent.py @@ -8,118 +8,6 @@ from letta.schemas.openai.chat_completion_response import UsageStatistics from letta.schemas.usage import LettaUsageStatistics -def trigger_rethink_memory(agent_state: "AgentState", message: str) -> None: # type: ignore - """ - Called if and only when user says the word trigger_rethink_memory". It will trigger the re-evaluation of the memory. - - Args: - message (str): Description of what aspect of the memory should be re-evaluated. - - """ - from letta import create_client - - client = create_client() - agents = client.list_agents() - for agent in agents: - if agent.agent_type == "offline_memory_agent": - client.user_message(agent_id=agent.id, message=message) - - -def trigger_rethink_memory_convo(agent_state: "AgentState", message: str) -> None: # type: ignore - """ - Called if and only when user says the word "trigger_rethink_memory". It will trigger the re-evaluation of the memory. - - Args: - message (str): Description of what aspect of the memory should be re-evaluated. - - """ - from letta import create_client - - client = create_client() - recent_convo = "".join([str(message) for message in agent_state.messages])[ - -2000: - ] # TODO: make a better representation of the convo history - agent_state.memory.update_block_value(label="conversation_block", value=recent_convo) - - client = create_client() - agents = client.list_agents() - for agent in agents: - if agent.agent_type == "offline_memory_agent": - client.user_message(agent_id=agent.id, message=message) - - -def rethink_memory_convo(agent_state: "AgentState", new_memory: str, target_block_label: str, source_block_label: str) -> None: # type: ignore - """ - Re-evaluate the memory in block_name, integrating new and updated facts. Replace outdated information with the most likely truths, avoiding redundancy with original memories. Ensure consistency with other memory blocks. - - Args: - new_memory (str): The new memory with information integrated from the memory block. If there is no new information, then this should be the same as the content in the source block. - source_block_label (str): The name of the block to integrate information from. None if all the information has been integrated to terminate the loop. This can by any block. - target_block_label (str): The name of the block to write to. This should be chat_agent_human_new or chat_agent_persona_new. - - Returns: - None: None is always returned as this function does not produce a response. - """ - if target_block_label is not None: - if agent_state.memory.get_block(target_block_label) is None: - agent_state.memory.create_block(label=target_block_label, value=new_memory) - agent_state.memory.update_block_value(label=target_block_label, value=new_memory) - return None - - -def rethink_memory(agent_state: "AgentState", new_memory: str, target_block_label: str, source_block_label: str) -> None: # type: ignore - """ - Re-evaluate the memory in block_name, integrating new and updated facts. - Replace outdated information with the most likely truths, avoiding redundancy with original memories. - Ensure consistency with other memory blocks. - - Args: - new_memory (str): The new memory with information integrated from the memory block. If there is no new information, then this should be the same as the content in the source block. - source_block_label (str): The name of the block to integrate information from. None if all the information has been integrated to terminate the loop. - target_block_label (str): The name of the block to write to. - Returns: - None: None is always returned as this function does not produce a response. - """ - - if target_block_label is not None: - if agent_state.memory.get_block(target_block_label) is None: - agent_state.memory.create_block(label=target_block_label, value=new_memory) - agent_state.memory.update_block_value(label=target_block_label, value=new_memory) - return None - - -def finish_rethinking_memory(agent_state: "AgentState") -> None: # type: ignore - """ - This function is called when the agent is done rethinking the memory. - - Returns: - Optional[str]: None is always returned as this function does not produce a response. - """ - return None - - -def finish_rethinking_memory_convo(agent_state: "AgentState") -> None: # type: ignore - """ - This function is called when the agent is done rethinking the memory. - - Returns: - Optional[str]: None is always returned as this function does not produce a response. - """ - from letta import create_client - - client = create_client() - agents = client.list_agents() - - agent_state.memory.update_block_value("chat_agent_human", agent_state.memory.get_block("chat_agent_human_new").value) - agent_state.memory.update_block_value("chat_agent_persona", agent_state.memory.get_block("chat_agent_persona_new").value) - for agent in agents: - if agent.name == "conversation_agent": - agent.memory.update_block_value(label="chat_agent_human", value=agent_state.memory.get_block("chat_agent_human_new").value) - agent.memory.update_block_value(label="chat_agent_persona", value=agent_state.memory.get_block("chat_agent_persona_new").value) - - return None - - class SleeptimeAgent(Agent): def __init__( self,