Make recent memory title-only by default
This commit is contained in:
@@ -49,7 +49,7 @@ import webbrowser
|
||||
from datetime import datetime, timedelta, timezone
|
||||
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
|
||||
|
||||
DISCOVERY_VIEWS = {"paths", "summary", "metadata", "full"}
|
||||
DISCOVERY_VIEWS = {"titles", "paths", "summary", "metadata", "full"}
|
||||
DISCOVERY_DEFAULT_LIMIT = 25
|
||||
DISCOVERY_COMPACT_MAX_LIMIT = 10_000
|
||||
DISCOVERY_FULL_MAX_LIMIT = 10_000
|
||||
@@ -5196,7 +5196,7 @@ def normalize_discovery_view(args, default="summary"):
|
||||
warnings = []
|
||||
if requested:
|
||||
if requested not in DISCOVERY_VIEWS:
|
||||
raise RuntimeError("view must be paths, summary, metadata, or full")
|
||||
raise RuntimeError("view must be titles, paths, summary, metadata, or full")
|
||||
return requested, warnings
|
||||
if as_bool(args.get("include_content"), False):
|
||||
return "full", warnings
|
||||
@@ -5276,6 +5276,12 @@ def summarize_node(node, view="summary", preview_chars=240):
|
||||
return node
|
||||
metadata = node_metadata(node)
|
||||
status = node_status(node)
|
||||
if view == "titles":
|
||||
item = {
|
||||
"title": node.get("title") or metadata.get("title") or node.get("name") or pathlib.PurePosixPath(str(node.get("full_path") or "")).name,
|
||||
"full_path": node.get("full_path"),
|
||||
}
|
||||
return {key: value for key, value in item.items() if value not in (None, "")}
|
||||
if view == "paths":
|
||||
item = {
|
||||
"full_path": node.get("full_path"),
|
||||
@@ -8687,7 +8693,7 @@ def search_memory(args):
|
||||
|
||||
def recent_memory(args):
|
||||
limit = max(1, min(int(args.get("limit", 25)), 100))
|
||||
view, _warnings = normalize_discovery_view(args)
|
||||
view, _warnings = normalize_discovery_view(args, default="titles")
|
||||
query = {**args, "limit": limit, "view": view}
|
||||
for key in ["folder_path", "tag", "updated_before", "updated_after", "cursor"]:
|
||||
if args.get(key):
|
||||
@@ -10221,7 +10227,7 @@ def raw_tools():
|
||||
"q": {"type": "string", "description": "Search text. Natural language is accepted; distinctive nouns, paths, tags, or quoted phrases produce better matches than full instructions."},
|
||||
"mode": {"type": "string", "enum": ["hybrid", "server", "local"], "default": "hybrid"},
|
||||
"limit": {"type": "integer", "minimum": 1, "maximum": 100},
|
||||
"view": {"type": "string", "enum": ["paths", "summary", "metadata", "full"], "default": "summary"},
|
||||
"view": {"type": "string", "enum": ["titles", "paths", "summary", "metadata", "full"], "default": "summary"},
|
||||
"include_content": {"type": "boolean", "default": False, "description": "Legacy; use view='full' for body text. Ignored when view is set."},
|
||||
"active_only": {"type": "boolean", "default": False},
|
||||
"status": {"oneOf": [{"type": "string"}, {"type": "array", "items": {"type": "string"}}]},
|
||||
@@ -10243,7 +10249,7 @@ def raw_tools():
|
||||
"q": {"type": "string"},
|
||||
"cursor": {"type": "string"},
|
||||
"limit": {"type": "integer", "minimum": 1, "maximum": 10000},
|
||||
"view": {"type": "string", "enum": ["paths", "summary", "metadata", "full"], "default": "summary"},
|
||||
"view": {"type": "string", "enum": ["titles", "paths", "summary", "metadata", "full"], "default": "summary"},
|
||||
"include_content": {"type": "boolean", "default": False, "description": "Legacy; use view='full' for body text. Ignored when view is set."},
|
||||
"include_archived": {"type": "boolean", "default": False},
|
||||
"archived_only": {"type": "boolean", "default": False},
|
||||
@@ -10337,8 +10343,8 @@ def raw_tools():
|
||||
"properties": {
|
||||
"path": {"type": "string"},
|
||||
"limit": {"type": "integer", "minimum": 1, "maximum": 100},
|
||||
"view": {"type": "string", "enum": ["paths", "summary", "metadata", "full"], "default": "summary"},
|
||||
"include_content": {"type": "boolean", "default": False, "description": "Legacy; use view='full' for body text. Ignored when view is set."},
|
||||
"view": {"type": "string", "enum": ["titles", "paths", "summary", "metadata", "full"], "default": "titles"},
|
||||
"include_content": {"type": "boolean", "default": False, "description": "Legacy; use view='full' for body text. Ignored when view is set. nap_recent defaults to title-only output."},
|
||||
"preview_chars": {"type": "integer", "minimum": 80, "maximum": 1000, "default": 240},
|
||||
},
|
||||
"additionalProperties": False,
|
||||
@@ -10346,7 +10352,7 @@ def raw_tools():
|
||||
},
|
||||
{
|
||||
"name": "nap_recent",
|
||||
"description": "List recently updated project memory with optional folder, tag, and cursor filters.",
|
||||
"description": "List recently updated project memory as title/path pairs by default, with optional folder, tag, and cursor filters.",
|
||||
"inputSchema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@@ -10356,8 +10362,8 @@ def raw_tools():
|
||||
"updated_before": {"type": "string"},
|
||||
"updated_after": {"type": "string"},
|
||||
"limit": {"type": "integer", "minimum": 1, "maximum": 100},
|
||||
"view": {"type": "string", "enum": ["paths", "summary", "metadata", "full"], "default": "summary"},
|
||||
"include_content": {"type": "boolean", "default": False, "description": "Legacy; use view='full' for body text. Ignored when view is set."},
|
||||
"view": {"type": "string", "enum": ["titles", "paths", "summary", "metadata", "full"], "default": "titles"},
|
||||
"include_content": {"type": "boolean", "default": False, "description": "Legacy; use view='full' for body text. Ignored when view is set. nap_recent defaults to title-only output."},
|
||||
"active_only": {"type": "boolean", "default": False},
|
||||
"status": {"oneOf": [{"type": "string"}, {"type": "array", "items": {"type": "string"}}]},
|
||||
"exclude_status": {"oneOf": [{"type": "string"}, {"type": "array", "items": {"type": "string"}}]},
|
||||
|
||||
@@ -80,6 +80,30 @@ def test_node_discovery_allows_large_requested_limit(mod):
|
||||
assert len(calls) == 1
|
||||
|
||||
|
||||
def test_recent_memory_defaults_to_titles(mod):
|
||||
recent = node(
|
||||
"/notes/recent-title",
|
||||
"active",
|
||||
metadata={"title": "Readable Recent Title", "priority": "high"},
|
||||
tags=["recent"],
|
||||
content="large body that should not appear in the default recent response",
|
||||
node_type="note",
|
||||
)
|
||||
|
||||
def fake_request(method, path, payload=None, **kwargs):
|
||||
assert method == "GET"
|
||||
assert "/nodes?" in path
|
||||
return {"items": [recent], "next_cursor": None}
|
||||
|
||||
mod.request_json = fake_request
|
||||
result = mod.recent_memory({})
|
||||
assert result["ok"] is True
|
||||
assert result["view"] == "titles"
|
||||
assert result["items"] == [{"title": "Readable Recent Title", "full_path": "/notes/recent-title"}]
|
||||
assert "content_text" not in result["items"][0]
|
||||
assert "metadata_summary" not in result["items"][0]
|
||||
|
||||
|
||||
def test_rest_query_string_serializes_booleans_lowercase(mod):
|
||||
query = mod.rest_query_string({
|
||||
"folder_path": "/kanban",
|
||||
|
||||
Reference in New Issue
Block a user