fix(plugins): resolve handoff issues found in live hosts
This commit is contained in:
@@ -7,4 +7,5 @@
|
||||
- Preserve the session title, project, readable compaction context, supported images, and completed tool calls/results. Hidden reasoning and harness configuration are excluded. Unsupported records, opaque compaction, and unfinished responses fail explicitly.
|
||||
- Requires Python 3.11+. Pi save additionally requires Node.js 22.19+ for its native SDK; list/resume work on Node.js 20. Other source formats may require an explicit completed transcript, directory, and title.
|
||||
- Handoff needs no destination CLI, model call, or Mem0 credentials. Resources are private, uniquely named files; saving preserves full supported context and resume returns it as historical evidence without replaying tools.
|
||||
- Live host checks: align the handoff skill’s shell permission with its quoted command; accept Codex harness/usage metadata without importing it as conversation; resolve DeepSeek attachment storage through its native optional-service API.
|
||||
- Replace strict before-answer and repeated-search instructions with focused optional retrieval. Existing context can answer the question without another search. Search scoping, retrieval limits, and capture scheduling are unchanged.
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"revision": "2ac8f2f9a9927f1d88e745432a66d66deab1e8d4",
|
||||
"files": {
|
||||
"handoff_engine.py": "5786e4f24e1145ce26867d18c78fafc8e3de4097b5494815073a2e09df15ea11",
|
||||
"handoff_sources.py": "0eeae1d92ebd8db58400531fba44e950eb5e3d4e7547375d14c1222041d6fe5f"
|
||||
"handoff_sources.py": "23957113d048179ba014bab39e121818507d61f976eebb6cfb66558f17fde0d1"
|
||||
},
|
||||
"artifacts": [
|
||||
"session_handoff.py",
|
||||
|
||||
@@ -153,7 +153,9 @@ def _codex(records: list[dict], warnings: list[str]) -> tuple[list[dict], dict]:
|
||||
elif kind == "event_msg":
|
||||
if payload.get("type") == "thread_rolled_back":
|
||||
raise engine.HandoffError("Codex rollback requires a native active-context export.")
|
||||
elif kind != "turn_context":
|
||||
# Codex 0.153+ persists harness snapshots and accounting beside response_items.
|
||||
# These records are not conversation history and must not become user context.
|
||||
elif kind not in {"turn_context", "world_state", "token_usage_record"}:
|
||||
raise engine.HandoffError(f"Unsupported Codex rollout record: {kind!r}.")
|
||||
result = []
|
||||
for item in items:
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
name: handoff
|
||||
description: Save a native session as a shared Mem0 handoff resource that another plugin can resume. Run only on explicit user request.
|
||||
disable-model-invocation: true
|
||||
allowed-tools: Bash(python3 {{PLUGIN_ROOT}}/core/session_handoff.py *)
|
||||
allowed-tools: Bash(python3 "{{PLUGIN_ROOT}}/core/session_handoff.py" *)
|
||||
---
|
||||
|
||||
# Save shared session context
|
||||
|
||||
@@ -2,6 +2,7 @@ from __future__ import annotations
|
||||
|
||||
import json
|
||||
import sys
|
||||
from fnmatch import fnmatchcase
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
@@ -139,3 +140,14 @@ def test_handoff_is_bundled_with_host_appropriate_invocation(host: str, tmp_path
|
||||
assert "!`" not in skill
|
||||
assert "NATIVE_TRANSCRIPT_PATH" in skill
|
||||
assert "Never guess the latest session" in skill
|
||||
|
||||
|
||||
def test_handoff_preprocessor_matches_its_declared_permission(tmp_path: Path) -> None:
|
||||
root = build("claude-code", "native", tmp_path / "plugin with spaces")
|
||||
skill = (root / "skills" / "handoff" / "SKILL.md").read_text()
|
||||
rule = next(line for line in skill.splitlines() if line.startswith("allowed-tools: Bash("))
|
||||
pattern = rule.removeprefix("allowed-tools: Bash(").removesuffix(")")
|
||||
command = next(line for line in skill.splitlines() if line.startswith("!`")).removeprefix("!`").removesuffix("`")
|
||||
assert fnmatchcase(command, pattern), (
|
||||
"Claude's preprocessor command must match its permission rule, including quotes"
|
||||
)
|
||||
|
||||
@@ -103,6 +103,8 @@ def test_codex_native_rollout_keeps_response_items_and_excludes_harness(tmp_path
|
||||
# openai/codex: codex-rs/protocol/src/protocol.rs and persisted response_item payloads.
|
||||
records = [
|
||||
{"type": "session_meta", "payload": {"id": "codex-session", "cwd": str(tmp_path)}},
|
||||
{"type": "world_state", "payload": {"full": True, "state": {"agents_md": {"text": "harness config"}}}},
|
||||
{"type": "token_usage_record", "payload": {"input_tokens": 123, "output_tokens": 45}},
|
||||
{"type": "response_item", "payload": message("developer", "harness config")},
|
||||
{"type": "response_item", "payload": {"type": "reasoning", "encrypted_content": "opaque"}},
|
||||
{"type": "response_item", "payload": message("user", "Keep user")},
|
||||
|
||||
Reference in New Issue
Block a user