Bust executor prompt cache on workspace SKILL.md layout changes

Add workspace_skills_layout_signature (hash of paths + mtimes + sizes) and fold it into get_executor_prompt_static and manager prebuild cache keys. Add tests for signature drift and cache invalidation.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
oliver 2026-05-11 16:28:16 +08:00
parent c33ca303a2
commit 939a734e76
4 changed files with 112 additions and 0 deletions

View file

@ -4,6 +4,7 @@ from pathlib import Path
import pytest
from oclaw.runtime.skills import workspace_skills_layout_signature
from oclaw.runtime.system_prompt import build_oclaw_executor_system_prompt
from oclaw.runtime.types import OclawMemoryContext
from oclaw.platform.persistence.sqlite_store import SqliteStore
@ -129,6 +130,79 @@ def test_executor_static_prompt_cache_invalidates_on_settings_change(monkeypatch
assert calls["n"] == 2
def test_workspace_skills_layout_signature_changes_on_skill_md_edit(monkeypatch: pytest.MonkeyPatch, tmp_path: Path) -> None:
root = tmp_path / "skills_root_sig"
(root / "pkg").mkdir(parents=True)
f = root / "pkg" / "SKILL.md"
f.write_text("---\nname: x\ndescription: d\n---\n", encoding="utf-8")
monkeypatch.setenv("AIA_SKILLS_ROOT", str(root))
a = workspace_skills_layout_signature()
f.write_text("---\nname: x\ndescription: d\n---\n\nbody", encoding="utf-8")
b = workspace_skills_layout_signature()
assert a != b
def test_executor_static_prompt_cache_invalidates_on_workspace_skills_layout_change(monkeypatch: pytest.MonkeyPatch) -> None:
from oclaw.runtime import system_prompt as sp
class DummyStore:
def get_setting(self, key: str) -> str:
_ = key
return ""
class DummyReg:
pass
calls = {"n": 0}
sig = {"v": "layout-a"}
def _skills_block(**kwargs) -> str:
_ = kwargs
calls["n"] += 1
return "skills-block"
monkeypatch.setattr(sp, "expert_workspace_signature_token", lambda: ("sig",))
monkeypatch.setattr(sp, "workspace_skills_layout_signature", lambda: sig["v"])
monkeypatch.setattr(sp, "build_project_context_block", lambda **kwargs: "")
monkeypatch.setattr(sp, "build_skills_catalog_block", _skills_block)
monkeypatch.setattr(
sp,
"render_runtime_prompt",
lambda prompt_id, variables, strict: f"{prompt_id}\n{variables.get('skills_catalog') or ''}",
)
store = DummyStore()
reg = DummyReg()
_ = sp.get_executor_prompt_static(
store=store,
tools=reg, # type: ignore[arg-type]
base_url="",
base_system="base",
workspace_dir=None,
skill_binding_role="generalist",
)
_ = sp.get_executor_prompt_static(
store=store,
tools=reg, # type: ignore[arg-type]
base_url="",
base_system="base",
workspace_dir=None,
skill_binding_role="generalist",
)
assert calls["n"] == 1
sig["v"] = "layout-b"
_ = sp.get_executor_prompt_static(
store=store,
tools=reg, # type: ignore[arg-type]
base_url="",
base_system="base",
workspace_dir=None,
skill_binding_role="generalist",
)
assert calls["n"] == 2
def test_executor_static_prompt_cache_invalidates_on_skill_role_binding_change(monkeypatch: pytest.MonkeyPatch) -> None:
from oclaw.runtime import system_prompt as sp