File size: 4,246 Bytes
281c084 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 | """
Command-line interface for frontier-check.
Usage:
frontier-check "claim text"
frontier-check - # read claim from stdin
echo "claim" | frontier-check -
frontier-check --json "claim"
frontier-check --strict "claim"
frontier-check --selftest
"""
from __future__ import annotations
import argparse
import json
import sys
from dataclasses import asdict
from .model import Claim, frontier_check, self_test
def _result_to_json(result) -> dict:
return {
"claim": result.claim.text,
"status": result.assessment.status,
"reason": result.assessment.reason,
"theorem_used": result.assessment.theorem_used or None,
"papers": [
{"title": p.title, "year": p.year, "on_target": p.on_target}
for p in result.papers
],
"sub_claims": [
{"kind": s.kind, "text": s.text,
"verdict": s.verdict or None,
"evidence": s.evidence or None}
for s in result.sub_claims
],
"verdict": result.verdict,
"action": result.action,
"residual": result.residual,
}
def _render(result) -> str:
lines = []
lines.append("=" * 72)
lines.append(f"CLAIM: {result.claim.text}")
lines.append("=" * 72)
a = result.assessment
lines.append(f" [1] Status : {a.status}")
lines.append(f" {a.reason}")
if a.theorem_used:
lines.append(f" forbidden by: {a.theorem_used}")
if result.papers:
lines.append(f" [2] Retrieval: {len(result.papers)} paper(s)")
for p in result.papers:
flag = "target" if p.on_target else "background"
lines.append(f" - [{flag}] {p.title} ({p.year})")
else:
lines.append(" [2] Retrieval: none")
if result.sub_claims:
lines.append(" [3] Sub-claims:")
for s in result.sub_claims:
lines.append(f" [{s.kind:12s}] {s.text}")
if s.verdict:
lines.append(f" -> {s.verdict}: "
f"{s.evidence}")
label = "*** FRONTIER ***" if result.verdict == "FRONTIER" else result.verdict
lines.append(f" [4] Verdict: {label}")
if result.action:
lines.append(f" action : {result.action}")
if result.residual:
lines.append(f" residual : {result.residual}")
return "\n".join(lines)
def main(argv=None) -> int:
p = argparse.ArgumentParser(
prog="frontier-check",
description=(
"Route LLM claims by their training-data status. "
"FRONTIER is first-class."
),
)
p.add_argument(
"claim",
nargs="?",
default=None,
help="claim text, or '-' to read from stdin",
)
p.add_argument(
"--json",
action="store_true",
help="emit JSON instead of a rendered report",
)
p.add_argument(
"--strict",
action="store_true",
help="abort with exit code 1 if the self-test fails",
)
p.add_argument(
"--selftest",
action="store_true",
help="run the self-test and exit",
)
p.add_argument(
"--quiet",
action="store_true",
help="suppress the self-test banner",
)
args = p.parse_args(argv)
# Self-test runs on every invocation.
if not args.quiet:
passed, total = self_test(verbose=True)
else:
passed, total = self_test(verbose=False)
if args.selftest:
return 0 if passed == total else 1
if args.strict and passed < total:
print("\n--strict: self-test failed; aborting.", file=sys.stderr)
return 1
if args.claim is None:
p.print_help()
return 0
if args.claim == "-":
claim_text = sys.stdin.read().strip()
else:
claim_text = args.claim
if not claim_text:
print("empty claim", file=sys.stderr)
return 1
result = frontier_check(Claim(claim_text))
if args.json:
print(json.dumps(_result_to_json(result), indent=2, ensure_ascii=False))
else:
print()
print(_render(result))
return 0
if __name__ == "__main__":
sys.exit(main()) |