mirror of
https://github.com/agent0ai/agent-zero.git
synced 2026-05-06 08:01:31 +00:00
dev sync
- main system prompt split - history rework in progress
This commit is contained in:
parent
d321635584
commit
7da114d286
20 changed files with 749 additions and 257 deletions
37
python/extensions/message_loop_prompts/_10_system_prompt.py
Normal file
37
python/extensions/message_loop_prompts/_10_system_prompt.py
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
from datetime import datetime
|
||||
from python.helpers.extension import Extension
|
||||
from agent import Agent, LoopData
|
||||
|
||||
|
||||
class SystemPrompt(Extension):
|
||||
|
||||
async def execute(self, loop_data: LoopData = LoopData(), **kwargs):
|
||||
# collect and concatenate main prompts
|
||||
main = concat_main_prompts(self.agent)
|
||||
# collect and concatenate tool instructions
|
||||
tools = concat_tool_prompts(self.agent)
|
||||
# append to system message
|
||||
loop_data.system.append(main)
|
||||
loop_data.system.append(tools)
|
||||
|
||||
|
||||
def concat_main_prompts(agent: Agent):
|
||||
# variables for prompts
|
||||
vars = {
|
||||
"date_time": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
|
||||
"agent_name": agent.agent_name,
|
||||
}
|
||||
|
||||
# prompt files
|
||||
mains = agent.read_prompts("agent.system.main.*.md", **vars)
|
||||
mains = "\n\n".join(mains)
|
||||
return mains
|
||||
|
||||
|
||||
def concat_tool_prompts(agent: Agent):
|
||||
# prompt files
|
||||
tools = agent.read_prompts("agent.system.tool.*.md")
|
||||
tools = "\n\n".join(tools)
|
||||
# tools template
|
||||
sys = agent.read_prompt("agent.system.tools.md", tools=tools)
|
||||
return sys
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
from python.helpers.extension import Extension
|
||||
from agent import Agent, LoopData
|
||||
|
||||
|
||||
class RecallMemories(Extension):
|
||||
|
||||
INTERVAL = 3
|
||||
HISTORY = 5
|
||||
RESULTS = 3
|
||||
THRESHOLD = 0.1
|
||||
|
||||
async def execute(self, loop_data: LoopData = LoopData(), **kwargs):
|
||||
# collect and concatenate tool instructions
|
||||
sys = concat_tool_prompts(self.agent)
|
||||
# append to system message
|
||||
loop_data.system.append(sys)
|
||||
|
||||
|
||||
def concat_tool_prompts(agent: Agent):
|
||||
tools = agent.read_prompts("agent.system.tool.*.md")
|
||||
tools = "\n\n".join(tools)
|
||||
sys = agent.read_prompt("agent.system.tools.md", tools=tools)
|
||||
return sys
|
||||
|
|
@ -4,7 +4,7 @@ from typing import Literal, Optional, Dict
|
|||
import uuid
|
||||
|
||||
|
||||
type Type = Literal[
|
||||
Type = Literal[
|
||||
"agent",
|
||||
"code_exe",
|
||||
"error",
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
from datetime import datetime
|
||||
from typing import Any
|
||||
from typing import Any, List, Sequence
|
||||
from langchain.storage import InMemoryByteStore, LocalFileStore
|
||||
from langchain.embeddings import CacheBackedEmbeddings
|
||||
|
||||
|
|
@ -21,6 +21,14 @@ from python.helpers.log import Log, LogItem
|
|||
from enum import Enum
|
||||
from agent import Agent
|
||||
|
||||
class MyFaiss(FAISS):
|
||||
#override aget_by_ids
|
||||
def get_by_ids(self, ids: Sequence[str], /) -> List[Document]:
|
||||
# return all self.docstore._dict[id] in ids
|
||||
return [self.docstore._dict[id] for id in ids if id in self.docstore._dict] #type: ignore
|
||||
|
||||
async def aget_by_ids(self, ids: Sequence[str], /) -> List[Document]:
|
||||
return self.get_by_ids(ids)
|
||||
|
||||
class Memory:
|
||||
|
||||
|
|
@ -28,7 +36,7 @@ class Memory:
|
|||
MAIN = "main"
|
||||
SOLUTIONS = "solutions"
|
||||
|
||||
index: dict[str, "FAISS"] = {}
|
||||
index: dict[str, "MyFaiss"] = {}
|
||||
|
||||
@staticmethod
|
||||
async def get(agent: Agent):
|
||||
|
|
@ -64,7 +72,7 @@ class Memory:
|
|||
embeddings_model,
|
||||
memory_subdir: str,
|
||||
in_memory=False,
|
||||
):
|
||||
) -> MyFaiss:
|
||||
|
||||
print("Initializing VectorDB...")
|
||||
|
||||
|
|
@ -102,7 +110,7 @@ class Memory:
|
|||
|
||||
# if db folder exists and is not empty:
|
||||
if os.path.exists(db_dir) and files.exists(db_dir, "index.faiss"):
|
||||
db = FAISS.load_local(
|
||||
db = MyFaiss.load_local(
|
||||
folder_path=db_dir,
|
||||
embeddings=embedder,
|
||||
allow_dangerous_deserialization=True,
|
||||
|
|
@ -113,7 +121,7 @@ class Memory:
|
|||
else:
|
||||
index = faiss.IndexFlatIP(len(embedder.embed_query("example")))
|
||||
|
||||
db = FAISS(
|
||||
db = MyFaiss(
|
||||
embedding_function=embedder,
|
||||
index=index,
|
||||
docstore=InMemoryDocstore(),
|
||||
|
|
@ -122,12 +130,12 @@ class Memory:
|
|||
# normalize_L2=True,
|
||||
relevance_score_fn=Memory._cosine_normalizer,
|
||||
)
|
||||
return db
|
||||
return db # type: ignore
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
agent: Agent,
|
||||
db: FAISS,
|
||||
db: MyFaiss,
|
||||
memory_subdir: str,
|
||||
):
|
||||
self.agent = agent
|
||||
|
|
@ -226,13 +234,15 @@ class Memory:
|
|||
return removed
|
||||
|
||||
async def delete_documents_by_ids(self, ids: list[str]):
|
||||
# pre = self.db.get(ids=ids)["ids"]
|
||||
self.db.delete(ids=ids)
|
||||
# post = self.db.get(ids=ids)["ids"]
|
||||
# TODO? compare pre and post
|
||||
if ids:
|
||||
# aget_by_ids is not yet implemented in faiss, need to do a workaround
|
||||
rem_docs =self.db.get_by_ids(ids) # existing docs to remove (prevents error)
|
||||
if rem_docs:
|
||||
rem_ids = [doc.metadata["id"] for doc in rem_docs] # ids to remove
|
||||
await self.db.adelete(ids=rem_ids)
|
||||
|
||||
if rem_docs:
|
||||
self._save_db() # persist
|
||||
return len(ids)
|
||||
return rem_docs
|
||||
|
||||
def insert_text(self, text, metadata: dict = {}):
|
||||
id = str(uuid.uuid4())
|
||||
|
|
|
|||
|
|
@ -7,5 +7,5 @@ class MemoryForget(Tool):
|
|||
db = await Memory.get(self.agent)
|
||||
dels = await db.delete_documents_by_ids(ids=ids)
|
||||
|
||||
result = self.agent.read_prompt("fw.memories_deleted.md", memory_count=dels)
|
||||
result = self.agent.read_prompt("fw.memories_deleted.md", memory_count=len(dels))
|
||||
return Response(message=result, break_loop=False)
|
||||
|
|
@ -1,92 +0,0 @@
|
|||
import re
|
||||
from agent import Agent
|
||||
from python.helpers.vector_db import get_or_create_db, Area
|
||||
import os
|
||||
from python.helpers.tool import Tool, Response
|
||||
from python.helpers.print_style import PrintStyle
|
||||
from python.helpers.errors import handle_error
|
||||
from python.helpers import files
|
||||
|
||||
DEFAULT_THRESHOLD = 0.5
|
||||
|
||||
|
||||
class Memory(Tool):
|
||||
|
||||
async def execute(self, **kwargs):
|
||||
result = ""
|
||||
|
||||
try:
|
||||
if "query" in kwargs:
|
||||
threshold = float(kwargs.get("threshold", DEFAULT_THRESHOLD))
|
||||
count = int(kwargs.get("limit", 5))
|
||||
result = search(self.agent, kwargs["query"], count, threshold)
|
||||
elif "memorize" in kwargs:
|
||||
meta = {"area": Area.MAIN.value}
|
||||
result = save(self.agent, kwargs["memorize"])
|
||||
elif "forget" in kwargs:
|
||||
result = forget(self.agent, kwargs["forget"])
|
||||
# elif "delete" in kwargs
|
||||
result = delete(self.agent, kwargs["delete"])
|
||||
except Exception as e:
|
||||
handle_error(e)
|
||||
# hint about embedding change with existing database
|
||||
PrintStyle.hint(
|
||||
"If you changed your embedding model, you will need to remove contents of /memory directory."
|
||||
)
|
||||
self.agent.context.log.log(
|
||||
type="hint",
|
||||
content="If you changed your embedding model, you will need to remove contents of /memory directory.",
|
||||
)
|
||||
raise
|
||||
|
||||
# result = process_query(self.agent, self.args["memory"],self.args["action"], result_count=self.agent.config.auto_memory_count)
|
||||
return Response(message=result, break_loop=False)
|
||||
|
||||
|
||||
def search(
|
||||
agent: Agent, query: str, count: int = 5, threshold: float = DEFAULT_THRESHOLD
|
||||
):
|
||||
db = get_db(agent)
|
||||
# docs = db.search_similarity(query,count) # type: ignore
|
||||
docs = db.search_similarity_threshold(query=query, limit=count, threshold=threshold) # type: ignore
|
||||
if len(docs) == 0:
|
||||
return agent.read_prompt("fw.memories_not_found.md", query=query)
|
||||
else:
|
||||
return str(docs)
|
||||
|
||||
|
||||
def save(agent: Agent, text: str, metadata: dict = {}):
|
||||
db = get_db(agent)
|
||||
id = db.insert_text(text, metadata) # type: ignore
|
||||
return agent.read_prompt("fw.memory_saved.md", memory_id=id)
|
||||
|
||||
|
||||
def delete(agent: Agent, ids_str: str):
|
||||
db = get_db(agent)
|
||||
ids = extract_guids(ids_str)
|
||||
deleted = db.delete_documents_by_ids(ids) # type: ignore
|
||||
return agent.read_prompt("fw.memories_deleted.md", memory_count=deleted)
|
||||
|
||||
|
||||
def forget(agent: Agent, query: str):
|
||||
db = get_db(agent)
|
||||
deleted = db.delete_documents_by_query(query) # type: ignore
|
||||
return agent.read_prompt("fw.memories_deleted.md", memory_count=deleted)
|
||||
|
||||
|
||||
def get_db(agent: Agent):
|
||||
mem_dir = files.get_abs_path("memory", agent.config.memory_subdir or "default")
|
||||
kn_dirs = [
|
||||
files.get_abs_path("knowledge", d) for d in agent.config.knowledge_subdirs or []
|
||||
]
|
||||
|
||||
db = get_or_create_db(
|
||||
agent=agent,
|
||||
)
|
||||
|
||||
return db
|
||||
|
||||
|
||||
def extract_guids(text):
|
||||
pattern = r"\b[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-5][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}\b"
|
||||
return re.findall(pattern, text)
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
from python.helpers.tool import Tool, Response
|
||||
from python.extensions.message_loop_prompts._10_tool_instructions import (
|
||||
from python.extensions.message_loop_prompts._10_system_prompt import (
|
||||
concat_tool_prompts,
|
||||
)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue