feat(plugins): share native session handoff and soften memory search

This commit is contained in:
kartik-mem0
2026-09-10 18:20:36 +05:30
parent 02f7a9b2c4
commit 82c32f993e
130 changed files with 16430 additions and 379 deletions
+35 -10
View File
@@ -41,6 +41,7 @@ TEMPLATE_TOKENS = {
"COMMAND_PREFIX",
"HARNESS_ID",
"HARNESS_NAME",
"HANDOFF_INSTRUCTIONS",
}
@@ -81,6 +82,30 @@ def replace_output(staged: Path, output: Path) -> Path:
return output
def handoff_instructions(host: str, plugin_root: str) -> str:
command = f'python3 "{plugin_root}/core/session_handoff.py"'
if host == "claude-code":
return (
"The transfer command has already run before model invocation:\n\n"
f'!`{command} --source claude-code --session "${{CLAUDE_SESSION_ID}}" --target codex --create --command-output`\n\n'
"Return the command output exactly. Do not retry the transfer or do any other work."
)
source = host if host != "coding-agent" else "SOURCE_HOST"
return (
f"The source is {host}. Ask for a completed native transcript path or a neutral handoff bundle "
"if none was supplied. Never guess the latest session. Do not create a summary from memory. "
"For the portable plugin, replace SOURCE_HOST with the actual supported native host.\n\n"
f'```bash\n{command} --source {source} --session "NATIVE_TRANSCRIPT_PATH" --target codex --create --command-output\n```\n\n'
"Quote the supplied path as one shell argument. Cursor and Antigravity transcripts need "
"`--cwd` with their source project directory; `--title` preserves a title absent from the export. "
"For a neutral bundle use `--bundle PATH` instead of `--source` and `--session`.\n\n"
"A still-running source or this skill's own shell call may leave an unfinished tool call. "
"In that case, return the error and show the same command for running from a terminal after "
"the source turn finishes. Never trim pending calls, automatically retry, or claim that a "
"partial memory capture is the complete conversation. Return the command output."
)
def _bundle_python(
staged: Path,
host: str,
@@ -103,17 +128,21 @@ def _bundle_python(
"COMMAND_PREFIX": "mem0",
"HARNESS_ID": host,
"HARNESS_NAME": host.replace("-", " ").title(),
"HANDOFF_INSTRUCTIONS": handoff_instructions(host, plugin_root),
}
for source in sorted(SHARED_SKILLS.glob("*/SKILL.md.tmpl")):
target = staged / "skills" / source.parent.name / "SKILL.md"
target.parent.mkdir(parents=True)
rendered = render_template(source.read_text(encoding="utf-8"), values)
if portable:
rendered = "\n".join(
line
for line in rendered.splitlines()
if not line.startswith(("argument-hint:", "disable-model-invocation:"))
) + "\n"
rendered = (
"\n".join(
line
for line in rendered.splitlines()
if not line.startswith(("argument-hint:", "disable-model-invocation:"))
)
+ "\n"
)
target.write_text(rendered, encoding="utf-8")
@@ -196,11 +225,7 @@ def bundle_drift(host: str, kind: str) -> list[str]:
generated = build(host, kind, Path(temporary) / "bundle")
errors: list[str] = []
for directory in ("core", "skills"):
expected = {
path.relative_to(generated)
for path in (generated / directory).rglob("*")
if path.is_file()
}
expected = {path.relative_to(generated) for path in (generated / directory).rglob("*") if path.is_file()}
actual = {
path.relative_to(target)
for path in (target / directory).rglob("*")
@@ -0,0 +1,5 @@
[
"claude_to_codex.py",
"session_handoff.py",
"handoff_sources.py"
]
@@ -0,0 +1,15 @@
import { copyFile, mkdir, readFile } from "node:fs/promises";
import { resolve } from "node:path";
import { fileURLToPath } from "node:url";
export async function packageHandoff(output = "dist") {
const files = JSON.parse(await readFile(new URL("./handoff-runtime.json", import.meta.url), "utf8"));
await mkdir(output, { recursive: true });
for (const name of files) {
await copyFile(new URL(`../python/${name}`, import.meta.url), resolve(output, name));
}
}
if (process.argv[1] && resolve(process.argv[1]) === fileURLToPath(import.meta.url)) {
await packageHandoff(process.argv[2]);
}