Skip to content

feat(history): consolidate durable costs and asset previews - #78

Open
peacenode wants to merge 12 commits into
mainfrom
codex/history-cost-assets
Open

feat(history): consolidate durable costs and asset previews#78
peacenode wants to merge 12 commits into
mainfrom
codex/history-cost-assets

Conversation

@peacenode

@peacenode peacenode commented Sep 10, 2026

Copy link
Copy Markdown
Collaborator

Summary

Consolidates and supersedes #75 and #77 on a fresh branch from current main.

  • persists sanitized, append-only billing receipts in Neon using exact owner + Console gateway request ID correlation
  • exposes one raw Neon-derived billing summary to both the History table and detail drawer
  • adds bounded authenticated billing sync for visible runs, with the open drawer prioritized and billing outages isolated from History
  • replaces Radix usage with the Livepeer registry Base UI Tooltip and existing Base UI Dialog/Button/Badge components
  • secures first-party asset playback with one-hour owner-bound HMAC URLs, redirect/origin validation, hard provider expiry, and bounded caching
  • preserves and re-signs owned first-party input assets while continuing to strip untrusted provider URLs
  • moves provider schema loading off the run-detail critical path

Billing behavior

Costs are authoritative only when PymtHouse returns the exact caller-supplied job_* gateway correlation ID. Receipts are idempotent via usage:<billing-event-id>, and multiple receipt values are summed with decimal-safe arithmetic. There is no model/time inference and unmatched runs display an em dash.

No historical migration is included because existing records are test/internal. Authenticated History sync ingests available current-month receipts going forward.

Registry alignment

Tooltip is sourced from https://livepeer.peaceno.de/r/tooltip.json and uses @base-ui/react/tooltip. The History drawer now uses the registry-derived Base UI Dialog for focus containment, Escape, background inertness, and focus restoration. radix-ui and all Radix imports are removed, with a contract test preventing reintroduction in touched UI primitives.

Preview verification

Use https://console-history-cost-assets.vercel.app. After sign-in, the preview automatically provisions four account-scoped Neon History runs; no fixture button or paid request is required.

Please verify:

  • History table and drawer display the same Neon-derived Cost
  • the asset-reuse run shows durable input/output lineage
  • the unmatched run displays
  • the full-screen Base UI drawer supports Escape and focus restoration
  • circled info controls open Base UI tooltips with top-aligned content, contained options, and visible padding

The stable preview currently points to signed head commit bb9ccaf. Its manual Vercel build completed successfully. The repository Vercel status remains red only because automatic preview deployments are canceled in the Vercel dashboard.

Release prerequisites

  • Deploy and verify the PymtHouse requests API correction that preserves and returns the Console-supplied job_* gateway correlation ID end to end. This repository already supplies that ID through @pymthouse/gateway-web, but the downstream correction is outside this PR.
  • Configure ASSET_URL_SIGNING_SECRET and ASSET_PROXY_ALLOWED_HOSTS in preview and production before deployment.
  • Run the paid preview smoke test after those prerequisites: execute one paid capability, verify the identical job_* ID in PymtHouse and Neon, then confirm the History drawer cost.

Validation

  • full test suite — passed (427 passed, 49 skipped) before the final tooltip-only refinements
  • pnpm test:console — passed (147 passed)
  • final tooltip contract test — passed (5 passed)
  • pnpm lint — passed; targeted lint remains green at head
  • pnpm typecheck — passed at head
  • pnpm build — passed locally and in the latest Vercel preview
  • Validate Console and CodeQL — green at head

The build emits only the expected missing local Auth0 configuration and Edge deprecation warnings.

Supersedes #75 and #77. The original PRs should be closed only after this replacement is approved and green.

@vercel

vercel Bot commented Sep 10, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
console Ready Ready Preview Sep 10, 2026 9:01pm UTC

Request Review

@peacenode

Copy link
Copy Markdown
Collaborator Author

Manual branch preview is ready: https://console-psra6vzuc-livepeer-foundation.vercel.app

The branch-scoped ASSET_URL_SIGNING_SECRET and ASSET_PROXY_ALLOWED_HOSTS settings are configured. Vercel build and deployment completed successfully; the original automatic Vercel check remains marked canceled from the dashboard, while Validate Console and CodeQL are green.

The paid end-to-end cost smoke test remains gated on PymtHouse returning the caller-supplied job_* correlation ID.

@peacenode

Copy link
Copy Markdown
Collaborator Author

Pulled the existing trial-observability pieces together in 65d1bd9:

  • normalized run_usage_receipts is now the authoritative queryable PymtHouse cost projection, with matching append-only run_events chronology
  • run_asset_links now records durable input/output lineage using the existing stable mcp_assets IDs
  • first-party input references are owner-checked at submission and retain role, parameter path, and ordinal
  • added a Vercel-preview-only authenticated fixture writer so each reviewer can create representative Neon-backed History records (single receipt, decimal-safe multi-receipt aggregate, unmatched receipt, generated asset, and reused input)

Local test, Console test, lint, typecheck, and production build are green. The additive migration rollback rehearsal correctly stopped because the available preview DATABASE_URL is the least-privilege runtime role. Before redeploying this head, the approved Neon owner connection must apply drizzle-baseline/0001_run_observability_and_lineage.sql and grant the runtime role SELECT/INSERT on run_usage_receipts and run_asset_links. No production database was queried or changed.

@peacenode

Copy link
Copy Markdown
Collaborator Author

Preview verification is ready at https://console-history-cost-assets.vercel.app

After signing in, open Calls and choose Create preview verification records. It creates three records scoped to your account: a single receipt, a two-receipt aggregate with asset reuse, and an unmatched/failed run showing . Please verify table/drawer cost parity and input/output assets in the drawer.

The preview database migration and least-privilege runtime access have been verified. Smoke checks pass, and all GitHub Actions checks are green. The repository Vercel check is still marked failed only because its automatic deployment was canceled from the Vercel Dashboard; the linked manual preview built successfully from 65d1bd9.

@peacenode

Copy link
Copy Markdown
Collaborator Author

Updated preview behavior at https://console-history-cost-assets.vercel.app

No setup button is required now. On the first authenticated History read, the preview automatically provisions an idempotent, account-scoped dataset and returns a matching preview usage balance. The visible dataset contains four richer records covering image generation, asset reuse, text inference, and a provider failure. Run drawers include stored media, prompts, parameters, provider results/timing, costs, receipts, and input/output lineage.

Superseded button-era fixture rows are hidden in preview responses without deleting Neon data. Verified in the deployed UI: $5 preview balance, four History rows, and a Flux Schnell drawer with image, prompt, seed, image size, safety setting, $0.0100 cost, and 1.28s render status. This supersedes my earlier instruction to click Create preview verification records.

@peacenode
peacenode marked this pull request as ready for review September 10, 2026 20:54
@peacenode
peacenode requested review from eliteprox and a lite review from Copilot September 10, 2026 20:54
@peacenode

Copy link
Copy Markdown
Collaborator Author

@eliteprox this is ready for your approval. It folds #75 and #77 together and now has a reviewer-ready Neon-backed preview at https://console-history-cost-assets.vercel.app

The preview auto-provisions four account-scoped History runs, so there is no setup button or paid request required. The main review points are:

  • table/drawer Cost parity from persisted Neon receipts
  • multiple-receipt aggregation and unmatched behavior
  • durable input/output asset lineage and signed playback URLs
  • Base UI Dialog/Tooltip behavior, including the latest tooltip layering, top alignment, and padding fixes

Validate Console and CodeQL are green. The stable preview is built from current head 2b49f85. The red repository Vercel status is the canceled automatic deployment; the manual deployment at the stable URL succeeded.

The remaining release prerequisite is still the downstream PymtHouse correction that returns the Console-supplied job_* correlation ID end to end; that should block production release, not review of this PR implementation.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The billing sync endpoint has a confirmed loop-control/performance defect (matched IDs are never removed from the wanted set), and there’s an easy type-safety fix that should be applied before merging.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

This PR consolidates run History cost computation and first-party asset preview handling by persisting authoritative billing receipts in Neon, deriving a single billing summary for both the History table and detail drawer, and proxying asset playback through owner-bound signed URLs. It also replaces the legacy tooltip implementation/Radix usage with registry-aligned Base UI primitives and moves provider schema loading off the run-detail critical path.

Changes:

  • Persist append-only billing receipts (run_usage_receipts) and surface a Neon-derived billing summary (billing) in run list + detail flows.
  • Introduce first-party asset signing + proxying (/api/assets/:id) and rewrite captured run payloads to remove provider media URLs.
  • Add preview-only fixture seeding and UI/contract coverage for history, billing sync, asset security, and tooltip/dialog primitives.
File summaries
File Description
tests/integration/run-records.test.ts Extends integration coverage for durable asset lineage (run_asset_links) and receipt aggregation into billing.
tests/integration/mcp-assets.test.ts Updates asset serialization expectations to use first-party signed URLs.
tests/contracts/ui-primitive-dependencies.test.ts Adds contract test preventing Radix dependency/import reintroduction in UI primitives.
tests/contracts/session-allowance.test.tsx Verifies preview usage can be served without contacting PymtHouse when preview fixtures are enabled.
tests/contracts/run-security.test.ts Expands redaction/output extraction contract to cover *_urls array outputs.
tests/contracts/run-http.test.ts Verifies preview fixture seeding occurs before listing runs and legacy preview rows are filtered.
tests/contracts/run-execution.test.ts Ensures durable execution returns first-party asset URLs and does not leak provider media URLs/status URLs.
tests/contracts/preview-run-fixtures-route.test.ts Adds contract coverage for preview-only fixture creation endpoint and seeded receipt lineage.
tests/contracts/home-history-surface.test.tsx Updates History surface tests for tooltip provider usage and Neon-derived cost behavior.
tests/contracts/call-detail-media.test.tsx Adds detailed UI contract coverage for media stage behavior, expiry, tooltips, and captured field presentation.
tests/contracts/billing-sync-route.test.ts Adds contract tests for bounded, exact-match billing sync and run-id limits.
tests/contracts/asset-proxy.test.ts Adds security contract tests for signed asset proxying (range requests, allowlist, private IP refusal, redirect validation).
tests/contracts/admin-runs-preview.test.tsx Updates admin drawer expectations to present captured fields without raw JSON section labels.
tests/contracts/account-history.test.ts Ensures cost lookups omit year window to preserve current-month ticket feed correctness.
tests/contracts/account-history-route.test.ts Updates route contract for new receipt metadata fields and recordRunUsage return type.
lib/runs/types.ts Introduces billing summary types, input schema types, and extends asset shape with role/displayName.
lib/runs/store.ts Implements receipt persistence + aggregation, asset lineage linking, and list/detail billing attachment.
lib/runs/preview-fixtures.ts Adds preview-only deterministic seeding of owner-scoped fixture runs + receipts and synthetic account usage payload.
lib/runs/outputs.ts Extends output extraction to include image_urls, video_urls, audio_urls.
lib/runs/execute.ts Rewrites execution payload to return first-party asset URLs and strips provider URL leakage from returned data.
lib/runs/billing.ts Adds decimal-safe aggregation helpers for receipt totals and billing summaries.
lib/runs/billing.test.ts Validates decimal-safe arithmetic and receipt aggregation behavior.
lib/mcp/store.ts Switches asset serialization to first-party signed URLs and adds getAssetSource for proxying.
lib/mcp/mcp-server.ts Updates MCP asset listing serialization to include principal-bound signed URLs.
lib/mcp/fal-input-schema.ts Adds schema parsing + caching for Fal OpenAPI input metadata to support History UI help.
lib/mcp/fal-input-schema.test.ts Tests Fal schema parsing and capability resolution behavior.
lib/db/schema/runs.ts Adds run_usage_receipts table for normalized, queryable billing evidence.
lib/db/schema/mcp-assets.ts Adds run_asset_links table for durable input/output lineage edges.
lib/db/full-baseline.test.ts Updates baseline/journal expectations to include additive migration(s).
lib/console/useRunHistory.ts Loads run input schema asynchronously after detail fetch to remove it from critical path.
lib/console/usage-capability-display.ts Improves model display names by stripping provider/catalog namespaces.
lib/console/types.ts Adds capabilityId to activity rows for pricing/joining context.
lib/console/signed-ticket-activity.ts Maps signed tickets to activity rows with capabilityId set for consistent joins.
lib/console/run-activity.ts Simplifies cost mapping to rely on persisted billing summary instead of inferred events/feeds.
lib/console/run-activity.test.ts Updates tests to reflect billing summary-driven cost display, including multi-receipt aggregation.
lib/console/pymthouse-bff.ts Adds recentWindow option to avoid from/to windows that drop current-month pricing tickets.
lib/console/dev-mock.ts Adds dev-mock run history/detail fixtures, schema mocks, and local /api/assets/* redirects for previews.
lib/console/capability-modality.ts Adds capabilityPresentation and modality labels to improve user-facing titles.
lib/console/capability-modality.test.ts Adds tests for capability title cleanup and namespace-stripped model display names.
lib/console/billing-receipts.ts Centralizes and tightens sanitization of upstream billing receipt fields before persistence.
lib/console/activity-output-match.ts Removes fuzzy/orchestrator-id inference; only exact gateway correlation is treated as authoritative.
lib/console/activity-output-match.test.ts Updates tests to ensure non-exact tickets do not attach assets.
lib/console/activity-assets.ts Rewrites attached output URLs to use first-party signed asset URLs.
lib/assets/public.ts Implements asset URL signing, captured payload rewriting, and provider URL stripping for public run detail responses.
lib/assets/public.test.ts Tests first-party URL rewriting and provider URL redaction behavior.
drizzle-baseline/meta/_journal.json Adds new migration entry to the baseline journal.
drizzle-baseline/0001_run_observability_and_lineage.sql Adds schema migration creating run_asset_links and run_usage_receipts with indexes/constraints.
docs/early-access/run-records.md Updates documentation to describe normalized receipts, sync bounds, lineage tables, and signed asset proxy behavior.
components/ui/tooltip.tsx Adds Base UI tooltip wrapper components used across the app.
components/design-system/Tooltip.tsx Removes legacy bespoke tooltip implementation.
components/console/ModalityChip.tsx Introduces shared ModalityChip used by table and drawer.
components/console/CallsTable.tsx Migrates tooltips to Base UI and adopts ModalityChip for consistent modality styling.
components/console/CallsSection.tsx Adds bounded authenticated billing sync for visible runs while keeping History resilient to billing outages.
components/console/CallDetailDrawer.tsx Migrates to Base UI dialog + tooltips, improves media stage behavior, and presents captured fields without raw JSON sections.
components/admin/RunsPreview.tsx Configures drawer variant for admin presentation mode.
app/layout.tsx Wraps the app in TooltipProvider for consistent tooltip behavior.
app/api/pymthouse/account-usage/route.ts Serves preview usage payload when preview fixtures are enabled.
app/api/pymthouse/account-requests/route.ts Uses receipt sanitization helper and enables recent-window behavior for correlation mode.
app/api/console/runs/route.ts Seeds preview fixtures (preview-only) before listing and filters legacy preview records.
app/api/console/runs/preview-fixtures/route.ts Adds preview-only authenticated endpoint to seed fixtures.
app/api/console/runs/billing-sync/route.ts Adds bounded, exact-match billing sync endpoint for visible run IDs.
app/api/console/runs/[id]/schema/route.ts Adds endpoint for loading run input schema metadata (Fal) off the detail critical path.
app/api/console/runs/[id]/route.ts Returns publicRunDetail to ensure asset URLs are signed and provider URLs are removed.
app/api/assets/[id]/route.ts Adds signed asset proxy route with origin/redirect validation and bounded caching.
app/api/admin/runs/[id]/route.ts Applies publicRunDetail for admin run detail responses as well.
.env.example Documents required asset signing/proxy env vars and preview fixture toggles.
Review details
  • Files reviewed: 66/67 changed files
  • Comments generated: 2
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +54 to +58
!wanted.has(item.gatewayRequestId)
)
continue;
const receipt = sanitizeBillingReceipt(item);
if (receipt) receipts.push(receipt);
Comment on lines +30 to +33
const wanted = new Set(owned.map((run) => run.gatewayRequestId));
const appId = configuredPymthouseScope().appId;
const receipts = [];
let cursor: string | null | undefined;
@peacenode

Copy link
Copy Markdown
Collaborator Author

Signature blocker resolved: all 12 commits have been rewritten with the dedicated peacenode GitHub signing key and GitHub now reports every commit as Verified. The file tree is byte-for-byte identical to the previously reviewed head; only commit IDs and signatures changed.

The stable preview has also been rebuilt from signed head bb9ccaf: https://console-history-cost-assets.vercel.app

@eliteprox the review request remains active. Required CI is rerunning against the signed head.

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.

3 participants