mirror of
https://github.com/hansjone/oclaw.git
synced 2026-10-09 01:50:44 +08:00
fix(prompt): invalidate bootstrap cache on wiki changes
Add a session-bootstrap content signature to the executor prompt cache key so identity/wiki updates invalidate cached system prompts and take effect on the next turn. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
5fc0805c69
commit
b15ff4c31c
1 changed files with 57 additions and 0 deletions
|
|
@ -1,8 +1,11 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import hashlib
|
||||
import threading
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
from oclaw.platform.config.paths import PROJECT_ROOT
|
||||
from oclaw.runtime.memory_stage import render_memory_context_block
|
||||
from oclaw.runtime.project_context_prompt import build_project_context_block
|
||||
from oclaw.runtime.skills_prompt import build_skills_catalog_block
|
||||
|
|
@ -19,6 +22,59 @@ _EXECUTOR_STATIC_PROMPT_CACHE_LOCK = threading.Lock()
|
|||
_EXECUTOR_STATIC_PROMPT_CACHE: dict[tuple[Any, ...], str] = {}
|
||||
|
||||
|
||||
def _file_stat_signature(path: Path) -> str:
|
||||
try:
|
||||
st = path.stat()
|
||||
return f"{path.as_posix()}:{int(st.st_mtime_ns)}:{int(st.st_size)}"
|
||||
except Exception:
|
||||
return f"{path.as_posix()}:missing"
|
||||
|
||||
|
||||
def _session_bootstrap_content_signature(*, skill_binding_role: str | None, workspace_dir: str | None) -> str:
|
||||
"""Best-effort signature for session-bootstrap content sources.
|
||||
|
||||
When this signature changes, cached executor system prompts are invalidated,
|
||||
so the next turn rebuilds project context and re-runs bootstrap hooks.
|
||||
"""
|
||||
repo = Path(PROJECT_ROOT).resolve()
|
||||
role = str(skill_binding_role or "").strip().lower()
|
||||
ws = Path(workspace_dir).expanduser().resolve() if str(workspace_dir or "").strip() else None
|
||||
|
||||
targets: list[Path] = []
|
||||
# session-bootstrap static source files
|
||||
targets.append((repo / "runtime" / "skills" / "session-bootstrap" / "SOUL.md").resolve())
|
||||
targets.append((repo / "runtime" / "skills" / "session-bootstrap" / "IDENTITY.md").resolve())
|
||||
# wiki global memory/improvement sources
|
||||
targets.append((repo / "data" / "wiki" / "improvement" / "learnings.md").resolve())
|
||||
targets.append((repo / "data" / "wiki" / "improvement" / "errors.md").resolve())
|
||||
targets.append((repo / "data" / "wiki" / "improvement" / "feature-requests.md").resolve())
|
||||
|
||||
core_dir = (repo / "data" / "wiki" / "core").resolve()
|
||||
if core_dir.exists() and core_dir.is_dir():
|
||||
for p in sorted(core_dir.glob("*.md"), key=lambda x: x.name.lower()):
|
||||
targets.append(p.resolve())
|
||||
|
||||
if role:
|
||||
role_dir = (repo / "data" / "wiki" / "experts" / role).resolve()
|
||||
if role_dir.exists() and role_dir.is_dir():
|
||||
for p in sorted(role_dir.glob("*.md"), key=lambda x: x.name.lower()):
|
||||
targets.append(p.resolve())
|
||||
|
||||
if ws is not None:
|
||||
mem_dir = (ws / "memory").resolve()
|
||||
if mem_dir.exists() and mem_dir.is_dir():
|
||||
mem_files = [p for p in mem_dir.glob("*.md") if p.is_file()]
|
||||
mem_files.sort(key=lambda p: p.stat().st_mtime if p.exists() else 0.0, reverse=True)
|
||||
if mem_files:
|
||||
targets.append(mem_files[0].resolve())
|
||||
|
||||
h = hashlib.sha256()
|
||||
for p in targets:
|
||||
h.update(_file_stat_signature(p).encode("utf-8", errors="ignore"))
|
||||
h.update(b"\n")
|
||||
return h.hexdigest()[:24]
|
||||
|
||||
|
||||
def _executor_prompt_settings_signature(store: Any) -> tuple[str, ...]:
|
||||
keys = (
|
||||
"AIA_SKILL_RUNTIME_ENABLED",
|
||||
|
|
@ -145,6 +201,7 @@ def get_executor_prompt_static(
|
|||
bool(tools is not None),
|
||||
int(bool(excl)),
|
||||
str(lane_seg or ""),
|
||||
_session_bootstrap_content_signature(skill_binding_role=skill_binding_role, workspace_dir=workspace_dir),
|
||||
)
|
||||
with _EXECUTOR_STATIC_PROMPT_CACHE_LOCK:
|
||||
cached = _EXECUTOR_STATIC_PROMPT_CACHE.get(cache_key)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue