Skip to content

Add pre-session billing and cost notice - #436

Open
AchlysChang wants to merge 1 commit into
sysprog21:mainfrom
AchlysChang:pre-session-cost-warning
Open

AchlysChang wants to merge 1 commit into
sysprog21:mainfrom
AchlysChang:pre-session-cost-warning

Conversation

@AchlysChang

@AchlysChang AchlysChang commented Oct 22, 2026 •

Copy link
Copy Markdown

Draw problems from a saved practice listImplements the pre-session cost warning notification for Issue #161. Adds clear cost and billing explanations to the setup screen and the interview lobby before starting, informing users that Gemini Live API continuous audio streaming and rolling context accumulation consume tokens rapidly and require sufficient prepaid credit or active billing.

Refs #161

UI Verification

  • Original
origin
  • Lobby - Coding Mode (Default):
1
  • Lobby - Coding Mode (With Example Drawing):
2
  • Lobby - Whiteboard Mode:
3

Summary by cubic

Warns candidates on the setup page and in the interview lobby that a Live interview bills the server's Google AI project, so they see the cost before starting.

  • The lobby shows a notice above Start once /api/session reports candidateVideo, and names voice and video only when that flag is active for the chosen mode; whiteboard mode never mentions video.
  • The setup page adds the same billing note in the Google AI section.
  • Whiteboard mode suppresses video at boot; the notice and candidateVideo flag account for that so billing text stays accurate per mode.

Written for commit 9e6ab86. Summary will update on new commits.

View guided diff

jserv

This comment was marked as outdated.

cubic-dev-ai[bot]

This comment was marked as resolved.

@jserv jserv left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Avoid ambiguous Refs #161. Always specify Close #? instead.

@AchlysChang
AchlysChang force-pushed the pre-session-cost-warning branch from 9d281e8 to 9c008bf Compare October 22, 2026 14:33

@jserv jserv left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Check CONTRIBUTING.md carefully.
Always use git rebase instead of git merge.

Comment thread web/app.js Outdated
Comment thread web/app.js Outdated
An interview opens a Gemini Live session that bills the server's
Google AI project on every turn. The lobby now shows a billing
notice above Start once /api/session reports candidateVideo, linked
via aria-describedby, stating that the provider is billed on the
whole context it runs in and naming voice and video only when
candidate video is active for the chosen mode. The Setup page states
the same in the Google AI section.

Refs sysprog21#161
@AchlysChang
AchlysChang force-pushed the pre-session-cost-warning branch from 9c008bf to 9e6ab86 Compare October 23, 2026 03:21
Comment thread src/web/auth.rs
// Candidate video is sent to Gemini only when the flag is enabled and the
// interview mode is not whiteboard; whiteboard suppresses it at boot time.
// Exposed here so the lobby can mention video cost only when it applies.
let candidate_video = state.config.gemini_candidate_video_enabled;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The value of candidateVideo comes from the web process's own CODETRIAL_GEMINI_CANDIDATE_VIDEO_ENABLED. That only matches what happens in the interview when this process also hosts the interviewer. When there is no GOOGLE_API_KEY, main.rs serves the web side only and the agent joins from another host with its own environment. The flag here then usually defaults to false and the lobby promises "voice" while the real agent forwards video. Take the value from the local agent config when one was loaded, and send null (or leave the field out) otherwise, so the lobby does not state something it cannot know.

Comment thread web/app.js
applyCostNote();
}

/// Show a billing notice above the Start button when the server has a Gemini

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The comment says the notice appears "when the server has a Gemini key", but nothing checks for one. /api/session always returns a boolean, so the notice shows on every server, including one with no interviewer configured at all, where the candidate ends up in offline practice. Either gate the notice on an interviewer actually being available or fix the comment. As it stands, the comment describes a check that does not exist.

Comment thread web/app.js
function applyCostNote() {
const videoActive = candidateVideo === true && mode !== "whiteboard";
const text = videoActive
? "This interview uses voice and video. The provider is billed on the whole context it runs in."

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

"The provider is billed" does not tell the reader who pays, which is the point of #161. A candidate can read it as their own account being charged. Name the payer, for example "Gemini Live usage is billed to this server's Google AI project, on the whole context of the session." The setup page note has the same gap.

Comment thread web/app.js
const text = videoActive
? "This interview uses voice and video. The provider is billed on the whole context it runs in."
: candidateVideo !== null
? "This interview uses voice. The provider is billed on the whole context it runs in."

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

In whiteboard mode the camera is off, but the board still goes to Gemini as realtime images on the same stream (see the candidate_video doc comment in src/runtime.rs), and those images are billed context too. "This interview uses voice" undersells the cost in exactly the mode that sends the most images. Mention the board images in whiteboard mode, and update the "voice alone otherwise" wording in docs/provider-cost-and-degradation.md to match.

session = { signedIn: false };
await page.goto(`${base}/`, { waitUntil: "domcontentloaded" });
await page.waitForFunction(
() => document.querySelector("#account-status").textContent !== "",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

#account-status starts out as "Checking account..." in index.html, so this wait passes immediately, before /api/session has been handled, and the assertion runs against the notice's initial hidden attribute. The test passes even if loadAccount would wrongly reveal the notice. Wait for something the session response changes (or hold the route open, check that the notice is hidden, then release it), so the assertion runs after the response has been processed.

@jserv jserv left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Avoid ambiguous references such as Refs #161. Complete the implementation and close the issue properly.

@jserv jserv left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

CI fails on the indent gate. Run make indent, then amend and force-push.

@jserv

jserv commented Oct 23, 2026

Copy link
Copy Markdown
Contributor

@AchlysChang To settle the two requests about the issue reference: this PR covers the pre-session cost warning accepted on #161 on 2026-10-12, while the session length cap and the text-only toggle stay open there, so it does not close #161 and Refs #161 stays. The later request to close the issue is withdrawn. For Refs to stand on its own, CONTRIBUTING.md asks the body to state the motivation and the implementation in full: say where the notice appears (the setup page and the lobby), when it is shown or hidden, and which part of docs/provider-cost-and-degradation.md its wording follows. Also remove the leftover first line, "Draw problems from a saved practice list".

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