Skip to content

Frontend v0.3 + GCP integration (Vertex AI / Cloud Run / BigQuery)#1

Merged
Vector897 merged 2 commits into
mainfrom
feat/gcp-integration
Jun 27, 2026
Merged

Frontend v0.3 + GCP integration (Vertex AI / Cloud Run / BigQuery)#1
Vector897 merged 2 commits into
mainfrom
feat/gcp-integration

Conversation

@Vector897

Copy link
Copy Markdown
Owner

Summary

  • Frontend v0.3 — 6/6 bonus items complete: persona picker, voice mode (en-GB), adaptive difficulty badge, streak counter, turning-point replay modal, evidence-anchored debrief
  • 2 new UK law scenarios — M&A Indemnity Cap (English law SPA) + CDPA 1988 commissioned works (Difficult Client)
  • GCP prize track integration:
    • Dockerfile + .dockerignore → Cloud Run deployment in europe-west2
    • llm.py → auto-routes to Vertex AI Gemini 2.0 Flash when GCP_PROJECT is set (judge/scoring calls); OpenRouter Claude stays for main adversary
    • data/bigquery.pyBigQuery whetstone.corpus table with graceful SQLite fallback
    • config.pyGCP_PROJECT, VERTEX_LOCATION; JUDGE_MODEL defaults to gemini-2.0-flash-001 when GCP is configured
    • /api/health reports gcp.vertex_ai and gcp.bigquery status

Deploy to Cloud Run

gcloud auth login
gcloud config set project YOUR_PROJECT_ID
gcloud run deploy whetstone \
  --source . --port 8080 --allow-unauthenticated \
  --region europe-west2 \
  --set-env-vars="OPENROUTER_API_KEY=...,GCP_PROJECT=YOUR_PROJECT_ID,VERTEX_LOCATION=europe-west2"

Test plan

  • Dojo: all 4 scenario cards load; persona picker works for each
  • Chat: voice mic (Chrome/Edge), difficulty badge visible in header
  • End Round → Debrief: rubric, turning-point, root cause
  • Dashboard: radial progress, sparklines, streak, recommended difficulty
  • Redact: Presidio detection + HITL toggle
  • Red/Blue: debate generates + flaw grading works
  • /api/healthgcp.vertex_ai: true after adding GCP_PROJECT to env

🤖 Generated with Claude Code

- Persona picker (Hardball / Slippery / Stone Wall) before each session
- Adaptive difficulty badge + indicator in session header (Level 1-3)
- Voice mode (Web Speech API, en-GB, interim → input field, pulse ring)
- Streak counter + sparklines on Dashboard
- Replay Turning Point modal with exchange replay
- Evidence-anchored debrief with root cause panel
- negotiation_ma_indemnity_cap_uklaw_v1.json — M&A SPA English law
- difficult_client_ip_uk_v1.json — CDPA 1988 s.11(1) copyright
- hot_seat_v1.json teammate update (GDPR Art 33, polished pressure lines)
- db.py: adaptive difficulty + persona columns; state.py/main.py updated
- adversary.py: per-difficulty modifier + per-arena system prompt builders
- Concession gate referee now calibrated to difficulty level
- Dockerfile + .dockerignore for Cloud Run deployment (europe-west2)
- llm.py: auto-route to Vertex AI Gemini when model starts with 'gemini'
  and GCP_PROJECT is configured; OpenRouter remains fallback
- config.py: GCP_PROJECT, VERTEX_LOCATION; JUDGE_MODEL auto-defaults to
  gemini-2.0-flash-001 when GCP_PROJECT is set
- data/bigquery.py: BigQuery corpus layer (whetstone.corpus table);
  graceful fallback to SQLite when GCP not configured
- main.py: ensure_table() on startup; /api/health reports GCP status;
  corpus search prefers BigQuery over SQLite
- requirements.txt: google-cloud-aiplatform>=1.60.0, google-cloud-bigquery>=3.11.0
- .gitignore: carve out backend/requirements.txt from *.txt rule
Copilot AI review requested due to automatic review settings June 27, 2026 12:55
@Vector897
Vector897 merged commit e704778 into main Jun 27, 2026
1 check passed

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.

Pull request overview

This PR upgrades the Whetstone single-file React frontend to “v0.3” (personas, voice mode, adaptive difficulty UI, streak/progress widgets, turning-point replay) and adds GCP prize-track integrations for Cloud Run deployment, Vertex AI (Gemini routing), and BigQuery-backed corpus search with SQLite fallback.

Changes:

  • Frontend: persona picker + voice input + richer debrief/dashboard UX (turning-point replay, streak, sparklines, difficulty badge).
  • Backend: adaptive difficulty + persona persisted on sessions; optional Vertex AI + BigQuery integration; health endpoint reports GCP status.
  • Deployment: Cloud Run-ready Dockerfile/.dockerignore and Python requirements.

Reviewed changes

Copilot reviewed 14 out of 15 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
frontend/index.html Frontend v0.3 UX updates (personas, voice mode, debrief/dashboard improvements).
Dockerfile Adds container build/run for Cloud Run (uvicorn entrypoint).
backend/requirements.txt Introduces backend dependency set (FastAPI/uvicorn/OpenAI + GCP libs).
backend/app/state.py Adds persona + adaptive difficulty to session creation/load.
backend/app/scenarios/negotiation_ma_indemnity_cap_uklaw_v1.json Adds new UK-law negotiation scenario (SPA liability cap/basket/disclosure).
backend/app/scenarios/hot_seat_v1.json Updates Hot Seat prompt lines/proposition wording.
backend/app/scenarios/difficult_client_ip_uk_v1.json Adds new UK copyright “difficult client” scenario.
backend/app/main.py Adds BigQuery startup init + GCP status in health + BQ-first corpus search.
backend/app/llm.py Adds routing: Vertex AI Gemini when model starts with gemini and GCP is configured.
backend/app/engines/adversary.py Adds adaptive difficulty + runtime persona override into adversary prompts/referee.
backend/app/db.py Extends sessions schema and adds adaptive difficulty computation.
backend/app/data/bigquery.py Adds BigQuery corpus layer with graceful SQLite fallback.
backend/app/config.py Adds GCP project/location config and defaults judge model to Gemini when GCP is set.
.gitignore Un-ignores backend/requirements.txt despite *.txt rule.
.dockerignore Defines Docker build context exclusions.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread .dockerignore
Comment on lines +10 to +12
*.md
*.txt
*.pdf
Comment thread backend/app/db.py
Comment on lines +63 to 68
def session_create(sid: str, scenario_id: str, lawyer_id: str,
persona: str = "Hardball", difficulty: int = 2) -> None:
_conn().execute(
"INSERT OR REPLACE INTO sessions (id, scenario_id, lawyer_id) VALUES (?,?,?)",
(sid, scenario_id, lawyer_id))
"INSERT OR REPLACE INTO sessions (id, scenario_id, lawyer_id, persona, difficulty) VALUES (?,?,?,?,?)",
(sid, scenario_id, lawyer_id, persona, difficulty))
_conn().commit()
Comment thread backend/app/main.py
Comment on lines 224 to +228
@app.get("/api/corpus/search")
def corpus_search(clause_type: str = "liability_cap", limit: int = 5):
return {"results": db.corpus_search(clause_type, limit)}
# Prefer BigQuery when GCP is configured, fall back to SQLite
results = bq.search(clause_type, limit) or db.corpus_search(clause_type, limit)
return {"results": results, "source": "bigquery" if bq.active() else "sqlite"}
Comment thread frontend/index.html
Comment on lines +55 to 57
const {useState,useEffect,useRef,useCallback,useMemo}=React;
const API="http://localhost:8000";

Comment thread frontend/index.html
Comment on lines +331 to +343
{msgs.map((m,i)=>{
const turnNum=Math.ceil((i)/2)+1;
const isHighlight=highlightTurn&&turnNum===highlightTurn&&m.role==="user";
return(
<div key={i} id={`turn-${turnNum}`}
className={cl("flex arise",m.role==="user"?"justify-end":"justify-start")}>
<div className={cl("max-w-[80%] rounded-2xl px-4 py-3 text-sm leading-relaxed",
m.role==="user"?"bg-blade text-ink font-medium":"bg-panel2 border border-edge",
isHighlight&&"ring-2 ring-gold ring-offset-1 ring-offset-panel")}>
<div className={cl("text-[10px] uppercase tracking-widest font-semibold mb-1.5",
m.role==="user"?"text-ink/60":"text-muted")}>
{m.role==="user"?"You":"Opposing Counsel"}
{m.role==="user"&&<span className="ml-1 opacity-50">Turn {Math.ceil(i/2)+1}</span>}
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