Skip to content

Conversation

@Kalpana-chavhan
Copy link

@Kalpana-chavhan Kalpana-chavhan commented Jan 8, 2026

Overview

Communication shouldn't have a language barrier. This PR introduces a robust, real-time translation layer that allows users to participate in debates using their preferred language,regardless of whether they are facing a human opponent in a WebSocket room or training against our AI bots.

By leveraging Google’s Gemini AI, we now translate incoming and outgoing arguments on the fly, ensuring that the core of the debate, the logic and the rhetoric remains intact across different languages.


Core Enhancements

  1. The Translation Engine (backend/services)
    Developed a centralized TranslateContent service that interfaces with Gemini.
    Implemented smart caching/initialization to ensure the API is only called when a language mismatch is detected.

  2. Seamless PvP Experience (backend/websocket)
    Integrated the translation logic directly into the WebSocket broadcast cycle.
    The Result: If Player A speaks English and Player B speaks Spanish, the system translates the payload mid-transit, allowing both users to see the argument in their native tongue instantly.

  3. Bot Mode Intelligence (backend/main.go & frontend)
    Exposed a new /api/translate REST endpoint to bridge the Gap for the Bot Room.
    Updated the DebateRoom logic to intercept bot-generated English responses and translate them before they hit the state, providing a localized experience for solo practice.


Technical Implementation Details

  • Backend: Built with Go and Gin. I've added a custom CORS configuration to handle the cross-origin requests between the React frontend and the new translation API.
  • Frontend: Refactored the handleBotTurn function in React to utilize an async translation bridge, complete with error boundaries to fallback to English if the translation service is unreachable.
  • Efficiency: Added checks to skip translation calls if the target_lang matches the source, saving API quota and reducing latency.

issue(s)

closes #171


How to Test

  • Environment: Ensure GEMINI_API_KEY is set in your .env.
  • User Settings: Set your profile language to something other than English (e.g., "Spanish" or "French").
  • Bot Debate: Start a "Bot Mode" debate. The bot's arguments should appear in your selected language.
  • PvP Debate: Open two browser windows with users set to different languages. Send a message from one; it should arrive translated in the other.

Closing Note

This feature significantly increases the accessibility of ArgueHub, opening the doors for a global user base to practice their debating skills without language constraints.

Summary by CodeRabbit

  • New Features
    • Real-time debate rooms with media capture, transcription, and live broadcasting.
    • Translation service integrated for on-demand and in-stream translations (API + WebSocket).
    • Chat UI: toggle between translated and original text; messages include translation metadata.
  • Refactor
    • Bot turn flow and state updates simplified for more reliable turn progression.
  • Chores
    • Environment config loading at startup and translation service initialization.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link

coderabbitai bot commented Jan 8, 2026

Caution

Review failed

An error occurred during the review process. Please try again later.

📝 Walkthrough

Walkthrough

Adds multilingual real-time translation: initializes Gemini, provides TranslateContent service, exposes HTTP and WebSocket translation endpoints, expands WebSocket message schema, implements a full debate WebSocket flow with media capture/transcription/translation, and updates frontend chat UI to show/toggle translated vs original text.

Changes

Cohort / File(s) Summary
Server bootstrap & routes
backend/cmd/server/main.go
Load .env, init Gemini via InitGemini, register HTTP /api/translate and WebSocket translation route.
Gemini client & helpers
backend/services/gemini.go
Add global GeminiInstance, InitGemini(apiKey string) error, switch default model constant, export GenerateDefaultModelText, validate client usage.
Translation service
backend/services/translation.go
New TranslateContent(content, fromLang, toLang) that builds prompt, calls Gemini, trims/cleans output, and returns translated text or original on error/early-exit.
Translation DTOs
backend/dto/translation.go
New TranslationRequest and TranslationResponse types for HTTP/API payloads.
WebSocket translation endpoint
backend/websocket/translation_handler.go
New HTTP/WS handler TranslationHandler with TranslationRequest/TranslationResponse, validates input, calls services.TranslateContent.
WebSocket message schema
backend/structs/websocket.go, backend/websocket/websocket.go
Expand Message with Room, Username, UserID, OriginalText, SenderLanguage, TargetLanguage, IsTranslated, Timestamp; integrate translation step on incoming messages and propagate metadata when broadcasting.
Debate orchestration (WebSocket)
backend/websocket/handler.go
New, large debate flow: room management, participant sync, per-turn media capture, transcript POSTs, calls services.TranslateContent, broadcasts events (DEBATE_START/END, SECTION/TURN events), and persists translated/original transcript messages.
Frontend debate flow
frontend/src/Pages/DebateRoom.tsx
Refactor bot turn handling to fetch bot response, optionally call translation API, use translated text in state updates, and advance turns reliably.
Frontend chat UI
frontend/src/components/Chatbox.tsx
Add MessageContent component to toggle original vs translated text; extend ChatMessage with originalText and isTranslated; update onSendMessage signature to include senderLang and targetLang.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant WS as WebSocket Server
    participant Media as Media Capture
    participant Trans as Transcription API
    participant Gemini as Gemini API

    Client->>WS: Join room
    WS->>WS: Wait for second participant
    WS->>Client: DEBATE_START

    loop per section/turn
        WS->>Client: TURN_START
        Client->>Media: Send audio binary
        Media->>Media: Save media file
        WS->>Trans: POST audio file for transcription
        Trans->>WS: Return transcribed text

        alt translation requested (sender != target)
            WS->>Gemini: TranslateContent(transcribed, source, target)
            Gemini->>WS: Return translated text
            WS->>Client: CHAT_MESSAGE (content=translated, originalText=transcribed, isTranslated=true)
        else no translation
            WS->>Client: CHAT_MESSAGE (content=transcribed, isTranslated=false)
        end

        WS->>Client: TURN_END
    end

    WS->>Client: DEBATE_END
    WS->>WS: Close connections & expire room
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~75 minutes

Possibly related PRs

Poem

🐰
I hopped into sockets, ears tuned to chat,
I fetched sweet words from Gemini’s hat,
I stitched originals with translated song,
Now debates speak many tongues all along,
Carrots for code — the burrow sings along!

🚥 Pre-merge checks | ✅ 4 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 9.09% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title clearly describes the main change: implementation of a real-time translation engine for cross-lingual debates, which accurately reflects the primary objective and scope of all modifications.
Linked Issues check ✅ Passed The code implements all key requirements from issue #171: real-time translation service (backend/services/translation.go), AI-powered translation via Gemini, language metadata in messages, WebSocket integration for message translation, frontend language selection and translation toggling (Chatbox), and REST API endpoint.
Out of Scope Changes check ✅ Passed All changes are directly related to implementing real-time translation: backend translation service, Gemini initialization, WebSocket message translation, frontend translation UI, and debate room translation logic. No unrelated modifications detected.

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


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

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

🤖 Fix all issues with AI agents
In @backend/cmd/server/main.go:
- Around line 195-221: Create a single shared DTO package (e.g., package dto)
that defines TranslationRequest and TranslationResponse, remove the duplicate
type declarations from both places, and update code to import dto and use
dto.TranslationRequest/dto.TranslationResponse; keep only one TranslationHandler
implementation (choose the existing websocket.TranslationHandler or
main.TranslationHandler), delete the duplicate handler, and wire your routes to
call the single exported TranslationHandler function from its package. Ensure
package imports and references to services.TranslateContent remain correct after
moving types.
- Line 31: Remove the unused variable declaration apiKey :=
os.Getenv("GEMINI_API_KEY") and ensure the code uses the existing geminiKey
variable instead (geminiKey := os.Getenv("GEMINI_API_KEY")), so the environment
value is only read once and no redundant/unused apiKey symbol remains; update
any references to use geminiKey if necessary.

In @backend/services/gemini.go:
- Line 14: The package-level variable geminiClient is unexported but needed by
backend/services/translation.go; either export it by renaming geminiClient to
GeminiInstance and update all internal references (functions like
GenerateDefaultModelText, any other usages) to use GeminiInstance, or add a
small exported accessor wrapper (e.g., GenerateContent) in gemini.go that calls
the existing GenerateDefaultModelText and returns the generated text and error
so translation.go can call that instead; choose one approach and apply it
consistently across the package.

In @backend/services/translation.go:
- Around line 27-32: The code references gemini.GeminiInstance which doesn't
exist; update the usage to the actual global variable name geminiClient (or
alternatively export the instance from gemini.go as GeminiInstance and update
InitGemini accordingly). Specifically, replace references to
gemini.GeminiInstance in TranslateText (and any other uses) with geminiClient,
or modify gemini.go to declare and initialize an exported GeminiInstance symbol
and update InitGemini to set it so the existing calls compile.
- Line 7: Replace the wrong import and variable usage: change the import to
"arguehub/services/gemini" (matching module name) and update any uses of
gemini.GeminiInstance to the actual exported symbol from the gemini package
(open backend/services/gemini/gemini.go to find the exported constructor/type
name — e.g., GeminiClient, NewGeminiClient, or similar — and use that instead of
the nonexistent GeminiInstance).

In @backend/websocket/handler.go:
- Around line 403-407: The package-level variable rooms and its mutex roomMu in
handler.go conflict with another rooms declaration in websocket.go; rename the
handler.go variables (e.g., debateRooms and debateRoomMu or handlerRooms and
handlerRoomMu) and update every reference in handler.go (including types
referencing structs.Room) accordingly, or alternatively consolidate room
management by removing one variable and using the shared manager from
websocket.go (ensure types match: structs.Room vs Room) and update all usages to
the chosen symbol to fix the redeclaration compilation error.
- Around line 368-369: The file contains a duplicate "package websocket"
declaration (second occurrence around line 369) which breaks compilation; remove
the redundant package declaration so the file only has a single "package
websocket" at the top, and ensure any code following that duplicate is not part
of a stray package statement.
- Around line 577-594: The generateTranscript function lacks error handling and
a request timeout; fix by checking the json.Marshal error for payload creation,
use an http.Client with a reasonable Timeout instead of http.Post to avoid
hanging, check resp.StatusCode and return an error for non-2xx responses before
decoding, handle and return the error from json.NewDecoder(resp.Body).Decode
into the result struct, and propagate any errors back to the caller from
generateTranscript.
- Around line 551-561: The translation block currently calls
services.TranslateContent(transcript, "en", "es") which hardcodes source/target
languages and ignores user preferences; change it to obtain the user's preferred
target language (e.g., from the connection/session user object like
user.PreferredLanguage or session.Language) and, if available, pass that as the
target lang to services.TranslateContent (and avoid assuming the source is
"en"—either detect source via existing language-detection utilities or use a
user/source profile field if present); update references around translatedText,
finalMessage and isTranslated so translation only runs when a target preference
exists and falls back to the original transcript otherwise.

In @backend/websocket/translation_handler.go:
- Around line 10-19: TranslationRequest and TranslationResponse are duplicated
in translation_handler.go and main.go; extract those two structs into a shared
package (e.g., package dto or structs) and import that package from both
websocket/translation_handler.go and backend/cmd/server/main.go so both files
reference dto.TranslationRequest and dto.TranslationResponse (preserve JSON
tags), then either remove the unused Error field from dto.TranslationResponse or
ensure all error paths populate its Error string before sending responses from
both translation handler and server code; update imports and any code that
referenced the old local types accordingly.
- Around line 21-42: There are two problems: this TranslationHandler duplicates
the one in main.go (remove the duplicate and keep a single canonical
TranslationHandler) and the source language is hardcoded to "en"; modify the
request payload struct to accept a source_lang field (e.g., SourceLang) and use
that value when calling services.TranslateContent instead of the hardcoded "en"
(fall back to a sensible default if SourceLang is empty), and ensure only one
TranslationHandler implementation remains (update any imports/route
registrations to point to the retained handler).

In @frontend/src/components/Chatbox.tsx:
- Around line 165-173: Replace the hardcoded senderLang and targetLang in
Chatbox.tsx by deriving them from the current user's settings or props rather
than literals: get the language values the same way as DebateRoom.tsx uses
user?.language (or accept a language prop on the Chatbox component), then pass
those variables into the existing onSendMessage call
(onSendMessage(inputText.trim(), inputMode, senderLang, targetLang)). Update the
Chatbox props or hook to access the user/settings context and remove the
"en"/"es" literals so languages reflect the real user settings.

In @frontend/src/Pages/DebateRoom.tsx:
- Around line 491-502: The variable context is left empty but passed into
sendDebateMessage; populate it before the call by building a meaningful context
string (e.g., prefer an explicit debateData.context or debateData.background if
present, otherwise derive it from debateData.topic, debate rules/metadata and
recent state.messages—for example concatenate the last N messages or any
system/instructions messages into a single string). Update the block around
context and the sendDebateMessage invocation so context is assigned the
constructed string (using debateData and state variables) before calling
sendDebateMessage to ensure the bot receives the intended context.
- Around line 510-519: Replace the hardcoded fetch URL with a configurable API
base (e.g., use an imported API_BASE_URL or a Vite/CRA env var like
process.env.REACT_APP_API_BASE_URL or import.meta.env.VITE_API_BASE_URL) and
build the translate endpoint from that in the code that calls fetch (the
translatedResponse fetch using botText and targetLang); also check
translatedResponse.ok before calling translatedResponse.json(), handle non-OK
responses (log error and fall back to English), and only assign
data.translatedText to botText when the response is OK and contains that field.
🧹 Nitpick comments (4)
backend/structs/websocket.go (1)

11-22: IsTranslated with omitempty may cause confusion.

The IsTranslated field (line 20) uses omitempty, which means false values are omitted from JSON output. The frontend may need to distinguish between "not translated" (false) and "translation status unknown" (field absent). Consider removing omitempty from this boolean field:

-IsTranslated   bool   `json:"isTranslated,omitempty"`
+IsTranslated   bool   `json:"isTranslated"`

Otherwise, the struct expansion is clean and properly supports the translation feature.

backend/cmd/server/main.go (1)

22-22: Non-idiomatic separate import statement.

The godotenv import on line 22 is outside the main import block (lines 3-19). Consolidate it with other imports:

 import (
 	"log"
 	"os"
 	"strconv"
 
 	"arguehub/config"
 	// ... other imports
 	"github.com/gin-gonic/gin"
+	"github.com/joho/godotenv"
 )
-
-import "github.com/joho/godotenv"
backend/websocket/websocket.go (1)

478-499: Synchronous translation may introduce latency in the WebSocket handler.

The translation call blocks the message processing loop. If the Gemini API is slow or times out, this could delay message delivery. Consider moving translation to a goroutine with a timeout and fallback to original content if translation takes too long.

Additionally, the current design translates to a single TargetLanguage and broadcasts to all recipients. In multi-user rooms (with spectators), different recipients may prefer different languages. This is acceptable for 2-person PvP debates but may need revisiting for spectator support.

♻️ Consider async translation with timeout
case "message":
    // Start translation asynchronously
    go func(msg Message, cl *Client) {
        ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
        defer cancel()
        
        if msg.SenderLanguage != "" && msg.TargetLanguage != "" &&
           !strings.EqualFold(msg.SenderLanguage, msg.TargetLanguage) {
            translated, err := services.TranslateContentWithContext(ctx, msg.Content, msg.SenderLanguage, msg.TargetLanguage)
            if err == nil {
                msg.OriginalText = msg.Content
                msg.Content = translated
                msg.IsTranslated = true
            }
        }
        handleChatMessage(room, conn, msg, cl, roomID)
    }(message, client)
backend/websocket/handler.go (1)

492-501: Busy-wait polling loop could be more efficient.

The loop polls every second waiting for a second participant. While functional, this is inefficient. Consider using a channel or sync.Cond to signal when the room is ready.

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b0bfbb2 and cabdbc0.

📒 Files selected for processing (9)
  • backend/cmd/server/main.go
  • backend/services/gemini.go
  • backend/services/translation.go
  • backend/structs/websocket.go
  • backend/websocket/handler.go
  • backend/websocket/translation_handler.go
  • backend/websocket/websocket.go
  • frontend/src/Pages/DebateRoom.tsx
  • frontend/src/components/Chatbox.tsx
🧰 Additional context used
🧬 Code graph analysis (6)
backend/structs/websocket.go (2)
backend/websocket/websocket.go (1)
  • Room (31-34)
backend/routes/rooms.go (1)
  • Room (21-26)
frontend/src/Pages/DebateRoom.tsx (3)
frontend/src/services/vsbot.ts (1)
  • sendDebateMessage (83-101)
backend/websocket/websocket.go (1)
  • Message (70-98)
backend/models/debatevsbot.go (1)
  • Message (6-10)
backend/websocket/translation_handler.go (2)
backend/cmd/server/main.go (3)
  • TranslationHandler (204-221)
  • TranslationRequest (195-198)
  • TranslationResponse (200-202)
backend/services/translation.go (1)
  • TranslateContent (10-45)
frontend/src/components/Chatbox.tsx (1)
backend/structs/websocket.go (1)
  • ChatMessage (48-51)
backend/websocket/websocket.go (1)
backend/services/translation.go (1)
  • TranslateContent (10-45)
backend/cmd/server/main.go (5)
backend/config/config.go (1)
  • LoadConfig (60-73)
backend/services/gemini.go (1)
  • InitGemini (17-30)
backend/services/debatevsbot.go (1)
  • InitDebateVsBotService (22-39)
backend/websocket/translation_handler.go (3)
  • TranslationHandler (21-42)
  • TranslationRequest (10-13)
  • TranslationResponse (16-19)
backend/services/translation.go (1)
  • TranslateContent (10-45)
🔇 Additional comments (5)
backend/services/gemini.go (2)

17-30: LGTM with minor observation.

The initialization logic is sound. The empty API key case is handled gracefully—if the key is empty, the client creation will likely fail and return an error, which is propagated correctly. The calling code in main.go already logs a warning on failure.


37-44: Safety settings disable all content filtering.

All harm categories are set to HarmBlockThresholdBlockNone. While this may be intentional to allow debate content, it also means potentially harmful content won't be filtered. Verify this aligns with your content policy.

frontend/src/components/Chatbox.tsx (1)

48-64: LGTM: Clean translation toggle component.

The MessageContent component elegantly handles the translated/original text toggle. The early return for non-translated messages (line 51) is efficient, and the toggle button provides good UX.

backend/websocket/websocket.go (2)

77-81: LGTM - Translation fields properly defined.

The new translation-related fields are well-structured with appropriate JSON tags and omitempty to avoid sending empty values.


530-558: LGTM - Clean broadcast logic with translation fields.

The function properly resets client state, sets a default timestamp, and includes all necessary translation metadata in the broadcast. The graceful handling of translation errors (falling back to original content) ensures chat reliability.

}

// Now os.Getenv("GEMINI_API_KEY") will work!
apiKey := os.Getenv("GEMINI_API_KEY")
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Unused variable apiKey.

apiKey is declared on line 31 but never used. It's redundantly redeclared as geminiKey on line 40. Remove the unused declaration:

-    // Now os.Getenv("GEMINI_API_KEY") will work!
-    apiKey := os.Getenv("GEMINI_API_KEY")

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In @backend/cmd/server/main.go at line 31, Remove the unused variable
declaration apiKey := os.Getenv("GEMINI_API_KEY") and ensure the code uses the
existing geminiKey variable instead (geminiKey := os.Getenv("GEMINI_API_KEY")),
so the environment value is only read once and no redundant/unused apiKey symbol
remains; update any references to use geminiKey if necessary.

Comment on lines 195 to 221
type TranslationRequest struct {
Text string `json:"text"`
TargetLang string `json:"target_lang"`
}

