feat: add OpenClaw LLM scoring pipeline for all domains and surface in panel
This commit is contained in:
parent
75300a1005
commit
df0f0515a0
5
api.php
5
api.php
@ -33,12 +33,15 @@ if ($action === 'domains') {
|
||||
$prevRunId = $prev['run_id'] ?? '';
|
||||
|
||||
$sql = "SELECT d.domain, d.tld, d.score, d.status, d.keywords_json,
|
||||
ls.llm_score, ls.decision, ls.reason,
|
||||
CASE
|
||||
WHEN :prev = '' THEN 1
|
||||
WHEN EXISTS (SELECT 1 FROM domains p WHERE p.run_id = :prev AND p.domain = d.domain) THEN 0
|
||||
ELSE 1
|
||||
END AS is_new
|
||||
FROM domains d WHERE d.run_id = :run";
|
||||
FROM domains d
|
||||
LEFT JOIN llm_scores ls ON ls.run_id = d.run_id AND ls.domain = d.domain
|
||||
WHERE d.run_id = :run";
|
||||
|
||||
if ($q !== '') $sql .= " AND d.domain LIKE :q";
|
||||
if ($tld !== '') $sql .= " AND d.tld = :tld";
|
||||
|
||||
23
export_latest_domains.py
Executable file
23
export_latest_domains.py
Executable file
@ -0,0 +1,23 @@
|
||||
#!/usr/bin/env python3
|
||||
import json
|
||||
import sqlite3
|
||||
from pathlib import Path
|
||||
|
||||
BASE = Path(__file__).resolve().parent
|
||||
DB = BASE / 'data' / 'domainhunter.db'
|
||||
|
||||
con = sqlite3.connect(DB)
|
||||
cur = con.cursor()
|
||||
run_id = cur.execute("SELECT value FROM metadata WHERE key='latest_run_id'").fetchone()
|
||||
run_id = run_id[0] if run_id else ''
|
||||
scanned = cur.execute("SELECT value FROM metadata WHERE key='latest_scanned_at'").fetchone()
|
||||
scanned = scanned[0] if scanned else ''
|
||||
rows = cur.execute("SELECT domain,tld,score,status,keywords_json FROM domains WHERE run_id=? ORDER BY score DESC,domain ASC", (run_id,)).fetchall()
|
||||
items=[]
|
||||
for d,tld,score,status,kw in rows:
|
||||
try:
|
||||
kws=json.loads(kw or '[]')
|
||||
except Exception:
|
||||
kws=[]
|
||||
items.append({"domain":d,"tld":tld,"score":score,"status":status,"keywords":kws})
|
||||
print(json.dumps({"runId":run_id,"scannedAt":scanned,"items":items}, ensure_ascii=False, indent=2))
|
||||
71
import_llm_scores.py
Executable file
71
import_llm_scores.py
Executable file
@ -0,0 +1,71 @@
|
||||
#!/usr/bin/env python3
|
||||
import json
|
||||
import sqlite3
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
BASE = Path(__file__).resolve().parent
|
||||
DB = BASE / 'data' / 'domainhunter.db'
|
||||
|
||||
|
||||
def main():
|
||||
if len(sys.argv) < 2:
|
||||
print('Usage: import_llm_scores.py <json-file>')
|
||||
sys.exit(1)
|
||||
|
||||
src = Path(sys.argv[1])
|
||||
if not src.exists():
|
||||
print(f'File not found: {src}')
|
||||
sys.exit(2)
|
||||
|
||||
payload = json.loads(src.read_text(encoding='utf-8'))
|
||||
items = payload if isinstance(payload, list) else payload.get('items', [])
|
||||
|
||||
con = sqlite3.connect(DB)
|
||||
cur = con.cursor()
|
||||
cur.executescript('''
|
||||
CREATE TABLE IF NOT EXISTS llm_scores (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
run_id TEXT,
|
||||
domain TEXT,
|
||||
llm_score REAL,
|
||||
decision TEXT,
|
||||
reason TEXT,
|
||||
updated_at TEXT,
|
||||
UNIQUE(run_id, domain)
|
||||
);
|
||||
''')
|
||||
|
||||
run_id = None
|
||||
if isinstance(payload, dict):
|
||||
run_id = payload.get('runId')
|
||||
if not run_id:
|
||||
r = cur.execute("SELECT value FROM metadata WHERE key='latest_run_id'").fetchone()
|
||||
run_id = (r[0] if r else '')
|
||||
|
||||
count = 0
|
||||
for it in items:
|
||||
d = (it.get('domain') or '').strip().lower()
|
||||
if not d:
|
||||
continue
|
||||
score = it.get('llm_score', None)
|
||||
dec = (it.get('decision') or '').strip().lower()[:32]
|
||||
reason = (it.get('reason') or '').strip()[:500]
|
||||
cur.execute('''
|
||||
INSERT INTO llm_scores(run_id, domain, llm_score, decision, reason, updated_at)
|
||||
VALUES(?,?,?,?,?,datetime('now'))
|
||||
ON CONFLICT(run_id, domain) DO UPDATE SET
|
||||
llm_score=excluded.llm_score,
|
||||
decision=excluded.decision,
|
||||
reason=excluded.reason,
|
||||
updated_at=excluded.updated_at
|
||||
''', (run_id, d, score, dec, reason))
|
||||
count += 1
|
||||
|
||||
con.commit()
|
||||
con.close()
|
||||
print(f'OK imported llm scores: {count} for run {run_id}')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@ -54,7 +54,7 @@
|
||||
<h2>TOP domen + porównanie cen (rejestracja / odnowienie)</h2>
|
||||
<div class="table-wrap">
|
||||
<table>
|
||||
<thead><tr><th>Domena</th><th>TLD</th><th>Score</th><th>Status</th><th>Oferty (top 3)</th></tr></thead>
|
||||
<thead><tr><th>Domena</th><th>TLD</th><th>Score</th><th>LLM</th><th>Status</th><th>Oferty (top 3)</th></tr></thead>
|
||||
<tbody id="rows"></tbody>
|
||||
</table>
|
||||
</div>
|
||||
@ -133,9 +133,11 @@ function renderRows(){
|
||||
}).join('')
|
||||
: `<span class='muted'>Brak danych cenowych dla .${d.tld}</span>`;
|
||||
|
||||
const llm = (d.llm_score!==null && d.llm_score!==undefined) ? `${Number(d.llm_score).toFixed(1)} ${d.decision ? `(${d.decision})` : ''}` : '—';
|
||||
tr.innerHTML = `<td><a href='${checkUrl}' target='_blank'><b>${d.domain}</b></a> ${d.is_new ? `<span class='chip'>NEW</span>` : ''}</td>
|
||||
<td>.${d.tld}</td>
|
||||
<td>${d.score}</td>
|
||||
<td>${llm}</td>
|
||||
<td>${d.status || 'available'}</td>
|
||||
<td>${offersHtml}</td>`;
|
||||
rows.appendChild(tr);
|
||||
|
||||
11
init_db.py
11
init_db.py
@ -37,6 +37,17 @@ CREATE TABLE IF NOT EXISTS registrar_prices (
|
||||
updated_at TEXT,
|
||||
UNIQUE(registrar, tld)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS llm_scores (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
run_id TEXT,
|
||||
domain TEXT,
|
||||
llm_score REAL,
|
||||
decision TEXT,
|
||||
reason TEXT,
|
||||
updated_at TEXT,
|
||||
UNIQUE(run_id, domain)
|
||||
);
|
||||
''')
|
||||
con.commit()
|
||||
con.close()
|
||||
|
||||
@ -96,6 +96,16 @@ def main():
|
||||
updated_at TEXT,
|
||||
UNIQUE(registrar, tld)
|
||||
);
|
||||
CREATE TABLE IF NOT EXISTS llm_scores (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
run_id TEXT,
|
||||
domain TEXT,
|
||||
llm_score REAL,
|
||||
decision TEXT,
|
||||
reason TEXT,
|
||||
updated_at TEXT,
|
||||
UNIQUE(run_id, domain)
|
||||
);
|
||||
''')
|
||||
|
||||
run_id = latest.get('runId')
|
||||
|
||||
Loading…
Reference in New Issue
Block a user