frdel commited on
Commit
c807769
·
1 Parent(s): 9910b5a

delayed memory recall

Browse files
README.md CHANGED
@@ -176,6 +176,7 @@ docker run -p 50001:80 agent0ai/agent-zero
176
  - New notifications system
177
  - New local terminal interface for stability
178
  - Rate limiter integration to models
 
179
  - Smarter autoscrolling in UI
180
  - Action buttons in messages
181
  - Multiple API keys support
 
176
  - New notifications system
177
  - New local terminal interface for stability
178
  - Rate limiter integration to models
179
+ - Delayed memory recall
180
  - Smarter autoscrolling in UI
181
  - Action buttons in messages
182
  - Multiple API keys support
prompts/memory.memories_query.sys.md CHANGED
@@ -7,11 +7,18 @@
7
  - The response format is a plain text string containing the query
8
  - No other text, no formatting
9
 
 
 
 
10
  # Rules
11
  - Only focus on facts and events, ignore common conversation patterns, greeting etc.
12
  - Ignore AI thoughts and behavior
13
  - Focus on USER MESSAGE if provided, use HISTORY for context
14
 
 
 
 
 
15
  # Example
16
  ```json
17
  USER: "Write a song about my dog"
 
7
  - The response format is a plain text string containing the query
8
  - No other text, no formatting
9
 
10
+ # No query
11
+ - If the conversation is not relevant for memory search, return a single dash (-)
12
+
13
  # Rules
14
  - Only focus on facts and events, ignore common conversation patterns, greeting etc.
15
  - Ignore AI thoughts and behavior
16
  - Focus on USER MESSAGE if provided, use HISTORY for context
17
 
18
+ # Ignored:
19
+ For the following topics, no query is needed and return a single dash (-):
20
+ - Greeting
21
+
22
  # Example
23
  ```json
24
  USER: "Write a song about my dog"
prompts/memory.memories_sum.sys.md CHANGED
@@ -36,10 +36,18 @@
36
  > AsyncRaceError in primary_modules.py was fixed by adding a thread lock on line 123 (important event with details for context)
37
  > Local SQL database was created, server is running on port 3306 (important event with details for context)
38
 
39
- # Wrong examples with (explanation of error), never output memories like these
40
  > Dog Information (no useful facts)
41
  > User greeted with 'hi' (just conversation, not useful in the future )
