Skip to content

Conversation

@laciferin2024
Copy link
Contributor

@laciferin2024 laciferin2024 commented Sep 15, 2025

PR Checklist

Please read and check all that apply.

Changesets

  • This PR includes a Changeset under .changeset/ describing the change (patch/minor/major) with a clear, user-focused summary
  • OR this PR is docs/tests-only and I added the skip-changeset label

Quality

  • UI builds locally: bun run build (Vite)
  • E2E or unit tests added/updated where applicable (playwright, vitest if used)
  • No breaking changes to public interfaces without a major bump

Notes

  • Add a changeset via: bun run changeset
  • Policy and examples: see aidocs/changesets.md

Summary by CodeRabbit

  • New Features

    • Pricing Catalog with per-model token rates, loading/fallback states, and fiat conversions.
    • Predictive cost estimates (input/output/total) with selectable output size and USD display.
    • Per-run Receipt modal with JSON/CSV export, copyable request IDs/tx hashes, and explorer links.
    • Transparency panel showing usage, remaining calls, raw headers toggle, and receipts/transaction details.
  • Chores

    • Minor release prepared; example environment updated with VITE_UNREAL_USD for fiat conversion.

@vercel
Copy link

vercel bot commented Sep 15, 2025

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

Project Deployment Preview Comments Updated (UTC)
console Ready Ready Preview Comment Sep 15, 2025 7:20am

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 15, 2025

Caution

Review failed

The pull request is closed.

Walkthrough

Adds a changeset and a new env var for fiat conversion, and implements extensive billing/pricing features in ChatPlayground: pricing fetch, per-run billing metadata extraction from response headers, chain-aware explorer links, cost estimation, transparency/receipt UI (JSON/CSV export, copy), and usage of API helpers (getCurrentChainId, verifyData).

Changes

Cohort / File(s) Summary
Release metadata
\.changeset/plenty-wolves-rush.md
Adds a changeset declaring a minor release for unreal-console with a note about showing pricing/flow in the UI.
Environment configuration
.env.example
Adds VITE_UNREAL_USD=0.01 (fiat conversion rate) and adjusts nearby formatting; retains VITE_TREZOR_EMAIL.
Chat billing, pricing, receipts & API usage
src/components/ChatPlayground.tsx
Adds pricing data structures and fetch from /models/pricing; chain-aware billing via getCurrentChainId; extracts cost/tx/usage headers from chat responses into per-run BillingMeta; implements pricing catalog UI, cost estimation (UNREAL + fiat), transparency panel, receipt modal with JSON/CSV export and copy-to-clipboard, explorer links, and related utilities (shortHash, ExpandableHash). Also integrates verifyData usage from the API context.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant U as User
  participant CP as ChatPlayground
  participant PR as Pricing API (/models/pricing)
  participant CH as Chain Provider (getCurrentChainId)
  participant OA as OpenAI Chat API
  participant RB as Receipt Builder / Export
  participant UI as UI Panels (Catalog / Transparency / Receipt)

  Note over CP: Initialization
  CP->>CH: getCurrentChainId()
  CH-->>CP: chainId
  CP->>PR: GET /models/pricing
  PR-->>CP: pricingMap

  U->>CP: Submit prompt
  CP->>OA: create chat completion (withResponse)
  OA-->>CP: message + headers (openai-*-cost, tx hashes, usage, refunds)
  CP->>CP: store lastRun BillingMeta (pricing, headers, tx, chain)
  CP->>RB: buildReceipt(lastRun)
  RB-->>CP: receipt (JSON/CSV)

  CP->>UI: update Transparency panel & enable explorer links
  U->>UI: View Receipt / Export / Copy IDs
  UI-->>U: rendered receipt, exported file, copied text
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Poem

A rabbit counts tokens by moonlight,
Hops through headers, chains in sight.
Receipts clutched close, a tidy trail,
Exports ready, CSV and mail.
Pricing carrots stacked just right—
Copy, click, the console’s bright. 🐇

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Description Check ⚠️ Warning The PR body contains only the checklist template with no items checked or a contextual summary; although the changeset file .changeset/plenty-wolves-rush.md and substantive UI changes exist in the diff, the description does not state that, nor does it confirm local build/tests or whether public interfaces changed, so the description is incomplete. Please update the PR description to explicitly reference the included changeset (for example .changeset/plenty-wolves-rush.md), add a short user-focused summary of the changes, mark the relevant checklist items or add the skip-changeset label if appropriate, confirm local build and test status (e.g., bun run build and any added/updated tests), and state whether there are breaking public API changes.
✅ Passed checks (2 passed)
Check name Status Explanation
Title Check ✅ Passed The title "observability : insight playground" is concise and directly reflects the primary intent of the changeset—adding observability/insight features (playground, billing/pricing/receipt transparency) to the ChatPlayground UI—so a reviewer scanning history can understand the main change; minor stylistic issues (space around the colon and capitalization) do not make it misleading.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5a3e1d3 and 2877a1d.

📒 Files selected for processing (1)
  • src/components/ChatPlayground.tsx (16 hunks)

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (7)
.changeset/plenty-wolves-rush.md (1)

2-5: Tighten the changeset summary and note the new env.

Make the note more user-facing and mention the optional env var so downstreams aren’t surprised.

Apply this diff:

 --- 
 "unreal-console": minor
 --- 

-show pricing and the flow elegantly in the ui
+Add transparent pricing and receipts in the Chat Playground UI. Fetch model pricing, estimate costs, and show per‑run receipts. Adds optional VITE_UNREAL_USD for fiat display. No public API changes.

Also confirm the package name key ("unreal-console") matches your published package.

.env.example (1)

24-27: Document fiat settings and expose VITE_FIAT_CODE in the example.

The UI reads VITE_FIAT_CODE, but it’s missing here; add it and clarify what VITE_UNREAL_USD means.

Apply this diff:

 # Hardware wallet helpers for Trezor module (optional)
 VITE_TREZOR_APP_URL=https://unreal.art
 VITE_TREZOR_EMAIL=support@unreal.art

-VITE_UNREAL_USD=0.01
+# Pricing & fiat display (optional)
+# UNREAL -> fiat conversion rate (e.g., 1 UNREAL = $0.01 USD)
+VITE_UNREAL_USD=0.01
+# Fiat currency code for UI display
+VITE_FIAT_CODE=USD
src/components/ChatPlayground.tsx (5)

662-673: Request ID source likely wrong — read it from headers.

OpenAI SDK doesn’t expose result.request_id in all environments. Prefer the headers.

Apply this diff:

   headersCollected = headersObj
-  requestId = result.request_id
+  requestId =
+    headersObj["x-request-id"] ||
+    headersObj["openai-request-id"] ||
+    headersObj["x-unreal-request-id"] ||
+    (result as any)?.request_id ||
+    undefined

173-190: Use the explorer URL helper as a fallback and avoid dangling “#” links.

You defined getExplorerTxUrl but URLs rely solely on headers. Use the helper when header URLs are absent, preferring header chain id, then the active wallet chain.

Apply this diff:

   setLastRun({
@@
-    priceTx: { hash: priceTxHash, url: priceTxUrl },
-    costTx: { hash: costTxHash, url: costTxUrl },
+    priceTx: {
+      hash: priceTxHash,
+      url: priceTxUrl || getExplorerTxUrl(chainIdParsed ?? activeChainId, priceTxHash),
+    },
+    costTx: {
+      hash: costTxHash,
+      url: costTxUrl || getExplorerTxUrl(chainIdParsed ?? activeChainId, costTxHash),
+    },
@@
-    refund: {
-      amount: refundAmount,
-      tx: { hash: refundTxHash, url: refundTxUrl },
-    },
+    refund: {
+      amount: refundAmount,
+      tx: {
+        hash: refundTxHash,
+        url:
+          refundTxUrl ||
+          getExplorerTxUrl(chainIdParsed ?? activeChainId, refundTxHash),
+      },
+    },

Also applies to: 760-774


836-840: Clear transparency state when clearing messages.

Reset lastRun (and hide details/modals) to avoid stale receipts after “Clear”.

Apply this diff:

   const handleClear = useCallback(() => {
     setMessages([])
     setError(null)
+    setLastRun(null)
+    setShowDetails(false)
+    setReceiptOpen(false)
   }, [])

1278-1285: Sanitize external URLs before rendering.

Prevent javascript: or malformed URLs from being used in anchors if a hostile proxy injects headers.

Suggested helper (place near other helpers) and usage:

+const safeUrl = (u?: string) => {
+  try {
+    if (!u) return "#"
+    const url = new URL(u)
+    return url.protocol === "http:" || url.protocol === "https:" ? u : "#"
+  } catch {
+    return "#"
+  }
+}

Then replace href={lastRun.priceTx.url || "#"} (and similar) with href={safeUrl(lastRun.priceTx.url)} in the three anchor instances above.

Also applies to: 1307-1314, 1353-1360


371-375: Token estimate heuristic is fine; consider swapping in a tokenizer later.

If you want closer pre-run cost estimates, consider tiktoken, gpt-tokenizer, or your backend’s tokenizer.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5adbf75 and 5a3e1d3.

📒 Files selected for processing (3)
  • .changeset/plenty-wolves-rush.md (1 hunks)
  • .env.example (1 hunks)
  • src/components/ChatPlayground.tsx (16 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
src/components/ChatPlayground.tsx (5)
src/lib/ApiContext.tsx (1)
  • useApi (686-692)
src/lib/api.ts (1)
  • getCurrentChainId (469-485)
utils/web3/index.ts (1)
  • getChainById (21-21)
utils/web3/chains.ts (1)
  • getChainById (122-128)
src/config/unreal.ts (1)
  • OPENAI_URL (8-9)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: E2E Tests
🔇 Additional comments (4)
.changeset/plenty-wolves-rush.md (1)

2-5: Changeset included — thanks.

Minor release makes sense for a UI-only enhancement.

.env.example (1)

26-26: Good addition.

Including a default UNREAL→fiat rate improves out-of-the-box UX.

src/components/ChatPlayground.tsx (2)

994-1062: Pricing catalog UI reads well and degrades gracefully.

Good sorting, loading/empty states, and clear UNREAL-per‑1K display.


1112-1222: Transparency panel + receipts UX is solid.

Clear remaining-calls, usage, copy affordances, and exports. Nice work.

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Signed-off-by: Hiro <laciferin2024@protonmail.com>
@laciferin2024 laciferin2024 merged commit 3ee583a into main Sep 15, 2025
3 of 4 checks passed
@coderabbitai coderabbitai bot mentioned this pull request Sep 16, 2025
5 tasks
@coderabbitai coderabbitai bot mentioned this pull request Oct 16, 2025
5 tasks
@coderabbitai coderabbitai bot mentioned this pull request Nov 6, 2025
5 tasks
@coderabbitai coderabbitai bot mentioned this pull request Nov 9, 2025
5 tasks
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.

2 participants