feat(history): consolidate durable costs and asset previews - #78
feat(history): consolidate durable costs and asset previews#78peacenode wants to merge 12 commits into
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
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. |
|
Pulled the existing trial-observability pieces together in 65d1bd9:
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. |
|
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 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 |
|
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. |
|
@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:
Validate Console and CodeQL are green. The stable preview is built from current head The remaining release prerequisite is still the downstream PymtHouse correction that returns the Console-supplied |
There was a problem hiding this comment.
🟡 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.
| !wanted.has(item.gatewayRequestId) | ||
| ) | ||
| continue; | ||
| const receipt = sanitizeBillingReceipt(item); | ||
| if (receipt) receipts.push(receipt); |
| const wanted = new Set(owned.map((run) => run.gatewayRequestId)); | ||
| const appId = configuredPymthouseScope().appId; | ||
| const receipts = []; | ||
| let cursor: string | null | undefined; |
Production usage ids are CloudEvent 8-hex, not console job_* keys. Keep the current-month ticket feed and match by capability and time so the request drawer can show a real fee.
2b49f85 to
bb9ccaf
Compare
|
Signature blocker resolved: all 12 commits have been rewritten with the dedicated The stable preview has also been rebuilt from signed head @eliteprox the review request remains active. Required CI is rerunning against the signed head. |
Summary
Consolidates and supersedes #75 and #77 on a fresh branch from current main.
Billing behavior
Costs are authoritative only when PymtHouse returns the exact caller-supplied
job_*gateway correlation ID. Receipts are idempotent viausage:<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-uiand 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:
—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
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.ASSET_URL_SIGNING_SECRETandASSET_PROXY_ALLOWED_HOSTSin preview and production before deployment.job_*ID in PymtHouse and Neon, then confirm the History drawer cost.Validation
pnpm test:console— passed (147 passed)pnpm lint— passed; targeted lint remains green at headpnpm typecheck— passed at headpnpm build— passed locally and in the latest Vercel previewThe 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.