fix: align AI-recent notes with WebUI prefill hook

This commit is contained in:
AJV20
2026-05-27 22:44:55 -04:00
parent 5bc3cdb3dd
commit 8757a8fbf6
3 changed files with 62 additions and 3 deletions
+4
View File
@@ -3,6 +3,10 @@
## [Unreleased]
### Fixed
- The third-party notes drawer's “Recently used by AI” Joplin list now follows the WebUI-specific `webui_prefill_messages_script` hook when configured, including argv-style hooks such as `[python3, /path/to/recall.py]`, before falling back to the legacy generic `prefill_messages_script`.
## [v0.51.150] — 2026-05-28 — Release DV (stage-batch32 — single-PR reasoning-effort agent metadata)
### Fixed
+25 -3
View File
@@ -12879,17 +12879,39 @@ _JOPLIN_AI_RECALL_NOTE_PRIORITY = [
]
def _joplin_prefill_script_path() -> Path | None:
cfg = get_config()
path_value = cfg.get("prefill_messages_script") if isinstance(cfg, dict) else None
def _script_path_from_config_value(path_value) -> Path | None:
"""Return the likely recall script path from a string or argv-style hook."""
if not path_value:
return None
try:
if isinstance(path_value, (list, tuple)):
candidates = [str(part).strip() for part in path_value if str(part).strip()]
# Hooks commonly use [python, /path/to/script.py]. Prefer the first
# Python-ish script argument over the interpreter so AI-recent notes
# reflect the configured recall source rather than "python3".
for candidate in candidates:
if candidate.endswith((".py", ".sh", ".bash")):
return Path(candidate).expanduser()
if candidates:
return Path(candidates[-1]).expanduser()
return None
return Path(str(path_value)).expanduser()
except Exception:
return None
def _joplin_prefill_script_path() -> Path | None:
cfg = get_config()
if not isinstance(cfg, dict):
return None
# The browser notes drawer should mirror the WebUI-specific recall hook when
# configured. Fall back to the legacy generic session prefill script only for
# deployments that have not opted into WebUI dynamic recall.
return _script_path_from_config_value(
cfg.get("webui_prefill_messages_script") or cfg.get("prefill_messages_script")
)
def _joplin_recall_note_refs(script_path: Path | None = None) -> list[dict]:
"""Find stable Joplin note IDs referenced by the configured recall script.
+33
View File
@@ -200,6 +200,39 @@ def test_joplin_recent_ai_notes_uses_configured_prefill_script(monkeypatch, tmp_
assert all(note["used_reason"] == "automatic_recall" for note in notes)
def test_joplin_recent_ai_notes_prefers_webui_prefill_script_hook(monkeypatch, tmp_path):
from api import routes
legacy_script = tmp_path / "legacy_context.py"
legacy_script.write_text('CURRENT_CONTEXT_ID = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"\n', encoding="utf-8")
webui_script = tmp_path / "webui_context.py"
webui_script.write_text(
'CURRENT_CONTEXT_ID = "5ba9ab822c344115939205ca4e8eaec0"\n'
'OPEN_ISSUES_ID = "623aeb6e55cb4aa39a0541f2ac09aa36"\n',
encoding="utf-8",
)
monkeypatch.setattr(routes, "get_config", lambda: {
"prefill_messages_script": str(legacy_script),
"webui_prefill_messages_script": ["python3", str(webui_script)],
})
def fake_get(path, params=None):
note_id = path.rsplit("/", 1)[-1]
assert note_id != "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
titles = {
"5ba9ab822c344115939205ca4e8eaec0": "Current Context",
"623aeb6e55cb4aa39a0541f2ac09aa36": "Open Issues",
}
return {"id": note_id, "title": titles[note_id], "updated_time": 123, "parent_id": "folder"}
monkeypatch.setattr(routes, "_joplin_api_get", fake_get)
notes = routes._joplin_recent_ai_notes(limit=2)
assert [note["title"] for note in notes] == ["Current Context", "Open Issues"]
def test_external_notes_ui_uses_minimal_lucide_icons_for_ai_recent_notes():
from pathlib import Path