-
-
Couldn't load subscription status.
- Fork 13.9k
feat(chatinput): Add input translation to English feature #9807
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
- Add InputTranslate action component with language icon - Integrate with existing chainTranslate from @lobechat/prompts - Enable translation of input text to English before sending - Add action to Desktop (ClassicChat/GroupChat) and Mobile inputs - Position between typo and fileUpload actions as per UI reference - Add translateToEnglish locale string for button tooltip Closes #9164 🤖 Generated with [Claude Code](https://claude.ai/code) Co-authored-by: Arvin Xu <[email protected]>
Reviewer's GuideIntroduces an InputTranslate action that lets users translate their chat input to English before sending. A new useInputTranslate hook wraps the existing chainTranslate API and chatService calls with trace payloads, while a memoized InputTranslate component handles user interactions and loading states. The action is registered in the ActionBar config and injected into both desktop and mobile chat input bars between typo and file upload icons, and a Chinese locale string is added for the tooltip. Sequence diagram for input translation process in chat inputsequenceDiagram
actor User
participant InputTranslate
participant useInputTranslate
participant chatService
participant chainTranslate
participant Editor
User->>InputTranslate: Clicks translate button
InputTranslate->>Editor: Get current input content
InputTranslate->>useInputTranslate: Call translateToEnglish(content)
useInputTranslate->>chainTranslate: Prepare translation prompt
useInputTranslate->>chatService: fetchPresetTaskResult(params)
chatService-->>useInputTranslate: Returns translated text
useInputTranslate-->>InputTranslate: Return translated text
InputTranslate->>Editor: Set translated content
Class diagram for new InputTranslate component and useInputTranslate hookclassDiagram
class InputTranslate {
+editor: Editor
+isTranslating: boolean
+translateToEnglish(content: string): Promise<string>
+handleTranslate(): void
}
class useInputTranslate {
+translateToEnglish(content: string): Promise<string>
}
InputTranslate --> useInputTranslate: uses
InputTranslate --> Editor: uses
useInputTranslate --> chatService: uses
useInputTranslate --> chainTranslate: uses
File-Level Changes
Assessment against linked issues
Possibly linked issues
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
|
The latest updates on your projects. Learn more about Vercel for GitHub.
💡 Enable Vercel Agent with $100 free credit for automated AI reviews |
TestGru AssignmentSummary
Tip You can |
|
👍 @arvinxx Thank you for raising your pull request and contributing to our Community |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey there - I've reviewed your changes - here's some feedback:
- In useInputTranslate you’re wrapping chatService.fetchPresetTaskResult in a new Promise—consider converting it to async/await and returning the underlying promise directly to simplify the code.
- useInputTranslate pulls translation settings with useUserStore.getState(), so it won’t update if the user changes settings—consider subscribing to the store inside the hook instead.
- On translation failure you only log to console; consider surfacing an error or feedback in the UI so users know when translation doesn’t succeed.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- In useInputTranslate you’re wrapping chatService.fetchPresetTaskResult in a new Promise—consider converting it to async/await and returning the underlying promise directly to simplify the code.
- useInputTranslate pulls translation settings with useUserStore.getState(), so it won’t update if the user changes settings—consider subscribing to the store inside the hook instead.
- On translation failure you only log to console; consider surfacing an error or feedback in the UI so users know when translation doesn’t succeed.
## Individual Comments
### Comment 1
<location> `src/features/ChatInput/ActionBar/InputTranslate/index.tsx:21-26` </location>
<code_context>
+ setIsTranslating(true);
+ try {
+ const translatedContent = await translateToEnglish(content);
+ if (translatedContent && translatedContent !== content) {
+ editor.setDocument('markdown', translatedContent);
+ }
</code_context>
<issue_to_address>
**suggestion:** Check for translatedContent equality may not handle whitespace or formatting changes.
Normalize both strings before comparison to avoid false negatives due to formatting or whitespace differences.
```suggestion
// Helper to normalize whitespace and formatting
const normalize = (str: string) =>
str.replace(/\s+/g, ' ').trim();
setIsTranslating(true);
try {
const translatedContent = await translateToEnglish(content);
if (
translatedContent &&
normalize(translatedContent) !== normalize(content)
) {
editor.setDocument('markdown', translatedContent);
}
```
</issue_to_address>
### Comment 2
<location> `src/features/ChatInput/ActionBar/InputTranslate/index.tsx:28` </location>
<code_context>
+ editor.setDocument('markdown', translatedContent);
+ }
+ } catch (error) {
+ console.error('Translation failed:', error);
+ } finally {
+ setIsTranslating(false);
</code_context>
<issue_to_address>
**suggestion:** Logging errors to console may not be sufficient for user feedback.
Please add a user-facing notification or UI message when translation fails to ensure users are aware of the error.
Suggested implementation:
```typescript
setErrorMessage('');
setIsTranslating(true);
try {
const translatedContent = await translateToEnglish(content);
if (translatedContent && translatedContent !== content) {
editor.setDocument('markdown', translatedContent);
}
} catch (error) {
console.error('Translation failed:', error);
setErrorMessage('Translation failed. Please try again.');
} finally {
setIsTranslating(false);
}
};
```
```typescript
return (
<>
<Action
icon={LanguagesIcon}
loading={isTranslating}
onClick={handleTranslate}
title={t('input.translateToEnglish')}
/>
{errorMessage && (
<div style={{ color: 'red', marginTop: 8 }}>
{errorMessage}
</div>
)}
</>
```
```typescript
const [errorMessage, setErrorMessage] = React.useState('');
const content = editor.getDocument('markdown') as string;
if (!content?.trim()) return;
```
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
| setIsTranslating(true); | ||
| try { | ||
| const translatedContent = await translateToEnglish(content); | ||
| if (translatedContent && translatedContent !== content) { | ||
| editor.setDocument('markdown', translatedContent); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion: Check for translatedContent equality may not handle whitespace or formatting changes.
Normalize both strings before comparison to avoid false negatives due to formatting or whitespace differences.
| setIsTranslating(true); | |
| try { | |
| const translatedContent = await translateToEnglish(content); | |
| if (translatedContent && translatedContent !== content) { | |
| editor.setDocument('markdown', translatedContent); | |
| } | |
| // Helper to normalize whitespace and formatting | |
| const normalize = (str: string) => | |
| str.replace(/\s+/g, ' ').trim(); | |
| setIsTranslating(true); | |
| try { | |
| const translatedContent = await translateToEnglish(content); | |
| if ( | |
| translatedContent && | |
| normalize(translatedContent) !== normalize(content) | |
| ) { | |
| editor.setDocument('markdown', translatedContent); | |
| } |
| editor.setDocument('markdown', translatedContent); | ||
| } | ||
| } catch (error) { | ||
| console.error('Translation failed:', error); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion: Logging errors to console may not be sufficient for user feedback.
Please add a user-facing notification or UI message when translation fails to ensure users are aware of the error.
Suggested implementation:
setErrorMessage('');
setIsTranslating(true);
try {
const translatedContent = await translateToEnglish(content);
if (translatedContent && translatedContent !== content) {
editor.setDocument('markdown', translatedContent);
}
} catch (error) {
console.error('Translation failed:', error);
setErrorMessage('Translation failed. Please try again.');
} finally {
setIsTranslating(false);
}
}; return (
<>
<Action
icon={LanguagesIcon}
loading={isTranslating}
onClick={handleTranslate}
title={t('input.translateToEnglish')}
/>
{errorMessage && (
<div style={{ color: 'red', marginTop: 8 }}>
{errorMessage}
</div>
)}
</> const [errorMessage, setErrorMessage] = React.useState('');
const content = editor.getDocument('markdown') as string;
if (!content?.trim()) return;
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #9807 +/- ##
==========================================
+ Coverage 78.98% 82.37% +3.38%
==========================================
Files 780 999 +219
Lines 48617 66982 +18365
Branches 6729 10923 +4194
==========================================
+ Hits 38401 55175 +16774
- Misses 10216 11807 +1591
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Codex Review
Here are some automated review suggestions for this pull request.
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| chatService | ||
| .fetchPresetTaskResult({ | ||
| onFinish: (result) => { | ||
| if (result && typeof result === 'string') { | ||
| resolve(result); | ||
| } else { | ||
| resolve(translatedContent); | ||
| } | ||
| }, | ||
| onMessageHandle: (chunk) => { | ||
| if (chunk.type === 'text') { | ||
| translatedContent += chunk.text; | ||
| } | ||
| }, | ||
| params: merge(translationSetting, chainTranslate(content, 'en-US')), | ||
| trace: getCurrentTracePayload({ traceName: TraceNameMap.Translator }), | ||
| }) | ||
| .catch((error) => { | ||
| reject(error); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reject translation promise on failure
The hook wraps chatService.fetchPresetTaskResult in a new promise that only resolves inside onFinish and rejects via .catch. However fetchPresetTaskResult swallows errors and invokes onError without rejecting, so when the translation call fails (e.g. network/provider error) onFinish is never triggered and the wrapper promise never settles. Because InputTranslate awaits this promise to toggle isTranslating, a failed request leaves the action permanently stuck in the loading state. Provide an onError handler that calls reject (or resolve to a fallback) so the UI can recover after errors.
Useful? React with 👍 / 👎.
Add InputTranslate action component that allows users to translate their input text to English before sending for better LLM responses.
Changes
Closes #9164
🤖 Generated with Claude Code
Summary by Sourcery
Add a new input translation feature that enables users to translate their message content to English via the chat input toolbar before sending.
New Features: