101 lines
3.3 KiB
Python
101 lines
3.3 KiB
Python
#!/usr/bin/env python3
|
|
"""Triage: classify recent AI-agent news items into categories.
|
|
|
|
Deterministic keyword rules over the item TITLE (headline focus).
|
|
Categories are checked in priority order; the first matching category wins.
|
|
Reads: /root/.hermes/wizard-outputs/sol/items.json
|
|
Writes: /root/.hermes/wizard-outputs/sol/triage.json, triage.md, checksum.txt
|
|
"""
|
|
import hashlib
|
|
import json
|
|
import os
|
|
|
|
SRC = "/root/.hermes/wizard-outputs/sol/items.json"
|
|
OUT = "/root/.hermes/wizard-outputs/sol"
|
|
|
|
KEY_RULES = [
|
|
("valuation", ["valuation", "valued", "value"]),
|
|
("security", ["security", "govern", "identity", "governance", "compliance"]),
|
|
("fundraise", ["raise", "funding round", "series", "round", "back", "funding"]),
|
|
("product", ["launch", "launching", "release", "platform", "announced"]),
|
|
]
|
|
|
|
CATEGORY_NAMES = {
|
|
"fundraise": "Fundraise",
|
|
"valuation": "Valuation",
|
|
"security": "Security",
|
|
"product": "Product",
|
|
}
|
|
|
|
|
|
def classify(title):
|
|
low = title.lower()
|
|
for category, kws in KEY_RULES:
|
|
for kw in kws:
|
|
if kw in low:
|
|
return category, kw
|
|
return "other", None
|
|
|
|
|
|
def main():
|
|
with open(SRC, encoding="utf-8") as f:
|
|
data = json.load(f)
|
|
|
|
results = []
|
|
counts = {"fundraise": 0, "valuation": 0, "security": 0, "product": 0, "other": 0}
|
|
|
|
for it in data["items"]:
|
|
category, matched = classify(it["title"])
|
|
results.append({
|
|
"n": it["n"],
|
|
"title": it["title"],
|
|
"url": it["url"],
|
|
"published": it["published"],
|
|
"category": category,
|
|
"category_name": CATEGORY_NAMES.get(category, category),
|
|
"matched_keyword": matched,
|
|
"evidence": "title contains keyword: %r" % (matched,),
|
|
})
|
|
counts[category] += 1
|
|
|
|
out = {
|
|
"schema": 1,
|
|
"source": data["source"],
|
|
"retrieved": data["retrieved"],
|
|
"total": len(results),
|
|
"categories": CATEGORY_NAMES,
|
|
"counts": counts,
|
|
"items": results,
|
|
}
|
|
|
|
os.makedirs(OUT, exist_ok=True)
|
|
|
|
with open(os.path.join(OUT, "triage.json"), "w", encoding="utf-8") as f:
|
|
json.dump(out, f, indent=2)
|
|
|
|
with open(os.path.join(OUT, "triage.md"), "w", encoding="utf-8") as f:
|
|
f.write("# AI-Agent News Triage\n\n")
|
|
f.write("Source: %s Retrieved: %s\n\n" % (data["source"], data["retrieved"]))
|
|
f.write("| # | Title | Category |\n|---|---|---|\n")
|
|
for r in results:
|
|
f.write("| %d | %s | %s |\n" % (r["n"], r["title"], r["category_name"]))
|
|
f.write("\n## Counts\n\n")
|
|
for k, v in counts.items():
|
|
f.write("- %s: %d\n" % (CATEGORY_NAMES.get(k, k), v))
|
|
f.write("\n## Methodology\n\n")
|
|
f.write("Deterministic keyword triage of the item title; categories checked in "
|
|
"priority order (valuation, security, fundraise, product, other); first "
|
|
"matching keyword wins.\n")
|
|
|
|
digest = hashlib.sha256(json.dumps(out, sort_keys=True).encode("utf-8")).hexdigest()
|
|
with open(os.path.join(OUT, "checksum.txt"), "w", encoding="utf-8") as f:
|
|
f.write(digest + " triage.json\n")
|
|
|
|
print("classified %d items" % len(results))
|
|
print("counts:", counts)
|
|
print("sha256:", digest)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|