mirror of
https://github.com/Strategic-Automation/violin.git
synced 2026-08-14 12:33:37 +02:00
Record research receipts for semantic unlocks
Record research receipts for semantic unlocks
This commit is contained in:
@@ -167,6 +167,12 @@ def _post_tool_call_hook(tool_name=None, args=None, result=None, duration_ms=0,
|
||||
if tool_name == "execute_code" and isinstance(args, dict):
|
||||
with contextlib.suppress(Exception):
|
||||
code_execution_audit.record_completion(args.get("code"), result, duration_ms)
|
||||
if tool_name in {"web_search", "web_extract"}:
|
||||
session_id = str(kwargs.get("session_id") or "")
|
||||
eng_dir = _SESSION_ENGAGEMENTS.get(session_id)
|
||||
if eng_dir:
|
||||
with contextlib.suppress(Exception):
|
||||
state.record_research_attempt(eng_dir, tool_name, not bool(result is None))
|
||||
if tool_name not in {"violin_record_ptt", "violin_review_batch"}:
|
||||
return
|
||||
args = args if isinstance(args, dict) else {}
|
||||
|
||||
@@ -332,7 +332,8 @@ def record_semantic_review(
|
||||
next_technique.strip().lower()
|
||||
and next_technique.strip().lower() != technique.strip().lower()
|
||||
)
|
||||
if lock and research_attempted and pivoted:
|
||||
research_after_lock = bool((data.get("research_attempts") or []) and lock)
|
||||
if lock and research_after_lock and pivoted:
|
||||
data.pop("lock", None)
|
||||
elif count >= 5:
|
||||
data["lock"] = {
|
||||
@@ -345,6 +346,25 @@ def record_semantic_review(
|
||||
return mutate_json(path, record)
|
||||
|
||||
|
||||
def record_research_attempt(eng_dir: str | Path, tool_name: str, success: bool) -> None:
|
||||
"""Record an actual web research-tool attempt for semantic-lock recovery."""
|
||||
|
||||
path = _state_dir(eng_dir) / _SEMANTIC_FILE
|
||||
|
||||
def record(data: dict[str, Any]) -> None:
|
||||
attempts = data.setdefault("research_attempts", [])
|
||||
attempts.append(
|
||||
{
|
||||
"tool": tool_name,
|
||||
"success": success,
|
||||
"timestamp": datetime.now(UTC).isoformat().replace("+00:00", "Z"),
|
||||
}
|
||||
)
|
||||
data["research_attempts"] = attempts[-20:]
|
||||
|
||||
mutate_json(path, record)
|
||||
|
||||
|
||||
def semantic_lock(eng_dir: str | Path) -> dict[str, Any] | None:
|
||||
return read_json(_state_dir(eng_dir) / _SEMANTIC_FILE).get("lock")
|
||||
|
||||
|
||||
@@ -32,7 +32,8 @@ def test_semantic_reviews_warn_then_hard_lock_and_require_research_pivot(tmp_pat
|
||||
|
||||
assert _review(tmp_path, research_attempted=True)["locked"]
|
||||
assert _review(tmp_path, next_technique="parameter-discovery")["locked"]
|
||||
unlocked = _review(tmp_path, research_attempted=True, next_technique="parameter-discovery")
|
||||
state.record_research_attempt(tmp_path, "web_search", True)
|
||||
unlocked = _review(tmp_path, next_technique="parameter-discovery")
|
||||
assert not unlocked["locked"]
|
||||
assert state.semantic_lock(tmp_path) is None
|
||||
|
||||
|
||||
Reference in New Issue
Block a user