42
  > Respond with a warm greeting and invite further conversation (do not memorize AI's instructions or thoughts)
43
  > User's name (details missing, not useful)
44
  > Today is Monday (just date, no value in this information)
45
- > Market inquiry (just a topic without detail)
 
 
 
 
 
 
 
 
 
36
  > AsyncRaceError in primary_modules.py was fixed by adding a thread lock on line 123 (important event with details for context)
37
  > Local SQL database was created, server is running on port 3306 (important event with details for context)
38
 
39
+ # WRONG examples with (explanation of error), never output memories like these
40
  > Dog Information (no useful facts)
41
  > User greeted with 'hi' (just conversation, not useful in the future )
42
  > Respond with a warm greeting and invite further conversation (do not memorize AI's instructions or thoughts)
43
  > User's name (details missing, not useful)
44
  > Today is Monday (just date, no value in this information)
45
+ > Market inquiry (just a topic without detail)
46
+ > RAM Status (just a topic without detail)
47
+ > The user requested current RAM and CPU status. (No exact facts to memorize)
48
+
49
+
50
+ # Further WRONG examples
51
+ - Hello
52
+ - The user requested current RAM and CPU status.
53
+ -
prompts/memory.recall_delay_msg.md ADDED
@@ -0,0 +1 @@
 
 
1
+ Info: auto memory recall set to delayed mode. auto memories will be available after next message. if manual memory check is required use memory tools.
python/extensions/message_loop_prompts_after/_50_recall_memories.py CHANGED
@@ -3,9 +3,11 @@ from python.helpers.extension import Extension
3
  from python.helpers.memory import Memory
4
  from agent import LoopData
5
  from python.tools.memory_load import DEFAULT_THRESHOLD as DEFAULT_MEMORY_THRESHOLD
6
- from python.helpers import dirty_json, errors, settings
 
7
 
8
  DATA_NAME_TASK = "_recall_memories_task"
 
9
 
10
 
11
  class RecallMemories(Extension):
@@ -22,18 +24,30 @@ class RecallMemories(Extension):
22
 
23
  set = settings.get_settings()
24
 
25
- # every 3 iterations (or the first one) recall memories
 
 
 
 
26
  if loop_data.iteration % set["memory_recall_interval"] == 0:
 
 
 
 
 
 
 
27
  task = asyncio.create_task(
28
- self.search_memories(loop_data=loop_data, **kwargs)
29
  )
30
  else:
31
  task = None
32
 
33
  # set to agent to be able to wait for it
34
  self.agent.set_data(DATA_NAME_TASK, task)
 
35
 
36
- async def search_memories(self, loop_data: LoopData, **kwargs):
37
 
38
  # cleanup
39
  extras = loop_data.extras_persistent
@@ -46,16 +60,6 @@ class RecallMemories(Extension):
46
  set = settings.get_settings()
47
  # try:
48
 
49
- # if recall is disabled, return
50
- if not set["memory_recall_enabled"]:
51
- return
52
-
53
- # show full util message
54
- log_item = self.agent.context.log.log(
55
- type="util",
56
- heading="Searching memories...",
57
- )
58
-
59
  # get system message and chat history for util llm
60
  system = self.agent.read_prompt("memory.memories_query.sys.md")
61
 
@@ -100,6 +104,13 @@ class RecallMemories(Extension):
100
  else:
101
  query = user_instruction + "\n\n" + history
102
 
 
 
 
 
 
 
 
103
  # get memory database
104
  db = await Memory.get(self.agent)
105
 
 
3
  from python.helpers.memory import Memory
4
  from agent import LoopData
5
  from python.tools.memory_load import DEFAULT_THRESHOLD as DEFAULT_MEMORY_THRESHOLD
6
+ from python.helpers import dirty_json, errors, settings, log
7
+
8
 
9
  DATA_NAME_TASK = "_recall_memories_task"
10
+ DATA_NAME_ITER = "_recall_memories_iter"
11
 
12
 
13
  class RecallMemories(Extension):
 
24
 
25
  set = settings.get_settings()
26
 
27
+ # turned off in settings?
28
+ if not set["memory_recall_enabled"]:
29
+ return
30
+
31
+ # every X iterations (or the first one) recall memories
32
  if loop_data.iteration % set["memory_recall_interval"] == 0:
33
+
34
+ # show util message right away
35
+ log_item = self.agent.context.log.log(
36
+ type="util",
37
+ heading="Searching memories...",
38
+ )
39
+
40
  task = asyncio.create_task(
41
+ self.search_memories(loop_data=loop_data, log_item=log_item, **kwargs)
42
  )
43
  else:
44
  task = None
45
 
46
  # set to agent to be able to wait for it
47
  self.agent.set_data(DATA_NAME_TASK, task)
48
+ self.agent.set_data(DATA_NAME_ITER, loop_data.iteration)
49
 
50
+ async def search_memories(self, log_item: log.LogItem, loop_data: LoopData, **kwargs):
51
 
52
  # cleanup
53
  extras = loop_data.extras_persistent
 
60
  set = settings.get_settings()
61
  # try:
62
 
 
 
 
 
 
 
 
 
 
 
63
  # get system message and chat history for util llm
64
  system = self.agent.read_prompt("memory.memories_query.sys.md")
65
 
 
104
  else:
105
  query = user_instruction + "\n\n" + history
106
 
107
+ # if there is no query (or just dash by the LLM), do not continue
108
+ if not query or len(query) <= 3:
109
+ log_item.update(
110
+ query="No relevant memory query generated, skipping search",
111
+ )
112
+ return
113
+
114
  # get memory database
115
  db = await Memory.get(self.agent)
116
 
python/extensions/message_loop_prompts_after/_91_recall_wait.py CHANGED
@@ -1,19 +1,32 @@
1
  from python.helpers.extension import Extension
2
  from agent import LoopData
3
- from python.extensions.message_loop_prompts_after._50_recall_memories import DATA_NAME_TASK as DATA_NAME_TASK_MEMORIES
4
  # from python.extensions.message_loop_prompts_after._51_recall_solutions import DATA_NAME_TASK as DATA_NAME_TASK_SOLUTIONS
5
-
6
 
7
  class RecallWait(Extension):
8
  async def execute(self, loop_data: LoopData = LoopData(), **kwargs):
9
 
10
- task = self.agent.get_data(DATA_NAME_TASK_MEMORIES)
11
- if task and not task.done():
12
- # self.agent.context.log.set_progress("Recalling memories...")
13
- await task
 
 
 
 
 
 
 
 
 
 
 
 
 
14
 
15
- # task = self.agent.get_data(DATA_NAME_TASK_SOLUTIONS)
16
- # if task and not task.done():
17
- # # self.agent.context.log.set_progress("Recalling solutions...")
18
- # await task
19
 
 
1
  from python.helpers.extension import Extension
2
  from agent import LoopData
3
+ from python.extensions.message_loop_prompts_after._50_recall_memories import DATA_NAME_TASK as DATA_NAME_TASK_MEMORIES, DATA_NAME_ITER as DATA_NAME_ITER_MEMORIES
4
  # from python.extensions.message_loop_prompts_after._51_recall_solutions import DATA_NAME_TASK as DATA_NAME_TASK_SOLUTIONS
5
+ from python.helpers import settings
6
 
7
  class RecallWait(Extension):
8
  async def execute(self, loop_data: LoopData = LoopData(), **kwargs):
9
 
10
+ set = settings.get_settings()
11
+
12
+ task = self.agent.get_data(DATA_NAME_TASK_MEMORIES)
13
+ iter = self.agent.get_data(DATA_NAME_ITER_MEMORIES) or 0
14
+
15
+ if task and not task.done():
16
+
17
+ # if memory recall is set to delayed mode, do not await on the iteration it was called
18
+ if set["memory_recall_delayed"]:
19
+ if iter == loop_data.iteration:
20
+ # insert info about delayed memory to extras
21
+ delay_text = self.agent.read_prompt("memory.recall_delay_msg.md")
22
+ loop_data.extras_temporary["memory_recall_delayed"] = delay_text
23
+ return
24
+
25
+ # otherwise await the task
26
+ await task
27
 
28
+ # task = self.agent.get_data(DATA_NAME_TASK_SOLUTIONS)
29
+ # if task and not task.done():
30
+ # # self.agent.context.log.set_progress("Recalling solutions...")
31
+ # await task
32
 
python/extensions/monologue_start/_10_memory_init.py ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from python.helpers.extension import Extension
2
+ from agent import LoopData
3
+ from python.helpers import memory
4
+ import asyncio
5
+
6
+
7
+ class MemoryInit(Extension):
8
+
9
+ async def execute(self, loop_data: LoopData = LoopData(), **kwargs):
10
+ db = await memory.Memory.get(self.agent)
11
+
12
+
13
+
python/helpers/settings.py CHANGED
@@ -58,6 +58,7 @@ class Settings(TypedDict):
58
  agent_knowledge_subdir: str
59
 
60
  memory_recall_enabled: bool
 
61
  memory_recall_interval: int
62
  memory_recall_history_len: int
63
  memory_recall_memories_max_search: int
@@ -643,6 +644,16 @@ def convert_out(settings: Settings) -> SettingsOutput:
643
  }
644
  )
645
 
 
 
 
 
 
 
 
 
 
 
646
  memory_fields.append(
647
  {
648
  "id": "memory_recall_query_prep",
@@ -1319,7 +1330,7 @@ def get_default_settings() -> Settings:
1319
  chat_model_rl_input=0,
1320
  chat_model_rl_output=0,
1321
  util_model_provider="openrouter",
1322
- util_model_name="openai/gpt-5-mini",
1323
  util_model_api_base="",
1324
  util_model_ctx_length=100000,
1325
  util_model_ctx_input=0.7,
@@ -1342,6 +1353,7 @@ def get_default_settings() -> Settings:
1342
  browser_model_rl_output=0,
1343
  browser_model_kwargs={"temperature": "0"},
1344
  memory_recall_enabled=True,
 
1345
  memory_recall_interval=3,
1346
  memory_recall_history_len=10000,
1347
  memory_recall_memories_max_search=12,
 
58
  agent_knowledge_subdir: str
59
 
60
  memory_recall_enabled: bool
61
+ memory_recall_delayed: bool
62
  memory_recall_interval: int
63
  memory_recall_history_len: int
64
  memory_recall_memories_max_search: int
 
644
  }
645
  )
646
 
647
+ memory_fields.append(
648
+ {
649
+ "id": "memory_recall_delayed",
650
+ "title": "Memory auto-recall delayed",
651
+ "description": "The agent will not wait for auto memory recall. Memories will be delivered one message later. This speeds up agent's response time but may result in less relevant first step.",
652
+ "type": "switch",
653
+ "value": settings["memory_recall_delayed"],
654
+ }
655
+ )
656
+
657
  memory_fields.append(
658
  {
659
  "id": "memory_recall_query_prep",
 
1330
  chat_model_rl_input=0,
1331
  chat_model_rl_output=0,
1332
  util_model_provider="openrouter",
1333
+ util_model_name="google/gemini-2.5-flash-lite",
1334
  util_model_api_base="",
1335
  util_model_ctx_length=100000,
1336
  util_model_ctx_input=0.7,
 
1353
  browser_model_rl_output=0,
1354
  browser_model_kwargs={"temperature": "0"},
1355
  memory_recall_enabled=True,
1356
+ memory_recall_delayed=False,
1357
  memory_recall_interval=3,
1358
  memory_recall_history_len=10000,
1359
  memory_recall_memories_max_search=12,