Update README.MD and add nano-claude-code v3.0 + original-source-code/src
- README.MD: add original-source-code and nano-claude-code sections, update overview table (4 subprojects), add v3.0 news entry, expand comparison table with memory/multi-agent/skills dimensions - nano-claude-code v3.0: multi-agent package (multi_agent/), memory package (memory/), skill package (skill/) with built-in /commit and /review skills, context compression (compaction.py), tool registry plugin system, diff view, 17 slash commands, 18 built-in tools, 101 tests (~5000 lines total) - original-source-code/src: add raw TypeScript source tree (1884 files) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
216
nano-claude-code/memory/tools.py
Normal file
216
nano-claude-code/memory/tools.py
Normal file
@@ -0,0 +1,216 @@
|
||||
"""Memory tool registrations: MemorySave, MemoryDelete, MemorySearch.
|
||||
|
||||
Importing this module registers the three tools into the central registry.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
from datetime import datetime
|
||||
|
||||
from tool_registry import ToolDef, register_tool
|
||||
from .store import MemoryEntry, save_memory, delete_memory, load_index
|
||||
from .context import find_relevant_memories
|
||||
from .scan import scan_all_memories, format_memory_manifest
|
||||
|
||||
|
||||
# ── Tool implementations ───────────────────────────────────────────────────
|
||||
|
||||
def _memory_save(params: dict, config: dict) -> str:
|
||||
"""Save or update a persistent memory entry."""
|
||||
entry = MemoryEntry(
|
||||
name=params["name"],
|
||||
description=params["description"],
|
||||
type=params["type"],
|
||||
content=params["content"],
|
||||
created=datetime.now().strftime("%Y-%m-%d"),
|
||||
)
|
||||
scope = params.get("scope", "user")
|
||||
save_memory(entry, scope=scope)
|
||||
|
||||
scope_label = "project" if scope == "project" else "user"
|
||||
return f"Memory saved: '{entry.name}' [{entry.type}/{scope_label}]"
|
||||
|
||||
|
||||
def _memory_delete(params: dict, config: dict) -> str:
|
||||
"""Delete a persistent memory entry by name."""
|
||||
name = params["name"]
|
||||
scope = params.get("scope", "user")
|
||||
delete_memory(name, scope=scope)
|
||||
return f"Memory deleted: '{name}' (scope: {scope})"
|
||||
|
||||
|
||||
def _memory_search(params: dict, config: dict) -> str:
|
||||
"""Search memories by keyword query with optional AI relevance filtering."""
|
||||
query = params["query"]
|
||||
use_ai = params.get("use_ai", False)
|
||||
max_results = params.get("max_results", 5)
|
||||
|
||||
results = find_relevant_memories(
|
||||
query, max_results=max_results, use_ai=use_ai, config=config
|
||||
)
|
||||
|
||||
if not results:
|
||||
return f"No memories found matching '{query}'."
|
||||
|
||||
lines = [f"Found {len(results)} relevant memory/memories for '{query}':", ""]
|
||||
for r in results:
|
||||
freshness = f" ⚠ {r['freshness_text']}" if r["freshness_text"] else ""
|
||||
lines.append(
|
||||
f"[{r['type']}/{r['scope']}] {r['name']}\n"
|
||||
f" {r['description']}\n"
|
||||
f" {r['content'][:200]}{'...' if len(r['content']) > 200 else ''}"
|
||||
f"{freshness}"
|
||||
)
|
||||
return "\n\n".join(lines)
|
||||
|
||||
|
||||
def _memory_list(params: dict, config: dict) -> str:
|
||||
"""List all memory entries with their manifest (type, scope, age, description)."""
|
||||
headers = scan_all_memories()
|
||||
if not headers:
|
||||
return "No memories stored."
|
||||
|
||||
scope_filter = params.get("scope", "all")
|
||||
if scope_filter != "all":
|
||||
headers = [h for h in headers if h.scope == scope_filter]
|
||||
if not headers:
|
||||
return f"No {scope_filter} memories stored."
|
||||
|
||||
manifest = format_memory_manifest(headers)
|
||||
return f"{len(headers)} memory/memories:\n\n{manifest}"
|
||||
|
||||
|
||||
# ── Tool registrations ─────────────────────────────────────────────────────
|
||||
|
||||
register_tool(ToolDef(
|
||||
name="MemorySave",
|
||||
schema={
|
||||
"name": "MemorySave",
|
||||
"description": (
|
||||
"Save a persistent memory entry as a markdown file with frontmatter. "
|
||||
"Use for information that should persist across conversations: "
|
||||
"user preferences, feedback/corrections, project context, or external references. "
|
||||
"Do NOT save: code patterns, architecture, git history, or task state.\n\n"
|
||||
"For feedback/project memories, structure content as: "
|
||||
"rule/fact, then **Why:** and **How to apply:** lines."
|
||||
),
|
||||
"input_schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "Human-readable name (becomes the filename slug)",
|
||||
},
|
||||
"type": {
|
||||
"type": "string",
|
||||
"enum": ["user", "feedback", "project", "reference"],
|
||||
"description": (
|
||||
"user=preferences/role, feedback=guidance on how to work, "
|
||||
"project=ongoing work/decisions, reference=external system pointers"
|
||||
),
|
||||
},
|
||||
"description": {
|
||||
"type": "string",
|
||||
"description": "Short one-line description (used for relevance decisions — be specific)",
|
||||
},
|
||||
"content": {
|
||||
"type": "string",
|
||||
"description": "Body text. For feedback/project: rule/fact + **Why:** + **How to apply:**",
|
||||
},
|
||||
"scope": {
|
||||
"type": "string",
|
||||
"enum": ["user", "project"],
|
||||
"description": (
|
||||
"'user' (default) = ~/.nano_claude/memory/ shared across projects; "
|
||||
"'project' = .nano_claude/memory/ local to this project"
|
||||
),
|
||||
},
|
||||
},
|
||||
"required": ["name", "type", "description", "content"],
|
||||
},
|
||||
},
|
||||
func=_memory_save,
|
||||
read_only=False,
|
||||
concurrent_safe=False,
|
||||
))
|
||||
|
||||
register_tool(ToolDef(
|
||||
name="MemoryDelete",
|
||||
schema={
|
||||
"name": "MemoryDelete",
|
||||
"description": "Delete a persistent memory entry by name.",
|
||||
"input_schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {"type": "string", "description": "Name of the memory to delete"},
|
||||
"scope": {
|
||||
"type": "string",
|
||||
"enum": ["user", "project"],
|
||||
"description": "Scope to delete from (default: 'user')",
|
||||
},
|
||||
},
|
||||
"required": ["name"],
|
||||
},
|
||||
},
|
||||
func=_memory_delete,
|
||||
read_only=False,
|
||||
concurrent_safe=False,
|
||||
))
|
||||
|
||||
register_tool(ToolDef(
|
||||
name="MemorySearch",
|
||||
schema={
|
||||
"name": "MemorySearch",
|
||||
"description": (
|
||||
"Search persistent memories by keyword. Returns matching entries with "
|
||||
"content preview and staleness warning for old memories. "
|
||||
"Set use_ai=true to use AI-powered relevance ranking (costs a small API call)."
|
||||
),
|
||||
"input_schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"query": {"type": "string", "description": "Search query"},
|
||||
"max_results": {
|
||||
"type": "integer",
|
||||
"description": "Maximum results to return (default: 5)",
|
||||
},
|
||||
"use_ai": {
|
||||
"type": "boolean",
|
||||
"description": "Use AI relevance ranking (default: false = keyword only)",
|
||||
},
|
||||
"scope": {
|
||||
"type": "string",
|
||||
"enum": ["user", "project", "all"],
|
||||
"description": "Which scope to search (default: 'all')",
|
||||
},
|
||||
},
|
||||
"required": ["query"],
|
||||
},
|
||||
},
|
||||
func=_memory_search,
|
||||
read_only=True,
|
||||
concurrent_safe=True,
|
||||
))
|
||||
|
||||
register_tool(ToolDef(
|
||||
name="MemoryList",
|
||||
schema={
|
||||
"name": "MemoryList",
|
||||
"description": (
|
||||
"List all memory entries with type, scope, age, and description. "
|
||||
"Useful for reviewing what's been remembered before deciding to save or delete."
|
||||
),
|
||||
"input_schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"scope": {
|
||||
"type": "string",
|
||||
"enum": ["user", "project", "all"],
|
||||
"description": "Which scope to list (default: 'all')",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
func=_memory_list,
|
||||
read_only=True,
|
||||
concurrent_safe=True,
|
||||
))
|
||||
Reference in New Issue
Block a user