def recall_memory(*, description: str, name: str = "recall_memory") -> Tool:
r"""Create an explicit, read-only search tool for the requester's memories."""
async def handler(*, query: str, max_items: int = 12) -> ToolResult:
if not isinstance(query, str):
return ToolResult(ToolOutcome.FAILED, content="memory query must be a string", is_error=True)
if len(query) > 200:
return ToolResult(ToolOutcome.FAILED, content="memory query exceeds 200 characters", is_error=True)
if isinstance(max_items, bool) or not isinstance(max_items, int) or not 1 <= max_items <= 50:
return ToolResult(ToolOutcome.FAILED, content="max_items must be an integer from 1 to 50", is_error=True)
try:
store, namespace, owner_key = await _memory_context()
except MemoryIdentityConflict:
return _memory_identity_conflict()
if store is None or namespace is None:
return _memory_not_configured()
text = query.strip()
if not text:
return ToolResult(ToolOutcome.FAILED, content="memory query must not be empty", is_error=True)
records = await store.recall(namespace=namespace, owner_key=owner_key, query=text, limit=max_items)
return ToolResult(
ToolOutcome.COMPLETED,
content={"memories": [{"scope": record.scope, "content": record.content} for record in records]},
)
return Tool(
name=name,
description=description,
input_schema={
"type": "object",
"properties": {
"query": {"type": "string", "minLength": 1, "maxLength": 200},
"max_items": {"type": "integer", "minimum": 1, "maximum": 50},
},
"required": ["query"],
"additionalProperties": False,
},
handler=handler,
)