mirror of
https://github.com/MODSetter/SurfSense.git
synced 2026-05-17 18:35:19 +02:00
feat: integrate MemoryInjectionMiddleware and update memory tool instructions
This commit is contained in:
parent
ba7e288879
commit
702d955e79
2 changed files with 65 additions and 95 deletions
|
|
@ -38,6 +38,7 @@ from app.agents.new_chat.llm_config import AgentConfig
|
|||
from app.agents.new_chat.middleware import (
|
||||
DedupHITLToolCallsMiddleware,
|
||||
KnowledgeBaseSearchMiddleware,
|
||||
MemoryInjectionMiddleware,
|
||||
SurfSenseFilesystemMiddleware,
|
||||
)
|
||||
from app.agents.new_chat.system_prompt import (
|
||||
|
|
@ -425,9 +426,16 @@ async def create_surfsense_deep_agent(
|
|||
)
|
||||
|
||||
# -- Build the middleware stack (mirrors create_deep_agent internals) ------
|
||||
_memory_middleware = MemoryInjectionMiddleware(
|
||||
user_id=user_id,
|
||||
search_space_id=search_space_id,
|
||||
thread_visibility=visibility,
|
||||
)
|
||||
|
||||
# General-purpose subagent middleware
|
||||
gp_middleware = [
|
||||
TodoListMiddleware(),
|
||||
_memory_middleware,
|
||||
SurfSenseFilesystemMiddleware(
|
||||
search_space_id=search_space_id,
|
||||
created_by_id=user_id,
|
||||
|
|
@ -447,6 +455,7 @@ async def create_surfsense_deep_agent(
|
|||
# Main agent middleware
|
||||
deepagent_middleware = [
|
||||
TodoListMiddleware(),
|
||||
_memory_middleware,
|
||||
KnowledgeBaseSearchMiddleware(
|
||||
llm=llm,
|
||||
search_space_id=search_space_id,
|
||||
|
|
|
|||
|
|
@ -250,113 +250,75 @@ _TOOL_INSTRUCTIONS["web_search"] = """
|
|||
# Memory tool instructions have private and shared variants.
|
||||
# We store them keyed as "save_memory" / "recall_memory" with sub-keys.
|
||||
_MEMORY_TOOL_INSTRUCTIONS: dict[str, dict[str, str]] = {
|
||||
"save_memory": {
|
||||
"update_memory": {
|
||||
"private": """
|
||||
- save_memory: Save facts, preferences, or context for personalized responses.
|
||||
- Use this when the user explicitly or implicitly shares information worth remembering.
|
||||
- Trigger scenarios:
|
||||
* User says "remember this", "keep this in mind", "note that", or similar
|
||||
* User shares personal preferences (e.g., "I prefer Python over JavaScript")
|
||||
* User shares facts about themselves (e.g., "I'm a senior developer at Company X")
|
||||
* User gives standing instructions (e.g., "always respond in bullet points")
|
||||
* User shares project context (e.g., "I'm working on migrating our codebase to TypeScript")
|
||||
- update_memory: Update your personal memory document about the user.
|
||||
- Your current memory is already in <user_memory> in your context. The `chars` and
|
||||
`limit` attributes show your current usage and the maximum allowed size.
|
||||
- This is your curated long-term memory — the distilled essence of what you know about
|
||||
the user, not raw conversation logs.
|
||||
- Call update_memory ONLY when the user shares genuinely important long-term information:
|
||||
* Explicit requests: "remember this", "keep in mind", "note that"
|
||||
* Preferences: "I prefer X", "I like Y", "always do Z"
|
||||
* Facts: name, role, company, expertise, current projects
|
||||
* Standing instructions: response format, communication style
|
||||
- Do NOT call for trivial, temporary, or conversation-specific information.
|
||||
- Args:
|
||||
- content: The fact/preference to remember. Phrase it clearly:
|
||||
* "User prefers dark mode for all interfaces"
|
||||
* "User is a senior Python developer"
|
||||
* "User wants responses in bullet point format"
|
||||
* "User is working on project called ProjectX"
|
||||
- category: Type of memory:
|
||||
* "preference": User preferences (coding style, tools, formats)
|
||||
* "fact": Facts about the user (role, expertise, background)
|
||||
* "instruction": Standing instructions (response format, communication style)
|
||||
* "context": Current context (ongoing projects, goals, challenges)
|
||||
- Returns: Confirmation of saved memory
|
||||
- IMPORTANT: Only save information that would be genuinely useful for future conversations.
|
||||
Don't save trivial or temporary information.
|
||||
- updated_memory: The FULL updated markdown document (not a diff).
|
||||
Merge new facts with existing ones, update contradictions, remove outdated entries.
|
||||
Treat every update as a curation pass — consolidate, don't just append.
|
||||
Include inline dates (YYYY-MM) on entries where temporal context matters (facts that
|
||||
may change, decisions, context). Skip dates on timeless preferences and instructions.
|
||||
- Keep it concise and well under the character limit shown in <user_memory>.
|
||||
- Organize using markdown sections as appropriate (suggested but not required):
|
||||
## About the user — name, role, background, company (with date if it may change)
|
||||
## Preferences — languages, tools, frameworks, response style
|
||||
## Instructions — standing instructions, things to always/never do
|
||||
## Current context — ongoing projects, goals, deadlines (with date)
|
||||
""",
|
||||
"shared": """
|
||||
- save_memory: Save a fact, preference, or context to the team's shared memory for future reference.
|
||||
- Use this when the user or a team member says "remember this", "keep this in mind", or similar in this shared chat.
|
||||
- Use when the team agrees on something to remember (e.g., decisions, conventions).
|
||||
- Someone shares a preference or fact that should be visible to the whole team.
|
||||
- The saved information will be available in future shared conversations in this space.
|
||||
- update_memory: Update the team's shared memory document for this search space.
|
||||
- Your current team memory is already in <team_memory> in your context. The `chars`
|
||||
and `limit` attributes show current usage and the maximum allowed size.
|
||||
- This is the team's curated long-term memory — decisions, conventions, key facts.
|
||||
- Call update_memory ONLY when the team shares genuinely important long-term information:
|
||||
* Team decisions: "let's remember we decided to use X"
|
||||
* Conventions: coding standards, processes, naming patterns
|
||||
* Key facts: where things are, how things work, team structure
|
||||
* Priorities: active projects, deadlines, blockers
|
||||
- Do NOT call for trivial, temporary, or conversation-specific information.
|
||||
- Args:
|
||||
- content: The fact/preference/context to remember. Phrase it clearly, e.g. "API keys are stored in Vault", "The team prefers weekly demos on Fridays"
|
||||
- category: Type of memory. One of:
|
||||
* "preference": Team or workspace preferences
|
||||
* "fact": Facts the team agreed on (e.g., processes, locations)
|
||||
* "instruction": Standing instructions for the team
|
||||
* "context": Current context (e.g., ongoing projects, goals)
|
||||
- Returns: Confirmation of saved memory; returned context may include who added it (added_by).
|
||||
- IMPORTANT: Only save information that would be genuinely useful for future team conversations in this space.
|
||||
""",
|
||||
},
|
||||
"recall_memory": {
|
||||
"private": """
|
||||
- recall_memory: Retrieve relevant memories about the user for personalized responses.
|
||||
- Use this to access stored information about the user.
|
||||
- Trigger scenarios:
|
||||
* You need user context to give a better, more personalized answer
|
||||
* User references something they mentioned before
|
||||
* User asks "what do you know about me?" or similar
|
||||
* Personalization would significantly improve response quality
|
||||
* Before making recommendations that should consider user preferences
|
||||
- Args:
|
||||
- query: Optional search query to find specific memories (e.g., "programming preferences")
|
||||
- category: Optional filter by category ("preference", "fact", "instruction", "context")
|
||||
- top_k: Number of memories to retrieve (default: 5)
|
||||
- Returns: Relevant memories formatted as context
|
||||
- IMPORTANT: Use the recalled memories naturally in your response without explicitly
|
||||
stating "Based on your memory..." - integrate the context seamlessly.
|
||||
""",
|
||||
"shared": """
|
||||
- recall_memory: Recall relevant team memories for this space to provide contextual responses.
|
||||
- Use when you need team context to answer (e.g., "where do we store X?", "what did we decide about Y?").
|
||||
- Use when someone asks about something the team agreed to remember.
|
||||
- Use when team preferences or conventions would improve the response.
|
||||
- Args:
|
||||
- query: Optional search query to find specific memories. If not provided, returns the most recent memories.
|
||||
- category: Optional filter by category ("preference", "fact", "instruction", "context")
|
||||
- top_k: Number of memories to retrieve (default: 5, max: 20)
|
||||
- Returns: Relevant team memories and formatted context (may include added_by). Integrate naturally without saying "Based on team memory...".
|
||||
- updated_memory: The FULL updated markdown document (not a diff).
|
||||
Merge new facts with existing ones, update contradictions, remove outdated entries.
|
||||
Treat every update as a curation pass — consolidate, don't just append.
|
||||
Include inline dates (YYYY-MM) on decisions and time-sensitive entries.
|
||||
- Keep it concise and well under the character limit shown in <team_memory>.
|
||||
- Organize using markdown sections as appropriate (suggested but not required):
|
||||
## Team decisions — agreed-upon choices with rationale and date
|
||||
## Conventions — coding standards, tools, processes, naming patterns
|
||||
## Key facts — where things are, how things work, team structure
|
||||
## Current priorities — active projects, deadlines, blockers
|
||||
""",
|
||||
},
|
||||
}
|
||||
|
||||
_MEMORY_TOOL_EXAMPLES: dict[str, dict[str, str]] = {
|
||||
"save_memory": {
|
||||
"update_memory": {
|
||||
"private": """
|
||||
- User: "Remember that I prefer TypeScript over JavaScript"
|
||||
- Call: `save_memory(content="User prefers TypeScript over JavaScript for development", category="preference")`
|
||||
- User: "I'm a data scientist working on ML pipelines"
|
||||
- Call: `save_memory(content="User is a data scientist working on ML pipelines", category="fact")`
|
||||
- User: "Always give me code examples in Python"
|
||||
- Call: `save_memory(content="User wants code examples to be written in Python", category="instruction")`
|
||||
- Timeless preference, no date needed. You see the current <user_memory> and merge:
|
||||
update_memory(updated_memory="## About the user\\n- Senior developer\\n\\n## Preferences\\n- Prefers TypeScript over JavaScript\\n...")
|
||||
- User: "I actually moved to Google last month"
|
||||
- Fact that changes over time, include date:
|
||||
update_memory(updated_memory="## About the user\\n- Senior developer at Google (since 2026-03, previously Acme Corp)\\n...")
|
||||
""",
|
||||
"shared": """
|
||||
- User: "Remember that API keys are stored in Vault"
|
||||
- Call: `save_memory(content="API keys are stored in Vault", category="fact")`
|
||||
- User: "Let's remember that the team prefers weekly demos on Fridays"
|
||||
- Call: `save_memory(content="The team prefers weekly demos on Fridays", category="preference")`
|
||||
""",
|
||||
},
|
||||
"recall_memory": {
|
||||
"private": """
|
||||
- User: "What programming language should I use for this project?"
|
||||
- First recall: `recall_memory(query="programming language preferences")`
|
||||
- Then provide a personalized recommendation based on their preferences
|
||||
- User: "What do you know about me?"
|
||||
- Call: `recall_memory(top_k=10)`
|
||||
- Then summarize the stored memories
|
||||
""",
|
||||
"shared": """
|
||||
- User: "What did we decide about the release date?"
|
||||
- First recall: `recall_memory(query="release date decision")`
|
||||
- Then answer based on the team memories
|
||||
- User: "Where do we document onboarding?"
|
||||
- Call: `recall_memory(query="onboarding documentation")`
|
||||
- Then answer using the recalled team context
|
||||
- User: "Let's remember that we decided to use GraphQL"
|
||||
- Decision with date:
|
||||
update_memory(updated_memory="## Team decisions\\n- 2026-04: Adopted GraphQL over REST for new APIs\\n...")
|
||||
- User: "Our deploy process uses Railway auto-deploys"
|
||||
- Key fact, no date needed:
|
||||
update_memory(updated_memory="## Key facts\\n- Deploy pipeline: git push -> Railway auto-deploys in ~3min\\n...")
|
||||
""",
|
||||
},
|
||||
}
|
||||
|
|
@ -456,8 +418,7 @@ _ALL_TOOL_NAMES_ORDERED = [
|
|||
"generate_report",
|
||||
"generate_image",
|
||||
"scrape_webpage",
|
||||
"save_memory",
|
||||
"recall_memory",
|
||||
"update_memory",
|
||||
]
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue