Skip to content

Burst populates the strip + hydrate Estimated/Actual after a hard refresh - #48

Merged
aakri0 merged 1 commit into
mainfrom
fix/burst-strip-and-hydrate
May 2, 2026
Merged

Burst populates the strip + hydrate Estimated/Actual after a hard refresh#48
aakri0 merged 1 commit into
mainfrom
fix/burst-strip-and-hydrate

Conversation

@aakri0

@aakri0 aakri0 commented May 2, 2026

Copy link
Copy Markdown
Owner

Why

Two cost-strip gaps left by #47:

  1. Invoke ×50 didn't update Estimated max / Actual. Last 30 days ticked because refreshAll already tracks /usage/cost, but onBurst skipped both renderEstimate and pollResult. The first two cells of the strip were single-submit-only.
  2. After a hard refresh, Estimated max and Actual were empty. Their values lived only in JS state set by onSubmit/onBurst. A page reload nuked that, leaving until the user submitted again.

Fixes

onBurst()

  • Calls fetchEstimate(body)renderEstimate. Estimated max populates immediately with the per-job number (the aggregate lives in Last 30 days where it belongs).
  • Clears the Actual cell, then awaits all 50 submits, picks the first job_id and calls pollResult() on it so Actual ticks live for one representative — same UX as a single submit.

hydrateCostStripFromJobs() + computeEstimateLocal()

  • On every refreshAll tick, if the strip is empty AND the user hasn't just submitted (lastInvokeAt < 30s), pick the most recent terminal job from /jobs and:
    • render its cost as Actual,
    • reconstruct its worst-case estimate locally using rates cached from /usage/cost.pricing.
  • Active flows take priority via state.lastInvokeAt, set in onSubmit and onBurst, so an in-flight pollResult never gets clobbered by hydration.

The local estimate reconstruction mirrors api/pricing.estimate_max_cost exactly (same formula, same per-attempt fee accounting, same network treatment) and reuses the rate card already on /usage/cost.pricing, so the API stays the single source of truth.

Verified

  • API /jobs?limit=1 returns every spec field hydration needs (memory_mb, timeout_seconds, max_retries, cpu_nanos, auto_install) plus the structured cost object on terminal rows.
  • 174 tests pass.
  • New JS shipped: 8 references to hydrateCostStripFromJobs/computeEstimateLocal/lastInvokeAt/results[0] in the served app.js?v=19.

app.js?v=19.

…resh

Two related cost-strip gaps from #47:

1. Invoke ×50 (load test) updated 'Last 30 days' (because refreshAll
   ticks /usage/cost) but Estimated max and Actual stayed at —. onBurst
   skipped renderEstimate and pollResult — the strip's first two cells
   were single-submit-only.

2. After a hard refresh the JS state was empty, so all cells started at
   '—'. The Last 30 days panel filled in within 2s, but Estimated and
   Actual had no source until the user submitted again.

Fixes:

onBurst now:
  - calls fetchEstimate(body) -> renderEstimate so Estimated max
    populates immediately with the per-job number (the aggregate lives
    in Last 30 days where it belongs);
  - clears the actual cell, then awaits all 50 submits, picks the first
    job_id and pollResult()s it so Actual ticks live for one
    representative — same UX as a single submit.

New hydrateCostStripFromJobs() + computeEstimateLocal():
  - On every refreshAll tick, if the strip is empty AND the user hasn't
    just submitted (lastInvokeAt < 30s), pick the most recent terminal
    job from /jobs and:
      * render its cost as Actual,
      * reconstruct its worst-case estimate locally using the rates we
        cache from /usage/cost.pricing.
  - Active flows take priority via state.lastInvokeAt set in onSubmit
    and onBurst, so an in-flight pollResult never gets clobbered.

The estimate reconstruction matches api/pricing.estimate_max_cost
exactly (same formula, same per-attempt accounting, same network
treatment) and uses the rate card already on /usage/cost so a single
source of truth stays.

Bumped app.js?v=19.
@aakri0
aakri0 merged commit 81b3421 into main May 2, 2026
3 checks passed
@aakri0
aakri0 deleted the fix/burst-strip-and-hydrate branch May 2, 2026 07:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant