chore(integrations): plugin updates, pi-agent auto-recall, and version bumps (#6011)
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "mem0",
|
||||
"version": "0.2.11",
|
||||
"version": "0.2.12",
|
||||
"description": "Persistent memory for Claude Code. Remembers decisions, patterns, and preferences across sessions.",
|
||||
"author": {
|
||||
"name": "Mem0",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "mem0",
|
||||
"version": "0.2.11",
|
||||
"version": "0.2.12",
|
||||
"description": "Persistent memory for Codex. Remembers decisions, patterns, and preferences across sessions.",
|
||||
"author": {
|
||||
"name": "Mem0",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "mem0",
|
||||
"version": "0.2.11",
|
||||
"version": "0.2.12",
|
||||
"description": "Mem0 memory layer for AI applications. Add persistent memory, personalization, and semantic search using the Mem0 Platform MCP server.",
|
||||
"author": {
|
||||
"name": "Mem0",
|
||||
|
||||
@@ -463,7 +463,7 @@ Identity context (resolved at plugin startup):
|
||||
}),
|
||||
|
||||
search_memories: tool({
|
||||
description: "Search through stored memories.",
|
||||
description: "Search stored memories by semantic meaning. Use this proactively before answering when the request may depend on the user's past work, preferences, decisions, or environment -- relevant memories are not always auto-injected. For multi-part or comparative questions, run several searches with different phrasings and combine the results rather than stopping after one (multi-hop).",
|
||||
args: {
|
||||
query: tool.schema.string().describe("Search query"),
|
||||
user_id: tool.schema.string().optional().describe("User ID"),
|
||||
@@ -489,7 +489,7 @@ Identity context (resolved at plugin startup):
|
||||
}),
|
||||
|
||||
get_memories: tool({
|
||||
description: "List all memories in the memory store, optionally filtered.",
|
||||
description: "List or browse stored memories without a search query -- useful for auditing what is remembered or paging through everything in a scope. To find memories relevant to a question, use search_memories instead (it ranks by semantic relevance).",
|
||||
args: {
|
||||
user_id: tool.schema.string().optional().describe("User ID"),
|
||||
app_id: tool.schema.string().optional().describe("App/Project ID"),
|
||||
@@ -513,7 +513,7 @@ Identity context (resolved at plugin startup):
|
||||
}),
|
||||
|
||||
get_memory: tool({
|
||||
description: "Retrieve a specific memory by its ID.",
|
||||
description: "Fetch one memory by its exact ID (e.g. an ID returned by search_memories or get_memories) to read its full content and metadata.",
|
||||
args: {
|
||||
id: tool.schema.string().describe("The ID of the memory to retrieve"),
|
||||
},
|
||||
@@ -525,7 +525,7 @@ Identity context (resolved at plugin startup):
|
||||
}),
|
||||
|
||||
update_memory: tool({
|
||||
description: "Update the content or metadata of a specific memory.",
|
||||
description: "Update an existing memory in place when a stored fact has changed -- requires the memory ID. Preserves the ID and history, so prefer this over deleting and re-adding.",
|
||||
args: {
|
||||
id: tool.schema.string().describe("The ID of the memory to update"),
|
||||
text: tool.schema.string().optional().describe("New text content for the memory"),
|
||||
@@ -542,7 +542,7 @@ Identity context (resolved at plugin startup):
|
||||
}),
|
||||
|
||||
delete_memory: tool({
|
||||
description: "Delete specific memories by their ID.",
|
||||
description: "Delete one or more memories by ID when they are wrong, obsolete, or the user asks to forget them. Irreversible -- only delete what is clearly no longer wanted.",
|
||||
args: {
|
||||
id: tool.schema.string().describe("The ID of the memory to delete"),
|
||||
},
|
||||
@@ -555,7 +555,7 @@ Identity context (resolved at plugin startup):
|
||||
}),
|
||||
|
||||
delete_all_memories: tool({
|
||||
description: "Delete all memories.",
|
||||
description: "Delete ALL memories in the given scope. Destructive and irreversible -- only use when the user explicitly asks to wipe their memory. Never call speculatively.",
|
||||
args: {
|
||||
user_id: tool.schema.string().optional().describe("User ID whose memories to delete"),
|
||||
app_id: tool.schema.string().optional().describe("App ID whose memories to delete"),
|
||||
@@ -577,7 +577,7 @@ Identity context (resolved at plugin startup):
|
||||
}),
|
||||
|
||||
delete_entities: tool({
|
||||
description: "Delete user/agent/app/run entities and all their associated memories.",
|
||||
description: "Delete entire user/agent/app/run entities and every memory attached to them. Destructive and irreversible -- only on explicit user request to remove a whole user, agent, or project.",
|
||||
args: {
|
||||
user_id: tool.schema.string().optional().describe("User ID of the entity to delete"),
|
||||
agent_id: tool.schema.string().optional().describe("Agent ID of the entity to delete"),
|
||||
@@ -597,7 +597,7 @@ Identity context (resolved at plugin startup):
|
||||
}),
|
||||
|
||||
list_entities: tool({
|
||||
description: "List all user/agent/app/run entities.",
|
||||
description: "List the user/agent/app/run entities that have memories. Use to discover which scopes exist before searching, listing, or deleting within a specific one.",
|
||||
args: {
|
||||
page: tool.schema.number().optional().describe("Page number"),
|
||||
page_size: tool.schema.number().optional().describe("Page size"),
|
||||
@@ -613,7 +613,7 @@ Identity context (resolved at plugin startup):
|
||||
}),
|
||||
|
||||
get_event_status: tool({
|
||||
description: "Check the status of an asynchronous memory operation by event_id.",
|
||||
description: "Check whether an asynchronous memory write (add/update/delete) finished, using the event_id that call returned. Poll this when you need to confirm a write was persisted before relying on it.",
|
||||
args: {
|
||||
event_id: tool.schema.string().describe("The ID of the event/async operation to check"),
|
||||
},
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@mem0/opencode-plugin",
|
||||
"version": "0.2.0",
|
||||
"version": "0.2.1",
|
||||
"type": "module",
|
||||
"description": "Mem0 persistent memory plugin for OpenCode — add, search, and manage memories across sessions",
|
||||
"main": "dist/index.js",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"id": "mem0",
|
||||
"name": "mem0",
|
||||
"version": "0.1.3",
|
||||
"version": "0.1.4",
|
||||
"description": "Persistent semantic memory for Antigravity agents. Cross-session, user-level recall via the Mem0 Platform MCP server. 16 slash commands, lifecycle hooks for auto-capture and metadata enforcement.",
|
||||
"author": { "name": "Mem0", "email": "support@mem0.ai" },
|
||||
"publisher": "mem0ai",
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
#!/usr/bin/env bash
|
||||
# Hook: UserPromptSubmit
|
||||
#
|
||||
# Fires on every user message. Instead of pre-searching mem0 with the
|
||||
# raw prompt, this injects a decision rubric telling the agent when
|
||||
# and how to search itself. The agent has more context than this
|
||||
# script does -- let it decide.
|
||||
# Fires on every user message. Prefetches memories relevant to the current
|
||||
# prompt (so relevant context is guaranteed) and also injects a decision
|
||||
# rubric telling the agent when to search further itself -- including
|
||||
# follow-up searches for multi-part questions. Prefetch can be disabled
|
||||
# with MEM0_PREFETCH=false.
|
||||
#
|
||||
# Input: JSON on stdin (prompt, session_id, cwd, transcript_path)
|
||||
# Output: Decision rubric injected into Claude's context (exit 0)
|
||||
@@ -152,12 +153,37 @@ else:
|
||||
fi
|
||||
fi
|
||||
|
||||
# Query-driven prefetch: search mem0 with the current prompt and inject the top
|
||||
# matches so relevant memories are guaranteed in context, not left for the agent
|
||||
# to fetch. Skipped on resume (handled above with targeted queries) and when
|
||||
# MEM0_PREFETCH=false.
|
||||
if [ -z "$HAS_RESUME" ] && [ "${MEM0_PREFETCH:-true}" != "false" ]; then
|
||||
PREFETCH_RESULTS=$(PYTHONPATH="$SCRIPT_DIR" MEM0_SEARCH_USER="$USER_ID" MEM0_SEARCH_QUERY="$PROMPT" python3 -c "
|
||||
import os, sys
|
||||
sys.path.insert(0, os.environ.get('PYTHONPATH', '.'))
|
||||
from _search import search_memories, format_results_for_context, should_rerank
|
||||
|
||||
api_key = os.environ.get('MEM0_API_KEY', '')
|
||||
user_id = os.environ.get('MEM0_SEARCH_USER', 'default')
|
||||
project_id = os.environ.get('MEM0_PROJECT_ID', 'unknown')
|
||||
query = os.environ.get('MEM0_SEARCH_QUERY', '')
|
||||
|
||||
results = search_memories(api_key, user_id, project_id, query, top_k=5, rerank=should_rerank())
|
||||
if results:
|
||||
print(format_results_for_context(results, heading='Relevant memories (auto-retrieved for this request)'))
|
||||
" 2>/dev/null || echo "")
|
||||
|
||||
if [ -n "$PREFETCH_RESULTS" ]; then
|
||||
_PROMPT_CTX="${_PROMPT_CTX:+${_PROMPT_CTX}\n}${PREFETCH_RESULTS}"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -n "$HAS_REMEMBER" ]; then
|
||||
_PROMPT_CTX="${_PROMPT_CTX:+${_PROMPT_CTX}\n}Remember intent detected. The /mem0:remember skill auto-classifies, sets confidence=1.0, and stores verbatim."
|
||||
fi
|
||||
|
||||
if [ -z "$RUBRIC_ALREADY_SHOWN" ]; then
|
||||
_PROMPT_CTX="${_PROMPT_CTX:+${_PROMPT_CTX}\n}Mem0 searches apply when user references past work, decision questions, errors, or non-trivial tasks. Queries use noun-phrases, 2-4 parallel calls with different metadata.type filters, and include user_id + app_id."
|
||||
_PROMPT_CTX="${_PROMPT_CTX:+${_PROMPT_CTX}\n}Mem0 searches apply when user references past work, decision questions, errors, or non-trivial tasks. Queries use noun-phrases, 2-4 parallel calls with different metadata.type filters, and include user_id + app_id. For multi-part or comparative questions, run follow-up searches and combine results before answering -- one search is rarely enough."
|
||||
touch "$RUBRIC_FLAG" 2>/dev/null || true
|
||||
fi
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@ def _run_hook(prompt: str, env_overrides: dict | None = None, session_id: str =
|
||||
"MEM0_RESOLVED_USER_ID": "testuser",
|
||||
"MEM0_PROJECT_ID": "test-project",
|
||||
"MEM0_BRANCH": "main",
|
||||
"MEM0_PREFETCH": "false",
|
||||
}
|
||||
if env_overrides:
|
||||
env.update(env_overrides)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"id": "openclaw-mem0",
|
||||
"name": "Memory (Mem0)",
|
||||
"description": "Mem0 memory backend for OpenClaw — platform (mem0.ai cloud) or self-hosted open-source. Auto-recall and auto-capture are opt-in (disabled by default). Supports OpenAI, Anthropic, Ollama (fully local), Qdrant, and PGVector providers.",
|
||||
"version": "1.0.11",
|
||||
"version": "1.0.14",
|
||||
"kind": "memory",
|
||||
"skills": ["skills"],
|
||||
"commandAliases": [
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@mem0/openclaw-mem0",
|
||||
"version": "1.0.13",
|
||||
"version": "1.0.14",
|
||||
"type": "module",
|
||||
"description": "Mem0 memory backend for OpenClaw — platform or self-hosted open-source",
|
||||
"license": "Apache-2.0",
|
||||
|
||||
@@ -11,7 +11,7 @@ export function createMemoryAddTool(deps: ToolDeps) {
|
||||
return {
|
||||
name: "memory_add",
|
||||
label: "Memory Add",
|
||||
description: "Save important information in long-term memory via Mem0. Use for preferences, facts, decisions, and anything worth remembering.",
|
||||
description: "Save important information to long-term memory via Mem0. Do this proactively, without being asked, whenever the user shares a preference, fact, decision, rule, or anything worth recalling in future sessions. Group related facts under one category.",
|
||||
parameters: Type.Object({
|
||||
text: Type.Optional(Type.String({ description: "Single fact to remember" })),
|
||||
facts: Type.Optional(Type.Array(Type.String(), { description: "Array of facts to store. ALL must share the same category." })),
|
||||
|
||||
@@ -8,7 +8,7 @@ export function createMemoryDeleteTool(deps: ToolDeps) {
|
||||
return {
|
||||
name: "memory_delete",
|
||||
label: "Memory Delete",
|
||||
description: "Delete memories. Provide memoryId, query to search-and-delete, or all:true for bulk deletion (requires confirm:true).",
|
||||
description: "Delete memories that are wrong, obsolete, or that the user asks to forget. Provide memoryId, a query to search-and-delete, or all:true for bulk deletion (requires confirm:true). Irreversible -- never delete speculatively or wipe everything without an explicit request.",
|
||||
parameters: Type.Object({
|
||||
memoryId: Type.Optional(Type.String({ description: "Specific memory ID to delete" })),
|
||||
query: Type.Optional(Type.String({ description: "Search query to find and delete" })),
|
||||
|
||||
@@ -7,7 +7,7 @@ export function createMemoryGetTool(deps: ToolDeps) {
|
||||
return {
|
||||
name: "memory_get",
|
||||
label: "Memory Get",
|
||||
description: "Retrieve a specific memory by its ID from Mem0.",
|
||||
description: "Fetch one memory by its exact ID (e.g. an ID returned by memory_search or memory_list) to read its full content and metadata.",
|
||||
parameters: Type.Object({
|
||||
memoryId: Type.String({ description: "The memory ID to retrieve" }),
|
||||
}),
|
||||
|
||||
@@ -8,7 +8,7 @@ export function createMemoryListTool(deps: ToolDeps) {
|
||||
return {
|
||||
name: "memory_list",
|
||||
label: "Memory List",
|
||||
description: "List all stored memories for a user or agent.",
|
||||
description: "List or browse all stored memories for a user or agent without a query -- useful for auditing what is remembered. To find memories relevant to a question, use memory_search instead (it ranks by semantic relevance).",
|
||||
parameters: Type.Object({
|
||||
userId: Type.Optional(Type.String({ description: "User ID (default: configured)" })),
|
||||
agentId: Type.Optional(Type.String({ description: "Agent ID namespace" })),
|
||||
|
||||
@@ -8,7 +8,7 @@ export function createMemorySearchTool(deps: ToolDeps) {
|
||||
return {
|
||||
name: "memory_search",
|
||||
label: "Memory Search",
|
||||
description: "Search through long-term memories stored in Mem0.",
|
||||
description: "Search long-term memories stored in Mem0 by semantic meaning. Use this proactively before answering when the request may depend on the user's past work, preferences, or decisions -- relevant memories are not always already in context. For multi-part or comparative questions, run several searches with different phrasings and combine the results rather than stopping after one (multi-hop).",
|
||||
parameters: Type.Object({
|
||||
query: Type.String({ description: "Search query" }),
|
||||
limit: Type.Optional(Type.Number({ description: `Max results (default: ${cfg.topK})` })),
|
||||
|
||||
@@ -8,7 +8,7 @@ export function createMemoryUpdateTool(deps: ToolDeps) {
|
||||
return {
|
||||
name: "memory_update",
|
||||
label: "Memory Update",
|
||||
description: "Update an existing memory's text in place. Atomic and preserves history.",
|
||||
description: "Update an existing memory's text in place when a stored fact has changed -- requires the memory ID. Atomic and preserves the ID and history, so prefer this over deleting and re-adding.",
|
||||
parameters: Type.Object({
|
||||
memoryId: Type.String({ description: "The memory ID to update" }),
|
||||
text: Type.String({ description: "The new text (replaces old)" }),
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@mem0/pi-agent-plugin",
|
||||
"version": "0.1.2",
|
||||
"version": "0.1.3",
|
||||
"type": "module",
|
||||
"description": "Mem0 memory extension for Pi Agent persistent, scoped, semantic memory across sessions and projects",
|
||||
"license": "Apache-2.0",
|
||||
|
||||
@@ -20,7 +20,7 @@ const DEFAULT_CONFIG: Mem0Config = {
|
||||
userId: "",
|
||||
autoCapture: true,
|
||||
defaultScope: "project",
|
||||
contextInjection: false,
|
||||
contextInjection: true,
|
||||
searchThreshold: 0.3,
|
||||
dream: DEFAULT_DREAM,
|
||||
};
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
|
||||
import { resolveUserId } from "./entry.ts";
|
||||
import { resolveUserId, buildRecallContext } from "./entry.ts";
|
||||
|
||||
describe("resolveUserId", () => {
|
||||
const originalEnv = { ...process.env };
|
||||
@@ -32,3 +32,34 @@ describe("resolveUserId", () => {
|
||||
expect(result.length).toBeGreaterThan(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe("buildRecallContext", () => {
|
||||
const search = async () => ({
|
||||
results: [{ id: "m1", memory: "User prefers pnpm over npm", categories: ["preferences"] }],
|
||||
});
|
||||
|
||||
it("returns empty when disabled", async () => {
|
||||
expect(await buildRecallContext("which pm?", false, search)).toBe("");
|
||||
});
|
||||
|
||||
it("returns empty for a blank prompt", async () => {
|
||||
expect(await buildRecallContext(" ", true, search)).toBe("");
|
||||
});
|
||||
|
||||
it("returns empty when no memories match", async () => {
|
||||
expect(await buildRecallContext("hi", true, async () => ({ results: [] }))).toBe("");
|
||||
});
|
||||
|
||||
it("injects recalled memory text when enabled and matches exist", async () => {
|
||||
const out = await buildRecallContext("which pm?", true, search);
|
||||
expect(out).toContain("User prefers pnpm over npm");
|
||||
expect(out).toContain("mem0-relevant-memories");
|
||||
});
|
||||
|
||||
it("swallows search errors so the turn is never blocked", async () => {
|
||||
const out = await buildRecallContext("hi", true, async () => {
|
||||
throw new Error("boom");
|
||||
});
|
||||
expect(out).toBe("");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -2,6 +2,7 @@ import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
||||
import MemoryClient from "mem0ai";
|
||||
import { loadConfig, CONFIG_DIR } from "./config/index.ts";
|
||||
import { detectAppId, detectRunId, resolveSearchFilters } from "./memory/scoping.ts";
|
||||
import { formatMemoryList } from "./memory/formatting.ts";
|
||||
import { registerMemoryTool } from "./memory/tools.ts";
|
||||
import { registerCommands } from "./commands.ts";
|
||||
import { setupAutoCapture } from "./capture/index.ts";
|
||||
@@ -26,6 +27,31 @@ export function resolveUserId(configUserId: string): string {
|
||||
try { return os.userInfo().username; } catch { return "default"; }
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the auto-recall context block for a turn: search memory with the user's
|
||||
* prompt and format the top matches so they are guaranteed in context instead of
|
||||
* relying on the agent to call the tool. Best-effort — returns "" when disabled,
|
||||
* the prompt is blank, nothing matches, or the search fails; it must never block
|
||||
* the turn.
|
||||
*/
|
||||
export async function buildRecallContext(
|
||||
prompt: string,
|
||||
enabled: boolean,
|
||||
search: (query: string) => Promise<{ results?: unknown[] }>,
|
||||
): Promise<string> {
|
||||
if (!enabled) return "";
|
||||
const q = prompt.trim();
|
||||
if (!q) return "";
|
||||
try {
|
||||
const res = await search(q);
|
||||
const memories = (res.results ?? []) as Parameters<typeof formatMemoryList>[0];
|
||||
if (memories.length === 0) return "";
|
||||
return `<mem0-relevant-memories>\nRetrieved automatically for the current request. This is a shallow first pass — search mem0_memory for more if you need it.\n${formatMemoryList(memories)}\n</mem0-relevant-memories>`;
|
||||
} catch {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
export default function mem0Extension(pi: ExtensionAPI): void {
|
||||
const config = loadConfig();
|
||||
|
||||
@@ -84,6 +110,15 @@ export default function mem0Extension(pi: ExtensionAPI): void {
|
||||
pi.on("before_agent_start", async (event, _ctx) => {
|
||||
let extra = MEMORY_POLICY;
|
||||
|
||||
// Guaranteed retrieval: prefetch memories relevant to this prompt so the
|
||||
// agent always has them, rather than depending on it to call the tool.
|
||||
const recall = await buildRecallContext(
|
||||
event.prompt ?? "",
|
||||
config.contextInjection,
|
||||
(q) => mem0.search(q, { filters: resolveSearchFilters("project", scopeCtx) }),
|
||||
);
|
||||
if (recall) extra += "\n\n" + recall;
|
||||
|
||||
if (config.dream.enabled && config.dream.auto && !dreamTriggered && !dreamChecked) {
|
||||
const gates = checkCheapGates(CONFIG_DIR, config.dream);
|
||||
if (gates.proceed) {
|
||||
|
||||
@@ -138,35 +138,54 @@ export function registerMemoryTool(
|
||||
name: "mem0_memory",
|
||||
label: "Mem0 Memory",
|
||||
description:
|
||||
"Search, add, update, and manage persistent semantic memories powered by Mem0. Memories persist across sessions and devices. Output is truncated to 200 lines / 50KB.",
|
||||
"Search, add, update, and manage persistent semantic memories powered by Mem0. Memories persist across sessions and devices. Use action \"search\" proactively -- before answering anything that may depend on what the user told you earlier -- and run multiple searches with different phrasings for multi-part questions. Output is truncated to 200 lines / 50KB.",
|
||||
promptSnippet: "Semantic memory search and storage via Mem0",
|
||||
promptGuidelines: [
|
||||
'Use mem0_memory with action "search" when the user asks about past conversations, preferences, or decisions',
|
||||
'Use mem0_memory with action "search" proactively whenever the request may depend on the user\'s past work, preferences, decisions, or environment -- not only when they explicitly mention the past',
|
||||
'For multi-part or comparative questions, run several searches with different phrasings and combine the results before answering -- one search is rarely enough',
|
||||
'Use mem0_memory with action "add" to save important facts, preferences, goals, decisions, or lessons the user shares',
|
||||
'Use mem0_memory with action "update" to modify an existing memory — requires memory_id and content. Preserves the memory ID',
|
||||
"Always use the default project scope unless the user EXPLICITLY asks to search across all projects — only then use scope \"global\"",
|
||||
"Do NOT pass scope at all for normal queries — omitting it uses the project default automatically",
|
||||
],
|
||||
parameters: Type.Object({
|
||||
action: StringEnum([
|
||||
"search",
|
||||
"add",
|
||||
"get_all",
|
||||
"update",
|
||||
"delete",
|
||||
"delete_all",
|
||||
] as const),
|
||||
action: StringEnum(
|
||||
[
|
||||
"search",
|
||||
"add",
|
||||
"get_all",
|
||||
"update",
|
||||
"delete",
|
||||
"delete_all",
|
||||
] as const,
|
||||
{
|
||||
description:
|
||||
"Memory operation to run: \"search\" (semantic recall -- use proactively before answering; run several with different phrasings for multi-part questions), \"add\" (save a new fact/preference/decision), \"get_all\" (list everything in scope, no query needed), \"update\" (replace an existing memory's text by id), \"delete\" (remove one memory by id), \"delete_all\" (wipe every memory in the scope -- destructive, only on explicit request).",
|
||||
},
|
||||
),
|
||||
query: Type.Optional(
|
||||
Type.String({ description: "Search query or memory text" }),
|
||||
Type.String({
|
||||
description:
|
||||
"Search text -- required for action \"search\". Use a focused noun-phrase; for multi-part questions run several searches with different phrasings.",
|
||||
}),
|
||||
),
|
||||
content: Type.Optional(
|
||||
Type.String({ description: "Memory content to store or updated text" }),
|
||||
Type.String({
|
||||
description:
|
||||
"Memory text -- required for action \"add\" (the fact to store) and \"update\" (the replacement text).",
|
||||
}),
|
||||
),
|
||||
memory_id: Type.Optional(
|
||||
Type.String({ description: "Memory ID for update or delete" }),
|
||||
Type.String({
|
||||
description:
|
||||
"Target memory's ID -- required for \"update\" and \"delete\". Use an ID returned by a prior \"search\" or \"get_all\".",
|
||||
}),
|
||||
),
|
||||
scope: Type.Optional(
|
||||
StringEnum(["project", "session", "global"] as const),
|
||||
StringEnum(["project", "session", "global"] as const, {
|
||||
description:
|
||||
"Where to read/write: \"project\" (default -- this repo), \"session\" (this run only), or \"global\" (across ALL projects; only when the user explicitly wants cross-project recall). Omit for normal queries.",
|
||||
}),
|
||||
),
|
||||
}),
|
||||
async execute(toolCallId, params, signal, onUpdate, ctx) {
|
||||
|
||||
@@ -1,16 +1,18 @@
|
||||
export const MEMORY_POLICY = `<mem0-memory-policy>
|
||||
You have persistent semantic memory via the mem0_memory tool, powered by Mem0.
|
||||
You have persistent semantic memory via the mem0_memory tool, powered by Mem0. Relevant memories may be auto-injected under <mem0-relevant-memories>, but that retrieval is shallow — treat it as a starting point, not the full picture.
|
||||
|
||||
Memory is scoped to the current project by default. Do not change the scope unless explicitly asked.
|
||||
- "project" (default): memories for this project — use this for all normal queries
|
||||
Be proactive about retrieval:
|
||||
- Search memory BEFORE answering whenever the request could depend on the user's past work, preferences, decisions, environment, or anything they told you earlier — don't wait to be asked.
|
||||
- Check memory before asking the user something they may have already told you.
|
||||
- For multi-part, comparative, or "how did we…" questions, run SEVERAL searches with different phrasings and combine the results. One search is rarely enough — keep going until you have what you need (multi-hop).
|
||||
|
||||
Be proactive about saving:
|
||||
- Save important facts, preferences, goals, decisions, lessons learned, identity, relationships, and routines the user shares.
|
||||
|
||||
Scope (do not change unless explicitly asked):
|
||||
- "project" (default): memories for this project — use for all normal queries
|
||||
- "session": memories from this session only
|
||||
- "global": all memories across projects — ONLY use when the user explicitly asks for cross-project search
|
||||
|
||||
When to use memory:
|
||||
- Search when the user references past conversations, preferences, or decisions
|
||||
- Save important facts, user preferences, key decisions, and lessons learned
|
||||
- Check memory before asking the user something they may have already told you
|
||||
- Save identity information, goals, relationships, and routines the user shares
|
||||
- "global": all memories across projects — ONLY when the user explicitly asks for cross-project search
|
||||
|
||||
Memory persists across sessions and devices via Mem0's cloud.
|
||||
</mem0-memory-policy>`;
|
||||
|
||||
Reference in New Issue
Block a user