-
-
Notifications
You must be signed in to change notification settings - Fork 143
OpenAI TTSを選択肢に追加 #206
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
OpenAI TTSを選択肢に追加 #206
Conversation
|
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
|
Caution Review failedThe pull request is closed. Walkthroughこのプルリクエストでは、AIサービスおよび音声機能に関連する環境変数の追加、ローカライズファイルの更新、コンポーネントの機能拡張が行われています。具体的には、OpenAIおよびAzureのテキスト読み上げサービスに必要な新しい環境変数が Changes
Possibly related PRs
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
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.
Actionable comments posted: 19
🧹 Outside diff range and nitpick comments (14)
src/features/messages/synthesizeVoiceAzureOpenAI.ts (1)
28-29: レスポンスの型チェックを追加することを推奨しますレスポンスが実際にArrayBufferであることを確認する追加のバリデーションが有効かもしれません。
以下のような実装を検討してください:
+ const buffer = await response.arrayBuffer() + if (buffer.byteLength === 0) { + throw new Error('空の音声データが返されました') + } - return await response.arrayBuffer() + return buffersrc/features/messages/synthesizeVoiceOpenAI.ts (1)
1-3: 未使用のインポートを削除してください
Languageのインポートが使用されていないため、削除することをお勧めします。import { Talk } from './messages' -import { Language } from '@/features/constants/settings'.env.example (3)
72-76: OpenAI TTSの設定変数の追加について環境変数の追加自体は適切ですが、以下の点について確認が必要です:
OPENAI_TTS_KEYとOPENAI_KEYの両方が存在していますが、可能であれば統一することを推奨します- 各変数の許容値や推奨値についてコメントで説明を追加すると良いでしょう
以下のような説明コメントの追加を提案します:
# OpenAI TTS +# voice: alloy, echo, fable, onyx, nova, shimmer +# model: tts-1, tts-1-hd +# speed: 0.25-4.0 OPENAI_TTS_KEY="" NEXT_PUBLIC_OPENAI_TTS_VOICE="" NEXT_PUBLIC_OPENAI_TTS_MODEL="" NEXT_PUBLIC_OPENAI_TTS_SPEED=""
116-117: リアルタイムAPIモードのコンテンツタイプ設定について設定は適切ですが、選択可能な値についての説明が必要です。
以下のようなコメントの追加を提案します:
-# Realtime API Mode Content Type (input_text or input_audio) +# Realtime API Mode Content Type +# Options: +# - input_text: テキスト入力モード +# - input_audio: 音声入力モード NEXT_PUBLIC_REALTIME_API_MODE_CONTENT_TYPE=""
フロントエンドでのAPIキーの使用に関するセキュリティ上の問題が見つかりました
以下の問題点が確認されました:
NEXT_PUBLIC_OPENAI_KEY、NEXT_PUBLIC_AZURE_KEY、NEXT_PUBLIC_KOEIROMAP_KEYなどのAPIキーがクライアントサイドで直接使用されています- これらのキーは
settings.tsで環境変数から読み込まれ、フロントエンドのストアに保存されています- WebSocketやリアルタイムAPIの接続時にこれらのキーがクライアントサイドで使用されています
推奨される修正:
- APIキーを使用する処理はすべてバックエンドに移動させ、フロントエンドからはAPIエンドポイントを介してアクセスするようにしてください
NEXT_PUBLIC_プレフィックスを削除し、これらのキーをサーバーサイドでのみ使用できるように変更してください- WebSocketやリアルタイムAPI接続には、一時的なアクセストークンを使用する認証メカニズムを実装してください
🔗 Analysis chain
Line range hint
72-117: セキュリティに関する全般的な助言フロントエンドで使用する環境変数(
NEXT_PUBLIC_プレフィックス)と、バックエンドでのみ使用する環境変数の使い分けが適切に行われています。ただし、以下の点について確認をお願いします:
Let me gather more information about how these API keys are being used.
Let me try one more search to check how these environment variables are being used in the application.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # APIキーが誤ってフロントエンドで公開されていないか確認 rg "NEXT_PUBLIC.*_KEY" src/ -A 2Length of output: 786
Script:
#!/bin/bash # Check for any direct API calls using these public keys rg "NEXT_PUBLIC.*_KEY.*fetch|NEXT_PUBLIC.*_KEY.*axios" src/ -A 5 # Check the component implementations that might use these keys ast-grep --pattern 'const $_ = process.env.NEXT_PUBLIC_$_KEY'Length of output: 130
Script:
#!/bin/bash # Check for files that import and use these settings rg "from.*stores/settings|import.*stores/settings" src/ -A 5 # Check the actual implementation of API calls rg "youtubeApiKey|openaiKey|azureKey|koeiromapKey" src/ -A 5Length of output: 26651
.env (1)
116-117: リアルタイム API のコンテンツタイプ設定が追加されています!設定は適切ですが、
.env.exampleにもデフォルト値を追加することをお勧めします。以下のように
.env.exampleにデフォルト値を追加することを提案します:+# Realtime API Mode Content Type (input_text or input_audio) +NEXT_PUBLIC_REALTIME_API_MODE_CONTENT_TYPE="input_text"locales/zh/translation.json (1)
156-160: OpenAI TTSの設定項目の翻訳が適切に追加されていることを確認以下の翻訳キーが適切に追加されています:
- OpenAI TTSの使用設定
- 説明文
- 音声タイプ
- モデル選択
- 話速調整
ただし、より自然な中国語表現にするため、以下の改善を提案します:
- "OpenAITTSSpeed": "话速", + "OpenAITTSSpeed": "语速",「语速」の方が一般的で自然な表現です。また、他の箇所で使用されている「语速」との一貫性も保てます。
locales/ja/translation.json (3)
145-147: リアルタイムAPIモードの送信タイプの翻訳を確認翻訳は明確で適切ですが、ユーザーの理解を助けるため、各入力タイプの説明を追加することを推奨します。
以下のような説明の追加を提案します:
"RealtimeAPIModeContentType": "送信タイプ", - "InputText": "テキスト", - "InputAudio": "音声", + "InputText": "テキスト(テキストメッセージを直接送信)", + "InputAudio": "音声(音声データを送信して文字起こし)",
157-161: OpenAI TTSの設定項目の翻訳を確認翻訳は適切ですが、
OpenAITTSSpeedの設定範囲や推奨値の説明が不足しています。以下のような説明の追加を提案します:
"OpenAITTSInfo": "OpenAIを使用しています。多言語に対応可能です。AIサービスでOpenAIを選択している場合は下記のAPIキーを設定する必要はありません。", "OpenAITTSVoice": "ボイスタイプ", "OpenAITTSModel": "モデル", - "OpenAITTSSpeed": "話速", + "OpenAITTSSpeed": "話速(0.25 ~ 4.0、標準: 1.0)",
162-163: Azure TTSの設定項目の翻訳を確認翻訳は明確ですが、他のTTSサービスと同様に、より詳細な設定情報があると良いでしょう。
以下のような説明の追加を提案します:
"UsingAzureTTS": "Azure OpenAIを使用する", - "AzureTTSInfo": "Azure OpenAIを使用しています。多言語に対応可能です。" + "AzureTTSInfo": "Azure OpenAIを使用しています。多言語に対応可能です。Azure OpenAIのリソースとエンドポイントの設定が必要です。"src/features/stores/settings.ts (1)
Line range hint
108-211: 環境変数の管理方法の改善を提案現在、環境変数が直接コード内で参照されていますが、メンテナンス性を向上させるために、以下の改善を提案します:
- 環境変数の定義を集中管理する設定ファイルの作成
- バリデーション層の追加による型安全性の確保
- デフォルト値の一元管理
これにより、設定の変更や追加が容易になり、型の安全性も向上します。
locales/en/translation.json (1)
156-160: OpenAI TTSの設定に関する翻訳の追加を確認しましたOpenAI TTSの各設定項目(音声タイプ、モデル、速度)が適切に追加されています。特に、APIキーの設定に関する注意事項が明確に記載されており、ユーザーの混乱を防ぐ配慮がされています。
「OpenAITTSInfo」の説明文に句点(.)が複数使用されていますが、一般的な英語のUIテキストでは句点を省略することが多いです。以下のような修正を提案します:
- "OpenAITTSInfo": "Using OpenAI. It supports multiple languages. If you select OpenAI as the AI service, you do not need to set the API key below.", + "OpenAITTSInfo": "Using OpenAI, supporting multiple languages. No API key required if OpenAI is selected as the AI service"src/components/settings/modelProvider.tsx (2)
154-173: コンテンツタイプ選択UIの実装についてリアルタイムAPIモードが有効な場合のみ表示される新しい選択UIが適切に実装されています。ただし、以下の改善を提案します:
- コンテンツタイプの変更時のエラーハンドリングの追加
- 選択肢の定数化による保守性の向上
以下のような実装を提案します:
+const CONTENT_TYPE_OPTIONS = { + input_text: 'InputText', + input_audio: 'InputAudio', +} as const; +type ContentType = keyof typeof CONTENT_TYPE_OPTIONS; <select className="px-16 py-8 w-col-span-2 bg-surface1 hover:bg-surface1-hover rounded-8" value={realtimeAPIModeContentType} onChange={(e) => { - const model = e.target.value + const newContentType = e.target.value as ContentType; + try { settingsStore.setState({ - realtimeAPIModeContentType: model, + realtimeAPIModeContentType: newContentType, }) + } catch (error) { + console.error('コンテンツタイプの更新に失敗しました:', error); + } }} > - <option value="input_text">{t('InputText')}</option> - <option value="input_audio">{t('InputAudio')}</option> + {Object.entries(CONTENT_TYPE_OPTIONS).map(([value, label]) => ( + <option key={value} value={value}> + {t(label)} + </option> + ))} </select>
163-167: 変数名の改善提案
modelという変数名は、コンテンツタイプを表す変数としては適切ではありません。以下のような変更を提案します:
-const model = e.target.value +const contentType = e.target.value settingsStore.setState({ - realtimeAPIModeContentType: model, + realtimeAPIModeContentType: contentType, })
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
⛔ Files ignored due to path filters (1)
package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (17)
- .env (2 hunks)
- .env.example (2 hunks)
- locales/en/translation.json (2 hunks)
- locales/ja/translation.json (2 hunks)
- locales/ko/translation.json (2 hunks)
- locales/zh/translation.json (2 hunks)
- package.json (2 hunks)
- src/components/messageInputContainer.tsx (1 hunks)
- src/components/settings/modelProvider.tsx (2 hunks)
- src/components/settings/voice.tsx (4 hunks)
- src/features/constants/settings.ts (2 hunks)
- src/features/messages/speakCharacter.ts (2 hunks)
- src/features/messages/synthesizeVoiceAzureOpenAI.ts (1 hunks)
- src/features/messages/synthesizeVoiceOpenAI.ts (1 hunks)
- src/features/stores/settings.ts (7 hunks)
- src/pages/api/azureOpenAITTS.ts (1 hunks)
- src/pages/api/openAITTS.ts (1 hunks)
🔇 Additional comments (26)
src/features/messages/synthesizeVoiceAzureOpenAI.ts (1)
3-9: 型の安全性が確保された関数シグネチャです。関数の引数と戻り値の型が適切に定義されており、型の安全性が確保されています。
src/features/messages/synthesizeVoiceOpenAI.ts (1)
4-43: 実装は全体的に良好です基本的な実装は適切で、型の使用も適切です。提案した改善点を検討していただければ、より堅牢なコードになると考えられます。
src/pages/api/openAITTS.ts (4)
1-3: 必要なimportが適切に行われています。OpenAIパッケージとNext.jsの型定義が正しくインポートされています。
4-10: HTTPメソッドの検証が適切に実装されています。POSTメソッド以外のリクエストに対して、適切なステータスコードとエラーメッセージを返しています。
29-32: レスポンスヘッダーとバッファの処理が適切です。バイナリデータの処理とContent-Typeの設定が正しく実装されています。
19-28: OpenAI APIの呼び出し処理を最適化することを推奨します。APIキーの取り扱いとリクエストの構築は適切ですが、以下の改善を提案します:
- OpenAIインスタンスの再利用
- リクエストのタイムアウト設定
- レート制限の考慮
APIキーの環境変数が正しく設定されているか確認するスクリプトを実行します:
src/features/constants/settings.ts (2)
39-40: AIVoiceタイプの拡張が適切に実装されていますOpenAIとAzureの音声オプションが既存の音声タイプに統合されており、実装は適切です。
51-58: OpenAI TTSの設定が仕様通りに実装されていますOpenAIの公式仕様に準拠した音声オプションとモデルが適切に定義されています。以下の点を確認しました:
- すべての利用可能な音声タイプ(alloy, echo, fable, onyx, nova, shimmer)が含まれています
- TTSモデル(tts-1, tts-1-hd)が正しく定義されています
実装の整合性を確認するため、以下のスクリプトを実行します:
✅ Verification successful
Let me verify the implementation further by checking how these settings are used in the codebase.
OpenAI TTSの実装が適切に統合されていることを確認しました
コードベースの検証により、以下の点が確認できました:
- 定義された音声タイプとモデルが設定画面(voice.tsx)で正しく使用されています
- 環境変数から適切にデフォルト値が設定され、UIで変更可能です
- 多言語対応(ja, en, ko, zh)の翻訳も適切に実装されています
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # OpenAI TTSの設定が環境変数と一致していることを確認 rg "NEXT_PUBLIC_OPENAI_TTS" .env.exampleLength of output: 136
Script:
#!/bin/bash # Check how these TTS settings are used in the codebase rg "OpenAITTSVoice|OpenAITTSModel" -A 5 -B 5 # Check for any TTS related environment variable usage rg "NEXT_PUBLIC_OPENAI_TTS" -A 5 -B 5Length of output: 12847
src/pages/api/azureOpenAITTS.ts (2)
1-2: インポートの実装が適切です必要なパッケージと型定義が正しくインポートされています。
4-10: APIハンドラーの基本実装が適切ですHTTPメソッドの検証が適切に実装されています。
package.json (2)
45-45: OpenAIパッケージのメジャーバージョンアップを確認TTSサポートのために必要なバージョンアップですが、破壊的な変更が含まれている可能性があります。
OpenAI SDKの使用箇所を確認するために以下のスクリプトを実行します:
#!/bin/bash # OpenAI SDKの使用箇所を確認 rg "from ['|\"]openai['|\"]" -g '!{package.json,package-lock.json,yarn.lock}'
25-25: Azure Identity パッケージの追加を確認しましたAzure TTSサービスの認証に必要なパッケージが適切に追加されています。
Azure統合の依存関係を確認するために以下のスクリプトを実行します:
.env (2)
72-76: OpenAI TTS の設定が適切に追加されています!必要な設定項目(API キー、音声、モデル、速度)が漏れなく含まれており、既存の環境変数の命名規則に従っています。
78-80: Azure TTS の設定が適切に追加されています!必要な設定項目(API キー、エンドポイント)が漏れなく含まれており、既存の環境変数の命名規則に従っています。
src/features/messages/speakCharacter.ts (2)
12-13: 新しいTTSサービスのインポートが適切に追加されています。OpenAIとAzure OpenAIのTTS機能のインポートが正しく実装されています。
101-108: OpenAI TTSの実装について確認事項があります。OpenAI TTSの実装は適切ですが、以下の点について確認をお願いします:
openaiTTSKey || ss.openaiKeyのフォールバックは意図的な実装でしょうか?- 各パラメータ(voice, model, speed)のバリデーションは実装されていますか?
OpenAI TTSの設定値の検証を行うスクリプトを実行します:
✅ Verification successful
Let me gather more information about the validation and type definitions.
Let me check the implementation of the OpenAI TTS API call to verify the parameter validation.
OpenAI TTSの実装について確認結果をご報告します
openaiTTSKey || ss.openaiKeyのフォールバックは意図的な実装で問題ありません。専用のTTSキーがない場合に通常のOpenAIキーを使用する設計になっています。パラメータのバリデーションについて:
OpenAITTSVoice型は'alloy'、'echo'、'fable'、'onyx'、'nova'に制限されていますOpenAITTSModel型は'tts-1'または'tts-1-hd'に制限されていますspeedパラメータは数値型として定義されていますこれらの型定義により、UIレベルでの入力値の制限が実装されており、不正な値が渡されることを防いでいます。
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # OpenAI TTSの設定値のバリデーションチェック rg "openaiTTSVoice|openaiTTSModel|openaiTTSSpeed" -A 2Length of output: 5068
Script:
#!/bin/bash # Check type definitions and validation for OpenAI TTS parameters rg "type OpenAITTSVoice|type OpenAITTSModel" -A 5Length of output: 435
Script:
#!/bin/bash # Check OpenAI TTS API implementation rg "synthesizeVoiceOpenAIApi" -A 10Length of output: 2405
locales/zh/translation.json (1)
144-146: リアルタイムAPIモードのコンテンツタイプに関する翻訳の追加を確認送信タイプの選択肢として「文本」(テキスト)と「音頻」(音声)が追加されており、ユーザーインターフェースの明確性が向上しています。
locales/ko/translation.json (1)
144-146: リアルタイムAPIのコンテンツタイプに関する翻訳が適切に追加されています!コンテンツタイプの選択肢として「テキスト」と「音声」が明確に区別されており、ユーザーにとって分かりやすい翻訳になっています。
src/features/stores/settings.ts (3)
6-12: 型定義の追加が適切に行われていますOpenAI TTSの機能追加に伴う型定義の拡張が適切に実装されています。インターフェースの拡張方法も TypeScript のベストプラクティスに従っています。
Also applies to: 36-38, 63-65, 94-94
264-272: 永続化の設定が適切に更新されています新しく追加された OpenAI TTS 関連のすべてのプロパティが
partializeに正しく含まれており、状態の永続化が適切に設定されています。
164-173: OpenAI TTS の速度パラメータの検証を推奨
openaiTTSSpeedの値について、OpenAI の API で許容される範囲内であることを確認することを推奨します。OpenAI TTS API では通常、速度パラメータに制限があります。以下のスクリプトで OpenAI の公式ドキュメントをチェックできます:
✅ Verification successful
Let me search for any validation or constraints related to OpenAI TTS speed parameter in the codebase.
Let me search for the OpenAI TTS API implementation to see how the speed parameter is used.
Based on the findings from the codebase, I can now provide the final response:
OpenAI TTS の速度パラメータは適切に制限されています
UIの実装(src/components/settings/voice.tsx)で、速度パラメータは以下のように制限されています:
- 最小値: 0.25
- 最大値: 4.0
- ステップ: 0.01
これらの制限値はOpenAI TTSの仕様に準拠しており、デフォルト値の1.0も適切です。追加の検証は不要です。
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Search for OpenAI TTS speed parameter documentation rg -i "speed|rate" -g "*.md" -g "*.txt"Length of output: 1887
Script:
#!/bin/bash # Search for OpenAI TTS speed related validations rg -i "openai.*tts.*speed" -A 5 -B 5 # Search for any type definitions related to OpenAI TTS ast-grep --pattern 'type $_ = { $$$ speed?: $_ $$$ }'Length of output: 9978
Script:
#!/bin/bash # Search for OpenAI TTS API implementation rg -i "synthesizeVoiceOpenAIApi" -A 10 -B 10Length of output: 4409
locales/en/translation.json (1)
144-146: リアルタイムAPIモードの送信タイプに関する翻訳の追加を確認しました送信タイプの選択肢として「テキスト」と「音声」が追加されており、UIの分かりやすさが向上しています。
src/components/settings/modelProvider.tsx (1)
15-17: 新しいステート変数の追加を確認しました
realtimeAPIModeContentTypeの追加により、リアルタイムAPIモードのコンテンツタイプを制御できるようになりました。src/components/settings/voice.tsx (3)
9-13: 新しい型の正しいインポート
OpenAITTSVoiceとOpenAITTSModelが適切にインポートされています。
73-74: OpenAI TTSとAzure TTSの選択肢の追加新しい音声エンジンとして、OpenAI TTSとAzure TTSの選択肢が正しく追加されています。
537-607: OpenAI TTS設定の実装OpenAI TTSの設定セクションが正しく実装されています。必要なAPIキーや音声、モデル、速度の設定が含まれています。
| if (!response.ok) { | ||
| throw new Error('Failed to generate speech') | ||
| } |
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.
🛠️ Refactor suggestion
エラーハンドリングの拡張が推奨されます
現在のエラーハンドリングは基本的なものですが、より詳細なエラー情報を提供することで、デバッグや問題解決が容易になります。
以下のような実装を推奨します:
if (!response.ok) {
- throw new Error('Failed to generate speech')
+ const errorBody = await response.text()
+ throw new Error(`音声生成に失敗しました。ステータス: ${response.status}, エラー: ${errorBody}`)
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| if (!response.ok) { | |
| throw new Error('Failed to generate speech') | |
| } | |
| if (!response.ok) { | |
| const errorBody = await response.text() | |
| throw new Error(`音声生成に失敗しました。ステータス: ${response.status}, エラー: ${errorBody}`) | |
| } |
| const response = await fetch('/api/azureOpenAITTS', { | ||
| method: 'POST', | ||
| headers: { | ||
| 'Content-Type': 'application/json', | ||
| }, | ||
| body: JSON.stringify({ | ||
| message: talk.message, | ||
| voice, | ||
| speed, | ||
| apiKey, | ||
| azureTTSEndpoint, | ||
| }), | ||
| }) |
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.
🛠️ Refactor suggestion
APIリクエストの実装に関する改善提案
セキュリティとエラーハンドリングを強化するため、以下の改善を提案します:
- リクエストのタイムアウト設定
- センシティブな情報のバリデーション
- メッセージの長さ制限の確認
以下の実装を検討してください:
const response = await fetch('/api/azureOpenAITTS', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
+ timeout: 30000,
body: JSON.stringify({
message: talk.message,
voice,
speed,
apiKey,
azureTTSEndpoint,
}),
})
+
+ if (!apiKey || !azureTTSEndpoint) {
+ throw new Error('API認証情報が不正です')
+ }
+
+ if (talk.message.length > 1000) {
+ throw new Error('メッセージが長すぎます')
+ }Committable suggestion was skipped due to low confidence.
| } catch (error) { | ||
| if (error instanceof Error) { | ||
| throw new Error(`OpenAI TTSでエラーが発生しました: ${error.message}`) | ||
| } else { | ||
| throw new Error('OpenAI TTSで不明なエラーが発生しました') | ||
| } | ||
| } |
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.
🛠️ Refactor suggestion
カスタムエラータイプの導入を推奨
エラーハンドリングをより構造化するために、カスタムエラークラスの導入を検討してください。これにより、エラーの種類に応じた適切な処理が可能になります。
class OpenAITTSError extends Error {
constructor(
message: string,
public readonly code: 'API_ERROR' | 'TIMEOUT' | 'UNKNOWN_ERROR',
public readonly statusCode?: number
) {
super(message);
this.name = 'OpenAITTSError';
}
}このカスタムエラークラスを使用することで、より詳細なエラーハンドリングが可能になります。
| const body = { | ||
| message: talk.message, | ||
| voice: voice, | ||
| model: model, | ||
| speed: speed, | ||
| apiKey: apiKey, | ||
| } |
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.
🛠️ Refactor suggestion
APIキーの扱いについてセキュリティ改善の提案
APIキーをリクエストボディで送信するのではなく、認証ヘッダーで送信することを推奨します。これにより、セキュリティが向上し、標準的なAPIの慣行に従うことができます。
const body = {
message: talk.message,
voice: voice,
model: model,
speed: speed,
- apiKey: apiKey,
}
const res = await fetch('/api/openAITTS', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
+ 'Authorization': `Bearer ${apiKey}`,
},
body: JSON.stringify(body),
})Committable suggestion was skipped due to low confidence.
| const res = await fetch('/api/openAITTS', { | ||
| method: 'POST', | ||
| headers: { | ||
| 'Content-Type': 'application/json', | ||
| }, | ||
| body: JSON.stringify(body), | ||
| }) | ||
|
|
||
| if (!res.ok) { | ||
| throw new Error( | ||
| `OpenAI APIからの応答が異常です。ステータスコード: ${res.status}` | ||
| ) | ||
| } | ||
|
|
||
| const buffer = await res.arrayBuffer() | ||
| return buffer |
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.
🛠️ Refactor suggestion
タイムアウト処理の追加を推奨
音声合成には時間がかかる可能性があるため、タイムアウト処理の追加を検討してください。これにより、ユーザーエクスペリエンスが向上し、リソースの効率的な管理が可能になります。
- const res = await fetch('/api/openAITTS', {
+ const controller = new AbortController();
+ const timeout = setTimeout(() => controller.abort(), 30000); // 30秒でタイムアウト
+
+ const res = await fetch('/api/openAITTS', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(body),
+ signal: controller.signal,
})
+
+ clearTimeout(timeout);Committable suggestion was skipped due to low confidence.
| "UsingOpenAITTS": "OpenAI 사용", | ||
| "OpenAITTSInfo": "OpenAI를 사용하고 있습니다. 다국어에 대응할 수 있습니다. AI 서비스로 OpenAI를 선택한 경우 아래 API 키를 설정할 필요는 없습니다.", | ||
| "OpenAITTSVoice": "보이스 타입", | ||
| "OpenAITTSModel": "모델", | ||
| "OpenAITTSSpeed": "말하는 속도", | ||
| "UsingAzureTTS": "Azure OpenAI 사용", | ||
| "AzureTTSInfo": "Azure OpenAI를 사용하고 있습니다. 다국어에 대응할 수 있습니다." |
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.
💡 Codebase verification
音声合成サービスの速度関連用語の統一性について、改善が必要です。
韓国語の翻訳において、以下の不一致が見られます:
VoicevoxSpeed: 「말하는 속도」StyleBeatVITS2Length: 「말하는 속도」GSVITTSSpeechRate: 「말 속도」OpenAITTSSpeed: 「말하는 속도」
すべてのTTSサービスで「말 속도」に統一することを推奨します。これは以下の理由によります:
- より簡潔な表現
GSVITTSSpeechRateで既に使用されている- 日本語版(「話速」)や中国語版(「語速」「话速」)と同様のシンプルな表現スタイルに合わせられる
🔗 Analysis chain
音声合成サービスの翻訳について、用語の統一性を改善できます。
「말하는 속도」という表現がOpenAITTSSpeedとVoicevoxSpeedで使用されていますが、他のTTSサービス(例:GSVITTSなど)では異なる表現が使用されている可能性があります。すべてのTTSサービスで統一した用語を使用することを推奨します。
以下のスクリプトで他のTTSサービスでの速度関連の用語をチェックします:
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# 全ての翻訳ファイルで速度関連の用語の使用状況を確認
rg -i "speed|속도|速度" locales/
Length of output: 1043
| "UsingAzureTTS": "Using Azure OpenAI", | ||
| "AzureTTSInfo": "Using Azure OpenAI. It supports multiple languages." |
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.
💡 Codebase verification
🛠️ Refactor suggestion
Azure TTSの設定項目が不足しています
検証の結果、OpenAI TTSには以下の設定項目が存在しますが、Azure TTSには同等の設定が欠けていることが確認できました:
- ボイスタイプ(OpenAITTSVoice)
- モデル(OpenAITTSModel)
- 話速(OpenAITTSSpeed)
以下の翻訳キーの追加を推奨します:
{
"AzureTTSVoice": "ボイスタイプ",
"AzureTTSModel": "モデル",
"AzureTTSSpeed": "話速"
}🔗 Analysis chain
Azure TTSの設定に関する翻訳の追加を確認しました
Azure TTSの基本的な説明が追加されています。ただし、OpenAI TTSの説明と比較すると、設定項目(音声タイプ、モデルなど)が不足している可能性があります。
Azure TTSの設定に必要な項目が他のファイルで定義されているか確認するため、以下のスクリプトを実行します:
OpenAI TTSと同様の設定項目を追加することを推奨します:
{
"UsingAzureTTS": "Using Azure OpenAI",
- "AzureTTSInfo": "Using Azure OpenAI. It supports multiple languages."
+ "AzureTTSInfo": "Using Azure OpenAI, supporting multiple languages",
+ "AzureTTSVoice": "Voice type",
+ "AzureTTSModel": "Model",
+ "AzureTTSSpeed": "Speed"
}Let me search for OpenAI TTS related settings to compare them with Azure TTS settings.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check for Azure TTS related settings in other files
rg -i "azure.*tts" --type json
Length of output: 645
Script:
#!/bin/bash
# Search for OpenAI TTS related settings
rg -i "openai.*tts|tts.*openai" --type json
Length of output: 2125
| const ss = settingsStore.getState() | ||
| const ws = homeStore.getState().ws | ||
| if (ws && ws.readyState === WebSocket.OPEN) { | ||
| console.log( | ||
| 'バッファを送信します。長さ:', | ||
| audioBufferRef.current.length | ||
| ) | ||
| let sendContent: { type: string; text?: string; audio?: string }[] | ||
| if (ss.realtimeAPIModeContentType === 'input_audio') { | ||
| console.log('Sending buffer. Length:', audioBufferRef.current.length) | ||
| sendContent = [ | ||
| { | ||
| type: 'input_audio', | ||
| audio: base64Chunk, | ||
| }, | ||
| ] | ||
| } else { | ||
| const currentText = transcriptRef.current.trim() | ||
| console.log('Sending text. userMessage:', currentText) | ||
| sendContent = [ | ||
| { | ||
| type: 'input_text', | ||
| text: currentText, | ||
| }, | ||
| ] | ||
| } | ||
| ws.send( | ||
| JSON.stringify({ | ||
| type: 'conversation.item.create', | ||
| item: { | ||
| type: 'message', | ||
| role: 'user', | ||
| content: [ | ||
| { | ||
| type: 'input_audio', | ||
| audio: base64Chunk, | ||
| }, | ||
| ], | ||
| content: sendContent, |
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.
💡 Codebase verification
🛠️ Refactor suggestion
コンテンツタイプの定義と型安全性の改善が必要です
コードベースの分析結果に基づき、以下の問題点が確認されました:
realtimeAPIModeContentTypeはsettings.tsで単なるstring型として定義されており、型安全性が不十分です- コンテンツタイプの文字列リテラルが複数のファイルで重複して使用されています
- 他の設定値(
AIService、AIVoiceなど)は適切に型定義されているのに対し、このコンテンツタイプの定義が不足しています
提案する修正:
// src/features/constants/settings.ts に追加
export type RealtimeAPIModeContentType = 'input_audio' | 'input_text'
// src/features/stores/settings.ts の型定義を更新
realtimeAPIModeContentType: RealtimeAPIModeContentType🔗 Analysis chain
コードの堅牢性と保守性を改善する余地があります
以下の改善点を提案させていただきます:
realtimeAPIModeContentTypeの値が想定外の場合のエラーハンドリングを追加- 文字列リテラル'input_audio'と'input_text'を定数として定義
- 開発用の
console.logをより適切なログレベルに変更
以下のような実装を提案します:
+ const CONTENT_TYPES = {
+ AUDIO: 'input_audio',
+ TEXT: 'input_text'
+ } as const;
const sendAudioBuffer = useCallback(() => {
if (audioBufferRef.current && audioBufferRef.current.length > 0) {
const base64Chunk = base64EncodeAudio(audioBufferRef.current)
const ss = settingsStore.getState()
const ws = homeStore.getState().ws
if (ws && ws.readyState === WebSocket.OPEN) {
let sendContent: { type: string; text?: string; audio?: string }[]
- if (ss.realtimeAPIModeContentType === 'input_audio') {
+ if (ss.realtimeAPIModeContentType === CONTENT_TYPES.AUDIO) {
- console.log('Sending buffer. Length:', audioBufferRef.current.length)
+ logger.debug('Sending buffer. Length:', audioBufferRef.current.length)
sendContent = [
{
- type: 'input_audio',
+ type: CONTENT_TYPES.AUDIO,
audio: base64Chunk,
},
]
- } else {
+ } else if (ss.realtimeAPIModeContentType === CONTENT_TYPES.TEXT) {
const currentText = transcriptRef.current.trim()
- console.log('Sending text. userMessage:', currentText)
+ logger.debug('Sending text. userMessage:', currentText)
sendContent = [
{
- type: 'input_text',
+ type: CONTENT_TYPES.TEXT,
text: currentText,
},
]
+ } else {
+ logger.error(`Unsupported content type: ${ss.realtimeAPIModeContentType}`)
+ return;
}コンテンツタイプの定義が他のファイルにも存在するか確認するスクリプトを実行します:
Let me gather more information about the content type usage and settings store implementation.
Let me try one more search to find any type definitions or constants related to these content types.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check for content type definitions across the codebase
rg -g '*.{ts,tsx}' "('input_audio'|'input_text')" --type-add 'tsx:*.tsx'
Length of output: 453
Script:
#!/bin/bash
# Check the settings store implementation and type definitions
ast-grep --pattern 'type $_ = {
$$$
realtimeAPIModeContentType: $_
$$$
}'
# Check for any enum or type definitions related to content types
rg -g '*.{ts,tsx}' "type.*ContentType|enum.*ContentType"
Length of output: 140
Script:
#!/bin/bash
# Search for any type definitions or constants related to input modes
rg -g '*.{ts,tsx}' -B 2 -A 2 "realtimeAPIModeContentType"
# Check for any type imports or exports
ast-grep --pattern 'export type $_ = $$$'
Length of output: 6677
| return ( | ||
| <> | ||
| <div>{t('AzureTTSInfo')}</div> | ||
| <div className="mt-16 font-bold">{t('AzureAPIKeyLabel')}</div> | ||
| <div className="mt-8"> | ||
| <input | ||
| className="text-ellipsis px-16 py-8 w-col-span-4 bg-surface1 hover:bg-surface1-hover rounded-8" | ||
| type="text" | ||
| placeholder="..." | ||
| value={azureTTSKey} | ||
| onChange={(e) => | ||
| settingsStore.setState({ | ||
| azureTTSKey: e.target.value, | ||
| }) | ||
| } | ||
| /> | ||
| </div> | ||
| <div className="mt-16 font-bold">{t('AzureEndpoint')}</div> | ||
| <div className="mt-8"> | ||
| <input | ||
| className="text-ellipsis px-16 py-8 w-col-span-4 bg-surface1 hover:bg-surface1-hover rounded-8" | ||
| type="text" | ||
| placeholder="..." | ||
| value={azureTTSEndpoint} | ||
| onChange={(e) => | ||
| settingsStore.setState({ | ||
| azureTTSEndpoint: e.target.value, | ||
| }) | ||
| } | ||
| /> | ||
| </div> | ||
| <div className="mt-16 font-bold">{t('OpenAITTSVoice')}</div> | ||
| <div className="mt-8"> | ||
| <select | ||
| value={openaiTTSVoice} | ||
| onChange={(e) => | ||
| settingsStore.setState({ | ||
| openaiTTSVoice: e.target.value as OpenAITTSVoice, | ||
| }) | ||
| } | ||
| className="px-16 py-8 bg-surface1 hover:bg-surface1-hover rounded-8" | ||
| > | ||
| <option value="alloy">alloy</option> | ||
| <option value="echo">echo</option> | ||
| <option value="fable">fable</option> | ||
| <option value="onyx">onyx</option> | ||
| <option value="nova">nova</option> | ||
| <option value="shimmer">shimmer</option> | ||
| </select> | ||
| </div> | ||
| <div className="mt-16 font-bold">{t('OpenAITTSModel')}</div> | ||
| <div className="mt-16 font-bold"> | ||
| {t('OpenAITTSSpeed')}: {openaiTTSSpeed} | ||
| </div> | ||
| <input | ||
| type="range" | ||
| min={0.25} | ||
| max={4.0} | ||
| step={0.01} | ||
| value={openaiTTSSpeed} | ||
| className="mt-8 mb-16 input-range" | ||
| onChange={(e) => { | ||
| settingsStore.setState({ | ||
| openaiTTSSpeed: Number(e.target.value), | ||
| }) | ||
| }} | ||
| /> | ||
| </> | ||
| ) |
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.
[バグ] Azure TTS設定でOpenAI TTSの変数とテキストが使用されています
Azure TTSの設定セクションで、OpenAI TTSに関連する変数やテキストが使用されています。これにより、ユーザーが混乱する可能性があります。
修正提案:
-
テキストの修正
表示されるテキストをAzure TTS用に変更します。
- {t('OpenAITTSVoice')} + {t('AzureTTSVoice')}
-
状態変数の修正
Azure TTS専用の状態変数を使用します。
- value={openaiTTSVoice} + value={azureTTSVoice}
-
型の修正
型アサーションをAzure TTS用にします。
- openaiTTSVoice: e.target.value as OpenAITTSVoice, + azureTTSVoice: e.target.value as AzureTTSVoice,
-
速度設定の追加
Azure TTS用の速度設定を追加し、状態変数を使用します。
<div className="mt-16 font-bold"> {t('AzureTTSSpeed')}: {azureTTSSpeed} </div> <input type="range" min={0.25} max={4.0} step={0.01} value={azureTTSSpeed} className="mt-8 mb-16 input-range" onChange={(e) => { settingsStore.setState({ azureTTSSpeed: Number(e.target.value), }) }} />
-
必要な型と状態変数の定義
AzureTTSVoiceやazureTTSSpeedなど、必要な型や状態変数を定義します。
| const openaiTTSKey = settingsStore((s) => s.openaiTTSKey) | ||
| const openaiTTSVoice = settingsStore((s) => s.openaiTTSVoice) | ||
| const openaiTTSModel = settingsStore((s) => s.openaiTTSModel) | ||
| const openaiTTSSpeed = settingsStore((s) => s.openaiTTSSpeed) | ||
| const azureTTSKey = settingsStore((s) => s.azureTTSKey) | ||
| const azureTTSEndpoint = settingsStore((s) => s.azureTTSEndpoint) |
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.
[バグ] Azure TTSとOpenAI TTSの設定が混在しています
Azure TTS用の設定で、OpenAI TTSの状態変数が使用されています。これは誤りであり、Azure TTS専用の状態変数を使用する必要があります。
具体的な修正提案:
-
状態変数の追加と取得
settingsStoreからAzure TTS用の状態変数を取得します。+ const azureTTSVoice = settingsStore((s) => s.azureTTSVoice) + const azureTTSSpeed = settingsStore((s) => s.azureTTSSpeed)
-
OpenAI TTSとAzure TTSの変数を明確に区別
Azure TTSの設定で、OpenAI TTSの変数を使用しないようにします。
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const openaiTTSKey = settingsStore((s) => s.openaiTTSKey) | |
| const openaiTTSVoice = settingsStore((s) => s.openaiTTSVoice) | |
| const openaiTTSModel = settingsStore((s) => s.openaiTTSModel) | |
| const openaiTTSSpeed = settingsStore((s) => s.openaiTTSSpeed) | |
| const azureTTSKey = settingsStore((s) => s.azureTTSKey) | |
| const azureTTSEndpoint = settingsStore((s) => s.azureTTSEndpoint) | |
| const openaiTTSKey = settingsStore((s) => s.openaiTTSKey) | |
| const openaiTTSVoice = settingsStore((s) => s.openaiTTSVoice) | |
| const openaiTTSModel = settingsStore((s) => s.openaiTTSModel) | |
| const openaiTTSSpeed = settingsStore((s) => s.openaiTTSSpeed) | |
| const azureTTSKey = settingsStore((s) => s.azureTTSKey) | |
| const azureTTSEndpoint = settingsStore((s) => s.azureTTSEndpoint) | |
| const azureTTSVoice = settingsStore((s) => s.azureTTSVoice) | |
| const azureTTSSpeed = settingsStore((s) => s.azureTTSSpeed) |
OpenAI TTSを選択肢に追加
Summary by CodeRabbit
新機能
翻訳の改善
バグ修正