Skip to content

feat: Cricket DRS AI — Real-time Third Umpire using Gemini Live + YOLO#379

Open
jaya6400 wants to merge 15 commits intoGetStream:mainfrom
jaya6400:main
Open

feat: Cricket DRS AI — Real-time Third Umpire using Gemini Live + YOLO#379
jaya6400 wants to merge 15 commits intoGetStream:mainfrom
jaya6400:main

Conversation

@jaya6400
Copy link
Copy Markdown

@jaya6400 jaya6400 commented Feb 26, 2026

AI-powered Third Umpire that reduces DRS review time from minutes to seconds using Gemini Live vision, YOLO pose detection,
and Stream's Voice Agents SDK.

What's added

  • examples/09_cricket_umpire/ — full working example
  • Gemini Live watching screen share at 2fps
  • YOLO11n-pose at 256px for real-time player skeleton detection
  • FastAPI trigger endpoint for frontend→agent communication
  • React frontend with Stream Video SDK

Demo

Watch Here

Blog

Medium link


Note

Medium Risk
Adds a full new runnable example (backend agent, FastAPI endpoints, token server, and React UI) plus large dependency lockfiles; main risk is integration/runtime issues from WebRTC/Gemini websocket requirements and new service credentials handling.

Overview
Adds a new examples/09_cricket_umpire end-to-end demo: a Vision Agents Agent wired to Gemini Live (2fps) plus YOLOPoseProcessor (256px) to deliver LBW/Run Out decisions via voice.

Introduces a lightweight FastAPI review trigger service (POST /review/{review_type}) that prompts the active agent, a separate FastAPI token server for Stream JWTs (/token), and a one-command run.sh to start token server, agent, and the Vite-based React UI.

Includes comprehensive documentation/instructions (README.md, cricket_umpire.md) and pins Python/Node dependencies (new requirements.txt, pyproject.toml, and frontend package-lock.json).

Written by Cursor Bugbot for commit c35a7a7. This will update automatically on new commits. Configure here.

Summary by CodeRabbit

  • New Features

    • Added a complete Cricket DRS (Decision Review System) AI example with an interactive frontend UI for managing umpire decisions, including Run Out and LBW review scenarios with AI-powered analysis and verdicts.
  • Documentation

    • Added comprehensive setup guides, deployment instructions, project structure documentation, and system behavioral specifications for the Cricket DRS example.

- cricket_umpire.py: Main agent using Gemini Live + YOLO pose detection
- cricket_umpire.md: Third umpire instructions (run out, stumping, catch, boundary)
- pyproject.toml: Project dependencies
- README.md: Setup and usage documentation
- Fixed YOLOPoseProcessor import and model name
- Added keepalive loop (every 20s) to prevent Gemini disconnecting
- Added separate token_server.py on port 8001 for frontend auth
- Agent continuously watches video and announces decisions"
- Built React frontend with Stream Video SDK
- Cricket-branded dark UI (Third Umpire AI branding)
- 5 scenario buttons: Run Out, Stumping, Catch, Boundary, LBW
- Decision log panel showing AI verdicts in real-time
- Screen share, camera, mic controls
- YOLO Pose Detection active badge
- Token fetched from token_server.py on port 8001"
- Simplified to LBW and Run Out only (DRS-focused)
- Removed YOLO processor to fix AudioQueue buffer overflow
- Added Text-to-Speech for spoken verdict on decision
- Removed fake setTimeout, replaced with DRS-accurate decisions
- Updated cricket_umpire.md with voice-trigger instructions
- Fixed run.sh to use correct script directory paths
- Cleaned up App.css to match two-panel layout
- Removed screen share audio to prevent WebRTC track timeout
- Re-added YOLOPoseProcessor at imgsz=256 (down from 320/1080p)
- Reduced Gemini fps to 2 to reduce processing load
- Root cause of AudioQueue overflow was SCREEN_SHARE_AUDIO track
- Fix: uncheck 'Share tab audio' in Chrome screen share dialog
- YOLO now runs without timeout at 256px resolution on CPU
- Added FastAPI server on port 8002 to receive review triggers
- Button click now calls POST /review/lbw or /review/runout
- Triggers agent.llm.simple_response() with analysis prompt
- Gemini watches live screen share and speaks real verdict
- YOLO pose detection running at imgsz=256 without timeouts
- Added requirements.txt for Python dependencies
- Verified: real DECISION/REVIEW TYPE/REASON/CONFIDENCE from Gemini
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Feb 26, 2026

📝 Walkthrough

Walkthrough

Introduces a complete Cricket DRS example application featuring a decision-review system for women's cricket. Includes a Python backend with an AI umpire agent using Gemini Realtime and YOLO pose detection, a token server, a FastAPI review endpoint, and a React + Vite frontend UI for managing review scenarios and displaying verdicts.

Changes

Cohort / File(s) Summary
Documentation & Specifications
examples/09_cricket_umpire/README.md, examples/09_cricket_umpire/cricket_umpire.md
Comprehensive README covering deployment, tech stack, setup workflow, and service orchestration; detailed markdown spec defining DRS system behavior, review workflows, verdict format, and decision criteria for Run Out and LBW reviews.
Backend Services
examples/09_cricket_umpire/cricket_umpire.py, examples/09_cricket_umpire/token_server.py
Agent creation with Gemini Realtime LLM and YOLO pose processor; FastAPI-based review endpoint accepting POST /review/{review_type} to trigger LBW or Run Out analysis; token generation service on port 8001 with /token and /health endpoints.
Backend & Project Configuration
examples/09_cricket_umpire/pyproject.toml, examples/09_cricket_umpire/requirements.txt
Python project metadata requiring Python >=3.12 with vision-agents, python-dotenv, and opencv-python; comprehensive dependency pin list including async frameworks, ML packages, and git-based installations.
Frontend Tooling & Configuration
examples/09_cricket_umpire/frontend/package.json, examples/09_cricket_umpire/frontend/vite.config.js, examples/09_cricket_umpire/frontend/eslint.config.js, examples/09_cricket_umpire/frontend/.gitignore
React + Vite development environment; npm scripts for dev/build/lint/preview; ESLint rules for JSX and React hooks; ignore patterns for logs, artifacts, and editor files.
Frontend Source Code
examples/09_cricket_umpire/frontend/index.html, examples/09_cricket_umpire/frontend/src/main.jsx, examples/09_cricket_umpire/frontend/src/App.jsx
HTML entry point and React bootstrapping; main App component integrating StreamVideoClient for token-based authentication, call management, and a two-tile video layout with scenario-based review triggering and transcript logging.
Frontend Styling
examples/09_cricket_umpire/frontend/src/App.css, examples/09_cricket_umpire/frontend/src/index.css, examples/09_cricket_umpire/frontend/README.md
Dark-themed CSS with variables, animations (float, spin, blink, bounce), responsive grid layouts, and component styling for header, video grid, controls, transcript, and footer; global reset and layout constraints; Vite/React template documentation.
Startup Orchestration
examples/09_cricket_umpire/run.sh
Shell script coordinating token server (port 8001) and DRS agent startup in background, then launches frontend dev server via npm run dev with cleanup trap on exit.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Poem

A third umpire stirs in silicon sleep,
Ball trajectories measured, decisions run deep—
YOLO sees what eyes cannot catch,
Verdicts stream where React meets match.
In Plath-dark code, the judgment descends,
Where cricket and AI at last transcend.

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main addition: a Cricket DRS AI example featuring real-time third umpire capability powered by Gemini Live and YOLO.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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
Copy Markdown

@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: 12

🧹 Nitpick comments (12)
examples/09_cricket_umpire/pyproject.toml (1)

14-14: Non-standard build backend specified.

setuptools.backends.legacy:build is atypical. The standard backend is setuptools.build_meta.

🛠️ Proposed fix
-build-backend = "setuptools.backends.legacy:build"
+build-backend = "setuptools.build_meta"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@examples/09_cricket_umpire/pyproject.toml` at line 14, The pyproject
specifies a non-standard build backend via build-backend =
"setuptools.backends.legacy:build"; replace this with the standard setuptools
backend by setting build-backend to "setuptools.build_meta" (update the
build-backend entry in pyproject.toml to use setuptools.build_meta) so the
project uses the supported build backend.
examples/09_cricket_umpire/README.md (1)

109-120: Consider adding language identifiers to fenced code blocks.

Markdown linters recommend specifying a language (e.g., text or plaintext) for code blocks to improve rendering consistency.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@examples/09_cricket_umpire/README.md` around lines 109 - 120, Update the
fenced code block in examples/09_cricket_umpire/README.md (the directory tree
block showing cricket_umpire.py, cricket_umpire.md, token_server.py, run.sh,
requirements.txt, and frontend/src/App.jsx/App.css) to include a language
identifier such as "text" or "plaintext" (i.e., replace the opening ``` with
```text) so Markdown linters/renderers correctly treat the block as plain text.
examples/09_cricket_umpire/frontend/eslint.config.js (1)

16-24: Redundant ecmaVersion settings.

ecmaVersion is set to 2020 at line 17 and 'latest' at line 20. The parserOptions.ecmaVersion will override the outer setting. Consider keeping only one.

🛠️ Proposed fix
     languageOptions: {
-      ecmaVersion: 2020,
       globals: globals.browser,
       parserOptions: {
         ecmaVersion: 'latest',
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@examples/09_cricket_umpire/frontend/eslint.config.js` around lines 16 - 24,
Remove the redundant ecmaVersion by keeping a single definitive setting: either
delete the outer languageOptions.ecmaVersion or remove parserOptions.ecmaVersion
so only one ecmaVersion remains; locate the languageOptions block and the nested
parserOptions (symbols: languageOptions, parserOptions, ecmaVersion) and ensure
the chosen ecmaVersion is the one in parserOptions if you expect parser-specific
behavior (or keep the outer one and remove the nested override).
examples/09_cricket_umpire/frontend/README.md (1)

1-16: Consider customizing this README for the Cricket DRS frontend.

This appears to be the default Vite template README. Consider replacing or augmenting it with project-specific documentation covering the DRS UI components, Stream Video SDK integration, and how to trigger reviews.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@examples/09_cricket_umpire/frontend/README.md` around lines 1 - 16, The
README.md in the frontend currently contains the default Vite template text;
replace or augment it with Cricket DRS-specific documentation: update README.md
to describe the DRS UI (key components like UmpireReviewPanel, BallEventList,
DecisionModal), explain how to set up and run the frontend dev server, list
Stream Video SDK integration steps and required environment variables, and
document how to trigger and test reviews (manual steps and any API endpoints or
mock data used). Ensure the new README includes a quick start, development
commands, testing instructions, and links to relevant source files and
components so contributors can quickly run and exercise the DRS review flow.
examples/09_cricket_umpire/token_server.py (1)

27-37: Consider adding return type annotations and a brief docstring.

Functions lack return type hints and docstrings per coding guidelines.

🛠️ Proposed fix
 `@app.get`("/token")
-async def get_token(user_id: str):
+async def get_token(user_id: str) -> JSONResponse:
+    """Generate a Stream token for the given user_id."""
     try:
 `@app.get`("/health")
-async def health():
+async def health() -> dict[str, str]:
+    """Health check endpoint."""
     return {"status": "ok"}

As per coding guidelines: "Use modern type annotation syntax everywhere" and "Use Google style docstrings."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@examples/09_cricket_umpire/token_server.py` around lines 27 - 37, Add a
Google-style docstring and explicit return type annotation to the FastAPI
handler get_token: document the user_id parameter and that the function returns
a fastapi.responses.JSONResponse containing either token and user_id or an
error; annotate the function signature as async def get_token(user_id: str) ->
JSONResponse. Reference the existing get_token function and the use of
StreamClient.create_token so the docstring briefly explains that it creates a
Stream token for the given user_id and returns a JSONResponse with {"token":
token, "user_id": user_id} or an error payload on exception.
examples/09_cricket_umpire/cricket_umpire.py (4)

34-43: Add a brief Google-style docstring to join_call.

Same as above—document the function purpose.

📝 Proposed fix
 async def join_call(agent: Agent, call_type: str, call_id: str, **kwargs) -> None:
+    """Join a call with the agent and announce readiness."""
     global active_agent

As per coding guidelines: "Use Google style docstrings and keep them short."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@examples/09_cricket_umpire/cricket_umpire.py` around lines 34 - 43, Add a
short Google-style docstring to the async function join_call describing its
purpose, parameters, and return type; place it immediately below the def line in
cricket_umpire.py and mention that it sets the global active_agent, creates and
joins a call via Agent.create_call/Agent.join, sends a simple_response, and
finishes the agent; include param entries for agent (Agent), call_type (str),
call_id (str), and **kwargs, plus a Returns: None line.

18-31: Add a brief Google-style docstring to create_agent.

Per guidelines, functions should have docstrings following Google style. A short summary suffices.

📝 Proposed fix
 async def create_agent(**kwargs) -> Agent:
+    """Create a Cricket DRS Third Umpire agent with Gemini and YOLO processors."""
     agent = Agent(

As per coding guidelines: "Use Google style docstrings and keep them short."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@examples/09_cricket_umpire/cricket_umpire.py` around lines 18 - 31, Add a
short Google-style docstring to the create_agent function that briefly describes
its purpose (e.g., constructs and returns an Agent configured for the Third
Umpire DRS with edge, user, instructions, LLM, and processors), mention the
return type (Agent), and place it immediately below the async def
create_agent(**kwargs) signature; ensure it is concise (one or two lines) and
follows Google docstring format (summary line plus "Returns:" section).

53-65: Add a brief docstring to trigger_review and consider returning a proper error status code.

Currently, when no agent is connected, the endpoint returns a 200 with {"error": "Agent not connected"}. A 503 or 400 would be more semantically correct.

♻️ Proposed fix
+from fastapi import FastAPI, HTTPException
+
 `@review_app.post`("/review/{review_type}")
 async def trigger_review(review_type: str):
+    """Trigger an LBW or Run Out review analysis via the active agent."""
     global active_agent
     if active_agent is None:
-        return {"error": "Agent not connected"}
+        raise HTTPException(status_code=503, detail="Agent not connected")
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@examples/09_cricket_umpire/cricket_umpire.py` around lines 53 - 65, Add a
short docstring to the endpoint function trigger_review explaining its purpose
and parameters, and change the error path so it returns a proper HTTP status
instead of a 200 JSON error; e.g., raise FastAPI's
HTTPException(status_code=503, detail="Agent not connected") or return a
Response with status_code=503 when active_agent is None, while keeping the rest
of the logic unchanged.

1-12: Move threading and uvicorn imports to the top of the module.

The coding guidelines specify that local imports should be avoided—imports belong at the module level. Currently threading and uvicorn are imported inside __main__ (lines 69-70).

♻️ Proposed fix
 import asyncio
 import logging
+import threading
 from contextlib import asynccontextmanager

 from dotenv import load_dotenv
 from fastapi import FastAPI
+import uvicorn
 from vision_agents.core import Agent, Runner, User
 from vision_agents.core.agents import AgentLauncher
 from vision_agents.plugins import gemini, getstream, ultralytics

Then remove the local imports in __main__:

 if __name__ == "__main__":
-    import threading
-    import uvicorn
-
     def run_api():

As per coding guidelines: "Do not use local imports; import at the top of the module."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@examples/09_cricket_umpire/cricket_umpire.py` around lines 1 - 12, The
threading and uvicorn imports currently done inside the __main__ block should be
moved to module-level imports at the top of the file; add "import threading" and
"import uvicorn" alongside the existing imports and remove the local imports
inside the if __name__ == '__main__': section so that no local imports remain
(look for the local usage in the __main__ block and any calls to threading or
uvicorn.run to verify behavior after moving).
examples/09_cricket_umpire/frontend/src/App.css (1)

1-1: Consider using string notation for the font import.

Stylelint prefers string notation over url() for @import statements.

📝 Proposed fix
-@import url('https://fonts.googleapis.com/css2?family=Oswald:wght@400;600;700&family=IBM+Plex+Mono:wght@400;500&family=Source+Sans+3:wght@400;500;600&display=swap');
+@import 'https://fonts.googleapis.com/css2?family=Oswald:wght@400;600;700&family=IBM+Plex+Mono:wght@400;500&family=Source+Sans+3:wght@400;500;600&display=swap';
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@examples/09_cricket_umpire/frontend/src/App.css` at line 1, The `@import` line
in App.css uses url(...) which Stylelint flags; replace the url(...) form with
string notation by changing the `@import` to use a quoted string (keeping the same
Google Fonts URL and query parameters) so the rule uses `@import`
'https://fonts.googleapis.com/…' instead of `@import` url(...), ensuring the font
families (Oswald, IBM Plex Mono, Source Sans 3) and display parameter remain
unchanged.
examples/09_cricket_umpire/frontend/src/App.jsx (1)

13-16: Consider externalizing backend URLs to environment variables.

The hardcoded localhost:8001 and localhost:8002 URLs (lines 59, 194) will break outside local development. Extract these to import.meta.env variables for flexibility.

♻️ Proposed fix
 const API_KEY = import.meta.env.VITE_STREAM_API_KEY;
+const TOKEN_SERVER_URL = import.meta.env.VITE_TOKEN_SERVER_URL || "http://localhost:8001";
+const REVIEW_API_URL = import.meta.env.VITE_REVIEW_API_URL || "http://localhost:8002";
 const CALL_TYPE = "default";

Then update usages:

-      await fetch("http://localhost:8002/review/" + scenario.id, { method: "POST" });
+      await fetch(`${REVIEW_API_URL}/review/${scenario.id}`, { method: "POST" });
-          const res = await fetch("http://localhost:8001/token?user_id=" + USER.id);
+          const res = await fetch(`${TOKEN_SERVER_URL}/token?user_id=${USER.id}`);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@examples/09_cricket_umpire/frontend/src/App.jsx` around lines 13 - 16,
Replace the hardcoded backend URLs with environment variables accessed via
import.meta.env (e.g. add VITE_BACKEND_URL and VITE_SIGNALING_URL constants and
fall back to "http://localhost:8001" / "http://localhost:8002" for local dev);
update every usage of the literal "localhost:8001" and "localhost:8002" (the
fetch/connection calls in the App where the backend and signaling endpoints are
constructed) to use these new constants so the app works outside local
development. Ensure the new env vars are referenced where CALL_ID / API_KEY are
defined and used so all endpoint construction uses the env-driven base URLs.
examples/09_cricket_umpire/frontend/index.html (1)

5-7: Update the page title and verify the favicon exists.

The generic title "frontend" should reflect the application purpose. Also ensure /vite.svg is present in the public/ folder or update the href.

📝 Proposed fix
-    <link rel="icon" type="image/svg+xml" href="/vite.svg" />
+    <link rel="icon" type="image/svg+xml" href="/vite.svg" /> <!-- or use a cricket emoji favicon -->
     <meta name="viewport" content="width=device-width, initial-scale=1.0" />
-    <title>frontend</title>
+    <title>Cricket DRS AI</title>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@examples/09_cricket_umpire/frontend/index.html` around lines 5 - 7, Update
the generic <title> element to a descriptive app name (replace "frontend" in the
<title> tag with something like "Cricket Umpire" or the actual app name) and
verify the favicon href (currently href="/vite.svg" on the <link rel="icon">)
points to an existing file in your public assets; if the file is missing, either
add vite.svg to the public/ folder or update the href to the correct favicon
path (e.g., /favicon.svg or /assets/favicon.ico) so the icon resolves.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@examples/09_cricket_umpire/cricket_umpire.py`:
- Around line 14-15: The global active_agent variable creates a race condition
when concurrent HTTP requests (e.g., /review/{review_type}) call join_call and
set/clear active_agent; protect access by introducing an asyncio.Lock (e.g.,
agent_lock) and acquire it around all places that read or write active_agent
(including join_call and any HTTP handler functions that inspect or mutate
active_agent) so modifications are serialized; ensure the lock is awaited (async
with agent_lock:) wherever active_agent is mutated or checked to prevent
interleaving and clear/reset operations from racing.
- Around line 68-80: The current pattern starts uvicorn in a daemon thread
(run_api -> uvicorn.run) and logs the server as running immediately, which can
hide startup errors; modify run_api to wrap uvicorn.run in a try/except that
logs any exception via logger.error and sets a threading.Event on success,
create a threading.Event (e.g., server_started_event) before starting
api_thread, start the thread non-daemon (api_thread = threading.Thread(...,
daemon=False)) or keep daemon but wait on the event, and only call logger.info
after the event is set (or perform a short health-check loop against
http://localhost:8002 to confirm the server is listening) so startup failures
are caught and reported before launching AgentLauncher/Runner.

In `@examples/09_cricket_umpire/frontend/src/App.jsx`:
- Around line 211-218: The disconnect function can throw from call.leave() or
client.disconnectUser(); wrap the await calls inside a try/catch and handle
errors (e.g., log them) to prevent unhandled rejections, and move state cleanup
(setCall(null), setClient(null), setStatus("idle"), setLastDecision(null)) into
a finally block so state is reset regardless of errors; update the disconnect
function and reference the existing call.leave(), client.disconnectUser(),
setCall, setClient, setStatus and setLastDecision identifiers.
- Around line 49-74: sendScenario currently starts a timeout that may run after
unmount and it also swallows fetch failures while still showing the fallback
decision; update sendScenario to store the timeout id (and any in-flight fetch
controller) in a ref, only schedule the fallback decision if the POST succeeded,
and in the catch branch push an error message to the transcript and clear
sending instead of showing the fallback decision; also add a cleanup useEffect
that clears the timeout and aborts the request on unmount to avoid setState
after unmount. Ensure you modify the logic around fetch, setTimeout,
setTranscript, setSending and call onDecision only when appropriate.

In `@examples/09_cricket_umpire/pyproject.toml`:
- Line 5: The pyproject.toml's requires-python = ">=3.12" conflicts with the
README's "Python 3.10+"; update one to match the other so they are
consistent—either change pyproject.toml's requires-python to ">=3.10" or update
the README to state "Python 3.12+"; edit the requires-python key in
pyproject.toml (and/or the Python version text in README.md) so both files
reference the same minimum Python version.

In `@examples/09_cricket_umpire/README.md`:
- Around line 13-16: Update the table link text to be descriptive for
accessibility: replace the generic "Link" label for the Frontend entry with a
descriptive phrase such as "Live demo" or the full URL (e.g., "Live demo —
ai-drs-vision-agents-sdk") and update the Backend entry text from "Runs locally
(see setup below)" to something like "Local backend (see setup below)" so screen
readers convey the destination; edit the README table row entries where the
Frontend and Backend link texts appear.

In `@examples/09_cricket_umpire/requirements.txt`:
- Around line 102-103: The requirements file currently lists Windows-only
packages pywin32 and pywin32-ctypes which will break installs on non-Windows
systems; update the requirements to conditionally install these packages using
environment markers (e.g., append a sys_platform marker like ; sys_platform ==
"win32" to the pywin32 and pywin32-ctypes entries) or move them into a
Windows-specific extras entry and/or add a README note documenting the platform
limitation so non-Windows users don’t attempt to install them unconditionally.
- Around line 136-139: Update the git dependency URLs in requirements.txt to
point to the official GetStream repository and use POSIX path separators;
specifically replace occurrences of
"git+https://github.com/jaya6400/Vision-Agents.git@..." with
"git+https://github.com/GetStream/Vision-Agents.git@..." and change any
backslashes in subdirectory fragments (e.g., "plugins\gemini" or
"plugins\ultralytics") to forward slashes ("plugins/gemini",
"plugins/ultralytics"), keeping the same `#egg` names (vision_agents,
vision_agents_plugins_gemini, vision_agents_plugins_getstream,
vision_agents_plugins_ultralytics) so pip can resolve the editable git
subpackages correctly.

In `@examples/09_cricket_umpire/run.sh`:
- Around line 6-7: The script sets SCRIPT_DIR and then runs cd "$SCRIPT_DIR"
without checking for failure; change the cd invocation (the line using
SCRIPT_DIR and the cd command) to guard against failure by testing its exit
status and aborting (or returning a non-zero exit) with an error message if cd
fails (e.g., use a conditional or "|| exit 1" style) so the script never
continues in the wrong working directory.
- Around line 28-31: The trap and directory change need two small fixes: quote
the trap body to make intent explicit (e.g., use single quotes so the kill
command is not expanded at trap definition: trap 'kill "$TOKEN_PID" "$AGENT_PID"
2>/dev/null' EXIT) and guard the cd frontend by failing early if it cannot
change directories (e.g., change the cd frontend line in run.sh to cd frontend
|| exit 1 or similar error handling) so npm run dev is not executed in the wrong
directory; update references to TOKEN_PID and AGENT_PID in the trap as shown.

In `@examples/09_cricket_umpire/token_server.py`:
- Around line 18-24: The CORS setup in app.add_middleware using CORSMiddleware
currently sets allow_origins=["*"] together with allow_credentials=True which is
insecure and blocked by browsers; update the CORSMiddleware configuration in
token_server.py (the app.add_middleware call) to either set
allow_credentials=False or replace the wildcard origin with an explicit list
(e.g., "http://localhost:3000" or your frontend URL) — alternatively use
allow_origin_regex to match trusted origins — and ensure
allow_methods/allow_headers remain as intended.
- Around line 36-37: Replace the bare except in token_server.py that currently
returns JSONResponse({"error": str(e)}, status_code=500) with explicit exception
handlers: catch KeyError for missing environment variables and return a
JSONResponse with a clear message and 400/500 as appropriate, and catch the
SDK-specific error type used by the token creation call (import and reference
the actual SDK exception class instead of a generic name) to return a
JSONResponse with that error and a 500 status; keep a final generic fallback
only if you re-raise or log it, and ensure you still use JSONResponse for the
handled cases (reference: JSONResponse and the existing except block).

---

Nitpick comments:
In `@examples/09_cricket_umpire/cricket_umpire.py`:
- Around line 34-43: Add a short Google-style docstring to the async function
join_call describing its purpose, parameters, and return type; place it
immediately below the def line in cricket_umpire.py and mention that it sets the
global active_agent, creates and joins a call via Agent.create_call/Agent.join,
sends a simple_response, and finishes the agent; include param entries for agent
(Agent), call_type (str), call_id (str), and **kwargs, plus a Returns: None
line.
- Around line 18-31: Add a short Google-style docstring to the create_agent
function that briefly describes its purpose (e.g., constructs and returns an
Agent configured for the Third Umpire DRS with edge, user, instructions, LLM,
and processors), mention the return type (Agent), and place it immediately below
the async def create_agent(**kwargs) signature; ensure it is concise (one or two
lines) and follows Google docstring format (summary line plus "Returns:"
section).
- Around line 53-65: Add a short docstring to the endpoint function
trigger_review explaining its purpose and parameters, and change the error path
so it returns a proper HTTP status instead of a 200 JSON error; e.g., raise
FastAPI's HTTPException(status_code=503, detail="Agent not connected") or return
a Response with status_code=503 when active_agent is None, while keeping the
rest of the logic unchanged.
- Around line 1-12: The threading and uvicorn imports currently done inside the
__main__ block should be moved to module-level imports at the top of the file;
add "import threading" and "import uvicorn" alongside the existing imports and
remove the local imports inside the if __name__ == '__main__': section so that
no local imports remain (look for the local usage in the __main__ block and any
calls to threading or uvicorn.run to verify behavior after moving).

In `@examples/09_cricket_umpire/frontend/eslint.config.js`:
- Around line 16-24: Remove the redundant ecmaVersion by keeping a single
definitive setting: either delete the outer languageOptions.ecmaVersion or
remove parserOptions.ecmaVersion so only one ecmaVersion remains; locate the
languageOptions block and the nested parserOptions (symbols: languageOptions,
parserOptions, ecmaVersion) and ensure the chosen ecmaVersion is the one in
parserOptions if you expect parser-specific behavior (or keep the outer one and
remove the nested override).

In `@examples/09_cricket_umpire/frontend/index.html`:
- Around line 5-7: Update the generic <title> element to a descriptive app name
(replace "frontend" in the <title> tag with something like "Cricket Umpire" or
the actual app name) and verify the favicon href (currently href="/vite.svg" on
the <link rel="icon">) points to an existing file in your public assets; if the
file is missing, either add vite.svg to the public/ folder or update the href to
the correct favicon path (e.g., /favicon.svg or /assets/favicon.ico) so the icon
resolves.

In `@examples/09_cricket_umpire/frontend/README.md`:
- Around line 1-16: The README.md in the frontend currently contains the default
Vite template text; replace or augment it with Cricket DRS-specific
documentation: update README.md to describe the DRS UI (key components like
UmpireReviewPanel, BallEventList, DecisionModal), explain how to set up and run
the frontend dev server, list Stream Video SDK integration steps and required
environment variables, and document how to trigger and test reviews (manual
steps and any API endpoints or mock data used). Ensure the new README includes a
quick start, development commands, testing instructions, and links to relevant
source files and components so contributors can quickly run and exercise the DRS
review flow.

In `@examples/09_cricket_umpire/frontend/src/App.css`:
- Line 1: The `@import` line in App.css uses url(...) which Stylelint flags;
replace the url(...) form with string notation by changing the `@import` to use a
quoted string (keeping the same Google Fonts URL and query parameters) so the
rule uses `@import` 'https://fonts.googleapis.com/…' instead of `@import` url(...),
ensuring the font families (Oswald, IBM Plex Mono, Source Sans 3) and display
parameter remain unchanged.

In `@examples/09_cricket_umpire/frontend/src/App.jsx`:
- Around line 13-16: Replace the hardcoded backend URLs with environment
variables accessed via import.meta.env (e.g. add VITE_BACKEND_URL and
VITE_SIGNALING_URL constants and fall back to "http://localhost:8001" /
"http://localhost:8002" for local dev); update every usage of the literal
"localhost:8001" and "localhost:8002" (the fetch/connection calls in the App
where the backend and signaling endpoints are constructed) to use these new
constants so the app works outside local development. Ensure the new env vars
are referenced where CALL_ID / API_KEY are defined and used so all endpoint
construction uses the env-driven base URLs.

In `@examples/09_cricket_umpire/pyproject.toml`:
- Line 14: The pyproject specifies a non-standard build backend via
build-backend = "setuptools.backends.legacy:build"; replace this with the
standard setuptools backend by setting build-backend to "setuptools.build_meta"
(update the build-backend entry in pyproject.toml to use setuptools.build_meta)
so the project uses the supported build backend.

In `@examples/09_cricket_umpire/README.md`:
- Around line 109-120: Update the fenced code block in
examples/09_cricket_umpire/README.md (the directory tree block showing
cricket_umpire.py, cricket_umpire.md, token_server.py, run.sh, requirements.txt,
and frontend/src/App.jsx/App.css) to include a language identifier such as
"text" or "plaintext" (i.e., replace the opening ``` with ```text) so Markdown
linters/renderers correctly treat the block as plain text.

In `@examples/09_cricket_umpire/token_server.py`:
- Around line 27-37: Add a Google-style docstring and explicit return type
annotation to the FastAPI handler get_token: document the user_id parameter and
that the function returns a fastapi.responses.JSONResponse containing either
token and user_id or an error; annotate the function signature as async def
get_token(user_id: str) -> JSONResponse. Reference the existing get_token
function and the use of StreamClient.create_token so the docstring briefly
explains that it creates a Stream token for the given user_id and returns a
JSONResponse with {"token": token, "user_id": user_id} or an error payload on
exception.

ℹ️ Review info

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between f684ece and c35a7a7.

⛔ Files ignored due to path filters (9)
  • examples/09_cricket_umpire/docs/screenshots/bash.PNG is excluded by !**/*.png
  • examples/09_cricket_umpire/docs/screenshots/frontend.PNG is excluded by !**/*.png
  • examples/09_cricket_umpire/docs/screenshots/realtime-voice-agent.PNG is excluded by !**/*.png
  • examples/09_cricket_umpire/docs/screenshots/stream-ui.PNG is excluded by !**/*.png
  • examples/09_cricket_umpire/docs/videos/lbw.mp4 is excluded by !**/*.mp4
  • examples/09_cricket_umpire/docs/videos/ro.mp4 is excluded by !**/*.mp4
  • examples/09_cricket_umpire/frontend/package-lock.json is excluded by !**/package-lock.json
  • examples/09_cricket_umpire/frontend/public/vite.svg is excluded by !**/*.svg
  • examples/09_cricket_umpire/frontend/src/assets/react.svg is excluded by !**/*.svg
📒 Files selected for processing (17)
  • examples/09_cricket_umpire/README.md
  • examples/09_cricket_umpire/cricket_umpire.md
  • examples/09_cricket_umpire/cricket_umpire.py
  • examples/09_cricket_umpire/frontend/.gitignore
  • examples/09_cricket_umpire/frontend/README.md
  • examples/09_cricket_umpire/frontend/eslint.config.js
  • examples/09_cricket_umpire/frontend/index.html
  • examples/09_cricket_umpire/frontend/package.json
  • examples/09_cricket_umpire/frontend/src/App.css
  • examples/09_cricket_umpire/frontend/src/App.jsx
  • examples/09_cricket_umpire/frontend/src/index.css
  • examples/09_cricket_umpire/frontend/src/main.jsx
  • examples/09_cricket_umpire/frontend/vite.config.js
  • examples/09_cricket_umpire/pyproject.toml
  • examples/09_cricket_umpire/requirements.txt
  • examples/09_cricket_umpire/run.sh
  • examples/09_cricket_umpire/token_server.py

Comment thread examples/09_cricket_umpire/cricket_umpire.py
Comment thread examples/09_cricket_umpire/cricket_umpire.py
Comment thread examples/09_cricket_umpire/frontend/src/App.jsx
Comment thread examples/09_cricket_umpire/frontend/src/App.jsx
Comment thread examples/09_cricket_umpire/pyproject.toml
Comment thread examples/09_cricket_umpire/requirements.txt
Comment thread examples/09_cricket_umpire/run.sh
Comment thread examples/09_cricket_umpire/run.sh
Comment thread examples/09_cricket_umpire/token_server.py
Comment thread examples/09_cricket_umpire/token_server.py
Copy link
Copy Markdown
Contributor

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 4 potential issues.

Bugbot Free Tier Details

Your team is on the Bugbot Free tier. On this plan, Bugbot will review limited PRs each billing cycle for each member of your team.

To receive Bugbot reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial.

Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Comment thread examples/09_cricket_umpire/cricket_umpire.py
Comment thread examples/09_cricket_umpire/cricket_umpire.py
Comment thread examples/09_cricket_umpire/requirements.txt
Comment thread examples/09_cricket_umpire/frontend/src/App.jsx
@jaya6400
Copy link
Copy Markdown
Author

jaya6400 commented Mar 1, 2026

Hi Vision Agents team 👋
I built 'Cricket DRS AI' as part of the Vision Agents Hackathon and would be happy to see it merged into the repo!
Happy to fix the CORS and requirements.txt path issues flagged by the bots if needed.
Let me know!

@Nash0x7E2 @aliev

@jaya6400
Copy link
Copy Markdown
Author

Hi Vision Agents team 👋 I built 'Cricket DRS AI' as part of the Vision Agents Hackathon and would be happy to see it merged into the repo! Happy to fix the CORS and requirements.txt path issues flagged by the bots if needed. Let me know!

@Nash0x7E2 @aliev

Hi 👋

Just following up on this PR — happy to address any remaining feedback or fix the issues flagged by the bots (CORS, path fixes, decision badge logic) if that helps move things forward.

Let me know if there's anything blocking the review. Thanks for your time!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant