refactor(integrations): shared agent plugin runtimes and native adapters (#7203)

This commit is contained in:
Kartik
2026-09-08 23:32:25 +05:30
committed by GitHub
parent dae67f74f5
commit 73e7b8763a
369 changed files with 31056 additions and 20464 deletions
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
"""Expose Mem0's memory search as one local Claude Code tool."""
"""Expose Mem0's memory search as one local coding-agent tool."""
from __future__ import annotations
@@ -11,13 +11,13 @@ from typing import Any
import telemetry
from memory_core import (
CODING_MEMORY_CATEGORY_NAMES,
PLUGIN_VERSION,
SEARCH_SCOPES,
format_search_result,
resolve_repo,
SEARCH_SCOPES,
search_memories,
)
PROTOCOL_VERSION = "2024-11-05"
TOOL_NAME = "search_memories"
TOOL_DESCRIPTION = (
@@ -30,8 +30,7 @@ TOOL_DESCRIPTION = (
"invocation works. The scope argument changes what is searched: 'repo' "
"(default) is the whole repository's shared memory plus your own "
"preferences, 'dir' narrows the shared part to the directory you are "
"working in, and 'mine' is your preferences alone. Pass run_id to look "
"at one earlier Claude Code session only."
"working in, and 'mine' is your preferences alone."
)
TOOL_SCHEMA = {
"type": "object",
@@ -65,8 +64,10 @@ TOOL_SCHEMA = {
"run_id": {
"type": "string",
"minLength": 1,
"maxLength": 200,
"description": "Optional Claude Code session ID. Restricts the search to memories written from that session.",
"description": (
"Optional coding-agent session ID. With any scope, restricts results to memories "
"saved in that session. Omit to recall memories across sessions."
),
},
},
"required": ["query"],
@@ -110,16 +111,17 @@ def _validate_arguments(
raise ToolInputError(f"scope must be one of {list(SEARCH_SCOPES)}.")
run_id = arguments.get("run_id")
if run_id is not None and (
not isinstance(run_id, str) or not run_id.strip() or len(run_id) > 200
):
raise ToolInputError("run_id must be a non-empty string of at most 200 characters.")
if run_id is not None:
if not isinstance(run_id, str) or not run_id.strip():
raise ToolInputError("run_id must be a non-empty string.")
run_id = run_id.strip()
return query, top_k, category, scope, run_id
def call_search_memories(arguments: Any) -> str:
def call_search_memories(arguments: Any, cwd: str | None = None) -> str:
query, top_k, category, scope, run_id = _validate_arguments(arguments)
repo = resolve_repo(os.environ.get("CLAUDE_PROJECT_DIR") or os.getcwd())
repo = resolve_repo(cwd or os.environ.get("CLAUDE_PROJECT_DIR") or os.getcwd())
result = search_memories(
None,
repo,
@@ -134,6 +136,19 @@ def call_search_memories(arguments: Any) -> str:
return format_search_result(result)
def _workspace_cwd(params: dict[str, Any]) -> str | None:
meta = params.get("_meta")
if not isinstance(meta, dict):
return None
metadata = meta.get("x-codex-turn-metadata")
if not isinstance(metadata, dict):
return None
workspaces = metadata.get("workspaces") or {}
if isinstance(workspaces, dict):
return next((path for path in workspaces if isinstance(path, str) and path), None)
return None
def _tool_response(text: str, *, is_error: bool = False) -> dict[str, Any]:
return {
"content": [{"type": "text", "text": text}],
@@ -157,7 +172,7 @@ def handle_request(message: Any) -> dict[str, Any] | None:
"result": {
"protocolVersion": requested or PROTOCOL_VERSION,
"capabilities": {"tools": {"listChanged": False}},
"serverInfo": {"name": "mem0", "version": "0.3.0"},
"serverInfo": {"name": "mem0", "version": PLUGIN_VERSION},
},
}
if method == "ping":
@@ -187,7 +202,9 @@ def handle_request(message: Any) -> dict[str, Any] | None:
result = _tool_response("Unknown Mem0 tool.", is_error=True)
else:
try:
result = _tool_response(call_search_memories(params.get("arguments")))
result = _tool_response(
call_search_memories(params.get("arguments"), _workspace_cwd(params))
)
except ToolInputError as exc:
result = _tool_response(str(exc), is_error=True)
except Exception: