Signals: index the judge's query, six calls at once, one call per item on the server's key, tokens counted, a week's look-back an admin sets, edits that ask again only what was picked out (#274, #275, #276)

The judge's query read all of entries (605 MB, 566 ms) on every wake; an
index on each feed's items by date, as the query asks, and the rechecks
in a half of their own. Calls ran one at a time, about 150 ms each, so a
new Signal's month of about 8,000 items took twenty minutes: six in flight
now. On the server's key everyone's Signals on an item share one call.
TypeSafe's token counts go to /metrics and each jev span.

An item's text is cut at 1,000 characters instead of 2,000: on 55 real
items of eight podcast feeds and six Signals, on the development key,
1,000 changed none of 330 verdicts (nor did the same request twice) and
saved 12% of the input tokens, 1,266 to 1,112 a call; 500 changed one.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-17 14:13:25 +00:00
parent 026fbd1622
commit 2077ea5810
16 changed files with 293 additions and 106 deletions

View File

@@ -58,6 +58,11 @@ async function drawServer(){
<span class="hint">${g.typesafe_server_key
? 'On, everyone has Signals and every item read for one is a call on this server\'s key. Off, each person turns Signals on in their own Settings with a key of their own.'
: 'This server has no TypeSafe key (<code>TYPESAFE_KEY</code>), so each person uses their own.'}</span></div>
<div class="field"><label for="gsigdays">Signals look back (days)</label>
<input type="number" id="gsigdays" min="1" max="365" value="${g.signal_days}">
<span class="hint">How far back a new Signal reads. Each item read is a call to TypeSafe, so a
longer look back costs more, once for each new Signal. Editing a Signal reads again only what
it had picked out.</span></div>
<div class="field"><label>Download folder</label>
<span class="hint" style="overflow-wrap:anywhere">${esc(g.download_dir)}</span></div>
<div class="cardacts"><button class="btn primary" id="gsave">${ICON.check} Save</button></div>`;
@@ -70,6 +75,7 @@ async function drawServer(){
max_total_gb: Number($<HTMLInputElement>('#gquota').value) || 0,
max_age_days: Number($<HTMLInputElement>('#gage').value) || 0,
art_cache_mb: Math.max(0, Number($<HTMLInputElement>('#gart').value) || 0),
signal_days: Math.min(365, Math.max(1, Number($<HTMLInputElement>('#gsigdays').value) || 7)),
// Left alone while the server has no key to offer, rather than switched off.
...($<HTMLInputElement>('#gsig').disabled ? {} : {signals_on_server: $<HTMLInputElement>('#gsig').checked})})});
toast('Settings saved');