type TranslationResponse struct {
TranslatedText string `json:"translatedText"`
}

func TranslationHandler(c *gin.Context) {
var req TranslationRequest
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(400, gin.H{"error": "Invalid request"})
return
}

// This calls the TranslateContent function we created in services/gemini.go
translated, err := services.TranslateContent(req.Text, "en", req.TargetLang)
if err != nil {
c.JSON(500, gin.H{"error": "Translation failed"})
return
}

c.JSON(200, TranslationResponse{
TranslatedText: translated,
})
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major

Duplicate translation types and handler.

TranslationRequest, TranslationResponse, and TranslationHandler are duplicated in backend/websocket/translation_handler.go. This creates maintenance burden and risk of divergence. Consolidate to a single location:

  1. Keep types in a shared package (e.g., structs or dto)
  2. Keep handler in one place (either main.go or websocket/translation_handler.go)
  3. Import and use from the chosen location
🤖 Prompt for AI Agents
In @backend/cmd/server/main.go around lines 195 - 221, Create a single shared
DTO package (e.g., package dto) that defines TranslationRequest and
TranslationResponse, remove the duplicate type declarations from both places,
and update code to import dto and use
dto.TranslationRequest/dto.TranslationResponse; keep only one TranslationHandler
implementation (choose the existing websocket.TranslationHandler or
main.TranslationHandler), delete the duplicate handler, and wire your routes to
call the single exported TranslationHandler function from its package. Ensure
package imports and references to services.TranslateContent remain correct after
moving types.

"context"
"fmt"
"strings"
"github.com/debateai/DebateAI/backend/services/gemini"
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify the actual module path used in go.mod
echo "=== go.mod module declaration ==="
head -5 go.mod

echo -e "\n=== Import patterns in backend/services ==="
find backend/services -name "*.go" -type f -exec grep -l "^import" {} \; | head -10 | while read file; do
  echo "--- $file ---"
  grep -A 20 "^import" "$file" | head -25
done

Repository: AOSSIE-Org/DebateAI

Length of output: 5314


🏁 Script executed:

#!/bin/bash
# View translation.go to see the actual imports
echo "=== backend/services/translation.go ==="
head -30 backend/services/translation.go

echo -e "\n=== Search for github.com/debateai/DebateAI references ==="
rg "github\.com/debateai/DebateAI" --type go

echo -e "\n=== Check if go.mod exists in different locations ==="
find . -name "go.mod" -type f 2>/dev/null | head -5

Repository: AOSSIE-Org/DebateAI

Length of output: 1314


🏁 Script executed:

#!/bin/bash
# Check the module path in backend/go.mod
echo "=== backend/go.mod module declaration ==="
head -5 backend/go.mod

echo -e "\n=== Check what's exported from gemini.go ==="
grep -n "^var\|^const\|^func" backend/services/gemini.go | head -20

echo -e "\n=== Search for GeminiInstance reference ==="
rg "GeminiInstance" backend/

Repository: AOSSIE-Org/DebateAI

Length of output: 889


Import path and variable reference are incorrect.

The import path "github.com/debateai/DebateAI/backend/services/gemini" is inconsistent with the module declaration in backend/go.mod, which uses arguehub. All other service files in the codebase correctly use arguehub/... imports (e.g., arguehub/db, arguehub/models).

Additionally, the code references gemini.GeminiInstance, but gemini.go exports geminiClient (lowercase, unexported), not GeminiInstance. This will cause a compile-time error.

The import should be "arguehub/services/gemini", and the variable reference needs to be corrected to access the actual exported symbols from the gemini package.

🤖 Prompt for AI Agents
In @backend/services/translation.go at line 7, Replace the wrong import and
variable usage: change the import to "arguehub/services/gemini" (matching module
name) and update any uses of gemini.GeminiInstance to the actual exported symbol
from the gemini package (open backend/services/gemini/gemini.go to find the
exported constructor/type name — e.g., GeminiClient, NewGeminiClient, or similar
— and use that instead of the nonexistent GeminiInstance).

Comment on lines 21 to 42
func TranslationHandler(c *gin.Context) {
var req TranslationRequest

// 1. Bind the incoming JSON to our struct
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request payload"})
return
}

// 2. Call the Gemini translation service
// We assume source is "en" as the bot generates English by default
translated, err := services.TranslateContent(req.Text, "en", req.TargetLang)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Translation service failed"})
return
}

// 3. Return the result to the React app
c.JSON(http.StatusOK, TranslationResponse{
TranslatedText: translated,
})
} No newline at end of file
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Duplicate handler and hardcoded source language.

This handler duplicates TranslationHandler in main.go (lines 204-221). Only one should be kept to avoid confusion and ensure consistent behavior.

The source language is hardcoded to "en" (line 32). For PvP scenarios where users may write in different languages, consider accepting source_lang in the request:

♻️ Suggested change
 type TranslationRequest struct {
 	Text       string `json:"text"`
+	SourceLang string `json:"source_lang,omitempty"`
 	TargetLang string `json:"target_lang"`
 }

 func TranslationHandler(c *gin.Context) {
 	// ...
-	translated, err := services.TranslateContent(req.Text, "en", req.TargetLang)
+	sourceLang := req.SourceLang
+	if sourceLang == "" {
+		sourceLang = "en" // Default to English for bot responses
+	}
+	translated, err := services.TranslateContent(req.Text, sourceLang, req.TargetLang)

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In @backend/websocket/translation_handler.go around lines 21 - 42, There are two
problems: this TranslationHandler duplicates the one in main.go (remove the
duplicate and keep a single canonical TranslationHandler) and the source
language is hardcoded to "en"; modify the request payload struct to accept a
source_lang field (e.g., SourceLang) and use that value when calling
services.TranslateContent instead of the hardcoded "en" (fall back to a sensible
default if SourceLang is empty), and ensure only one TranslationHandler
implementation remains (update any imports/route registrations to point to the
retained handler).

Comment on lines 165 to 173
// 1. Get the languages.
// In a real app, these should come from your settings state or props.
// For now, we use "en" and "es" as placeholders.
const senderLang = "en";
const targetLang = "es";

if (isRecognizing) {
stopRecognition();
}
};
// 2. Pass the new arguments to onSendMessage
// This matches the update we need to make in your WebSocket handler
onSendMessage(inputText.trim(), inputMode, senderLang, targetLang);
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major

Hardcoded language placeholders need replacement.

The comment acknowledges that senderLang and targetLang are placeholders. These should be derived from user settings (similar to how DebateRoom.tsx uses user?.language). Consider passing these as props or accessing them from a shared user/settings context.

♻️ Suggested approach
+// Add to Chatbox props:
+userLanguage?: string;
+opponentLanguage?: string;

 const handleSendMessage = () => {
   if (!inputText.trim() || disabled || !isMyTurn) return;
 
-  const senderLang = "en"; 
-  const targetLang = "es";
+  const senderLang = userLanguage || "en"; 
+  const targetLang = opponentLanguage || "en";

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In @frontend/src/components/Chatbox.tsx around lines 165 - 173, Replace the
hardcoded senderLang and targetLang in Chatbox.tsx by deriving them from the
current user's settings or props rather than literals: get the language values
the same way as DebateRoom.tsx uses user?.language (or accept a language prop on
the Chatbox component), then pass those variables into the existing
onSendMessage call (onSendMessage(inputText.trim(), inputMode, senderLang,
targetLang)). Update the Chatbox props or hook to access the user/settings
context and remove the "en"/"es" literals so languages reflect the real user
settings.

@Kalpana-chavhan
Copy link
Author

Kalpana-chavhan commented Jan 8, 2026

Hello, @bhavik-mangla , @Zahnentferner, @varunchitre15, @saisankargochhayat, @heychirag.
The checks are passing, i request you the review the PR and let me know if there's changes to be made at my end.
waiting!
Thanks ;)

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.

🚀 Feature Request: Multilingual Live Debate with Real-Time Translation

1 participant