Fix LLM Cost: accumulate per-version costs, include stems, show total

- Webhook no longer overwrites cost estimate with 0 when conversion_cost
  is missing from the payload
- Per-version costs (A/B) are tracked separately and summed into total
- Stems cost is only overwritten when a non-zero cost is reported
- Template shows combined total (songs + stems) with breakdown
- Added musicgpt_cost_a and musicgpt_cost_b columns to schema
This commit is contained in:
Troll (Hermes Agent) 2026-08-11 19:42:28 +00:00
parent f2c64848dd
commit 24838c73ac
3 changed files with 38 additions and 8 deletions

31
app.py
View file

@ -364,10 +364,29 @@ def musicgpt_webhook():
# the webhook is the rare complete one.
if data.get('album_cover_path'):
update_fields['album_cover_url'] = data.get('album_cover_path')
# Accumulate cost from each per-version webhook instead of overwriting.
# The estimate is set when the job is queued; webhooks may report
# per-conversion costs. We sum them into the total.
try:
update_fields['musicgpt_cost'] = float(data.get('conversion_cost') or 0)
cc = float(data.get('conversion_cost') or 0)
except (ValueError, TypeError):
pass
cc = 0
if cc > 0:
# Only accumulate if the webhook reports a non-zero cost;
# otherwise keep whatever was already stored (estimate or prior sum).
current = float(req.get('musicgpt_cost') or 0)
# If this is a per-version webhook, add to the total.
# First webhook for version A: total = cc. Second for B: total += cc.
# If the estimate was stored and no per-version cost was reported yet,
# the first real cost replaces the estimate.
if version == 'A':
update_fields['musicgpt_cost'] = cc + float(req.get('musicgpt_cost_b') or 0)
update_fields['musicgpt_cost_a'] = cc
elif version == 'B':
update_fields['musicgpt_cost'] = float(req.get('musicgpt_cost_a') or 0) + cc
update_fields['musicgpt_cost_b'] = cc
else:
update_fields['musicgpt_cost'] = cc
download_musicgpt_outputs(req, data, version=version)
row = db.execute('SELECT * FROM requests WHERE id = ?', (req['id'],)).fetchone()
req = dict(row)
@ -402,9 +421,11 @@ def musicgpt_webhook():
update_fields['stems_url'] = stems_url
update_fields['stems_link'] = stems_url
try:
update_fields['stems_cost'] = float(data.get('conversion_cost') or 0)
sc = float(data.get('conversion_cost') or 0)
except (ValueError, TypeError):
pass
sc = 0
if sc > 0:
update_fields['stems_cost'] = sc
elif new_status in ('FAILED', 'ERROR'):
update_fields['stems_error'] = data.get('reason') or data.get('error') or 'Extraction failed'
update_request(req['id'], **update_fields)
@ -1537,7 +1558,7 @@ def admin_settings():
'approval_notified_at', 'preview_sent_at', 'delivery_sent_at',
'square_payment_ref', 'admin_alert_email', 'player_token', 'revision_note', 'revision_count', 'operator_notes', 'stems_link', 'stems_interest',
'musicgpt_task_id', 'musicgpt_conversion_id_1', 'musicgpt_conversion_id_2',
'musicgpt_status', 'musicgpt_cost', 'musicgpt_error',
'musicgpt_status', 'musicgpt_cost', 'musicgpt_cost_a', 'musicgpt_cost_b', 'musicgpt_error',
'album_cover_url', 'song_a_wav_path', 'song_b_wav_path', 'deliver_wav',
'stems_task_id', 'stems_status', 'stems_cost', 'stems_url', 'stems_error'
}