mirror of
https://github.com/kuhyx/testsAndMisc.git
synced 2026-11-10 21:47:02 +01:00
Some checks are pending
dependency freshness / dependencies on newest stable (push) Waiting to run
md-naming / markdown naming convention (push) Waiting to run
Pre-commit checks / pre-commit (${{ matrix.group }}) (mypy, mypy) (push) Waiting to run
Pre-commit checks / pre-commit (${{ matrix.group }}) (pylint, pylint) (push) Waiting to run
Pre-commit checks / pre-commit (${{ matrix.group }}) (rest, ) (push) Waiting to run
Pre-commit checks / pre-commit (${{ matrix.group }}) (shellcheck, shellcheck) (push) Waiting to run
Python tests / test (push) Waiting to run
repo-contract / repo contract (push) Waiting to run
Shell tests / shell-tests (push) Waiting to run
Shell tests / lib-tests (push) Waiting to run
Shell tests / arch-tests (push) Waiting to run
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JThjboXTeZ3yJPBzxMx5wS
105 lines
3.5 KiB
Python
105 lines
3.5 KiB
Python
"""Pure readers for individual transcript records and content blocks.
|
|
|
|
Split from :mod:`walk` so the record-level rules (what counts as a typed
|
|
prompt, how a status tag or a commit hash is recognised) are testable without a
|
|
file and the walker stays under the file-length cap.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import os
|
|
from pathlib import Path
|
|
import re
|
|
from typing import Any
|
|
|
|
from python_pkg.token_audit.discover import WRAPPER
|
|
|
|
PROMPT_CHARS = 120
|
|
LEVER_HEADING = "Candidate levers (rule-based)"
|
|
# kuhy's convention: every final reply ends on one of these status tags.
|
|
TAG = re.compile(r"^\W*(DONE|RUNNING|QUESTION|NEEDS ACTION)\W*:", re.MULTILINE)
|
|
COMMAND = re.compile(r"<command-name>\s*(\S+?)\s*</command-name>")
|
|
# `git commit` prints `[branch sha] subject`, also through finish_auto.sh.
|
|
COMMIT_LINE = re.compile(
|
|
r"^\[[^\]\s]+(?: \(root-commit\))? ([0-9a-f]{7,40})\]", re.MULTILINE
|
|
)
|
|
REPO_HINT = re.compile(r"(?:git\s+-C|\bcd)\s+(\"[^\"]+\"|'[^']+'|[^\s;&|]+)")
|
|
_SKIP_PREFIXES = ("[Request interrupted", "Caveat:")
|
|
|
|
|
|
def text_of(content: object) -> str:
|
|
"""Flatten a message/tool-result ``content`` into plain text."""
|
|
if isinstance(content, str):
|
|
return content
|
|
if not isinstance(content, list):
|
|
return ""
|
|
parts = [
|
|
str(block.get("text") or "")
|
|
for block in content
|
|
if isinstance(block, dict) and block.get("type") == "text"
|
|
]
|
|
return "\n".join(parts)
|
|
|
|
|
|
def prompt_text(record: dict[str, Any]) -> str | None:
|
|
"""The typed text of a real user prompt, or ``None`` for anything else.
|
|
|
|
Excludes tool results, ``isMeta`` / compact-summary records, interrupts,
|
|
and harness-injected ``<tag>`` blocks. A slash command keeps its name.
|
|
"""
|
|
if record.get("type") != "user" or record.get("isMeta"):
|
|
return None
|
|
if record.get("isCompactSummary") or record.get("isVisibleInTranscriptOnly"):
|
|
return None
|
|
message = record.get("message")
|
|
content = message.get("content") if isinstance(message, dict) else None
|
|
if isinstance(content, list) and any(
|
|
isinstance(b, dict) and b.get("type") == "tool_result" for b in content
|
|
):
|
|
return None
|
|
raw = text_of(content)
|
|
command = COMMAND.search(raw)
|
|
text = WRAPPER.sub("", raw).strip()
|
|
if command is not None and not text:
|
|
text = command.group(1)
|
|
if not text or text.startswith(_SKIP_PREFIXES):
|
|
return None
|
|
return " ".join(text.split())[:PROMPT_CHARS]
|
|
|
|
|
|
def final_tag(text: str) -> str | None:
|
|
"""The last status tag in a reply, or ``None`` when it carries none."""
|
|
found = TAG.findall(text)
|
|
return found[-1] if found else None
|
|
|
|
|
|
def commit_shas(text: str) -> list[str]:
|
|
"""Commit hashes printed by ``git commit`` in a tool result."""
|
|
return COMMIT_LINE.findall(text)
|
|
|
|
|
|
def repo_hint(command: str, cwd: str | None) -> str:
|
|
"""The repository a commit command ran in: ``-C``/``cd`` target, else cwd."""
|
|
match = REPO_HINT.search(command)
|
|
target = match.group(1).strip("\"'") if match else (cwd or "")
|
|
if not target:
|
|
return ""
|
|
path = Path(target).expanduser()
|
|
if cwd and not path.is_absolute():
|
|
path = Path(cwd) / path
|
|
return os.path.normpath(path)
|
|
|
|
|
|
def lever_table(text: str) -> str | None:
|
|
"""The markdown table following the candidate-levers heading, if any."""
|
|
at = text.find(LEVER_HEADING)
|
|
if at < 0:
|
|
return None
|
|
rows: list[str] = []
|
|
for line in text[at:].splitlines()[1:]:
|
|
if line.startswith("|"):
|
|
rows.append(line)
|
|
elif rows:
|
|
break
|
|
return "\n".join(rows) if rows else None
|