-
-
Notifications
You must be signed in to change notification settings - Fork 143
Develop #327
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
Conversation
キャラクタープリセット機能を実装
…善し、既に認識が開始されている場合の処理を明確化しました。
…を強化しました。また、VRMモデルの初期化時にforceStartオプションを有効にしました。
…0msに変更し、認識の安定性を向上させました。
Feature/update several functions
|
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
|
Caution Review failedThe pull request is closed. Walkthroughこのプルリクエストは、AITuberKitプロジェクトに音声関連の新しい機能と設定を追加するものです。 Changes
Sequence DiagramsequenceDiagram
participant User
participant UI
participant SpeechRecognition
participant AIService
participant CharacterModel
User->>UI: 音声入力を開始
UI->>SpeechRecognition: 音声認識を開始
SpeechRecognition-->>UI: 音声テキストを取得
UI->>AIService: テキストを送信
AIService-->>CharacterModel: レスポンスを生成
CharacterModel->>UI: 感情と応答を返す
UI->>User: キャラクターの応答を表示
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.
Caution
Inline review comments failed to post. This is likely due to GitHub's limits when posting large numbers of comments. If you are seeing this consistently it is likely a permissions issue. Please check "Moderation" -> "Code review limits" under your organization settings.
Actionable comments posted: 10
🧹 Nitpick comments (87)
website/document/guide/ai/multimodal.md (1)
93-96: 新しい警告セクションの追加新たに追加された「::: warning 注意」ブロックは、APIへ送信する画像に関して、最新の画像のみが対象となるという重要な注意をユーザーに明示的に伝えています。記述内容は明瞭で、読者が意図する動作を理解するのに十分です。
ただし、より具体的なシナリオや例(例:過去のチャットセッション内で共有された画像についての具体例)を補足情報として追加すると、利用者の理解がさらに深まるかもしれません。
docs/README_pl.md (1)
46-48: 説明文の改善と表記の確認:
追加された説明文は AITuberKit の主要な機能を明確に説明しており、ユーザーがツールの利用方法を理解しやすくなっています。ただし、文中に「AITuber」という表記が用いられていますが、静的解析ツールからはハイフンを含めた「AIT-uber」とすることが推奨されています。必要であれば、表記の一貫性を保つために修正をご検討ください。🧰 Tools
🪛 LanguageTool
[misspelling] ~47-~47: Prawdopodobny błąd zapisu odmiany; skrótowce odmieniamy z dywizem:"AIT-uber".
Context: ... funkcjach dialogowych i streamingowych AITuber z wysokim stopniem personalizacji. <im...(SKROTOWCE_BEZ_DYWIZU)
docs/character_model_licence.md (1)
35-37: 禁止事項内の例外規定の導入についてVRMモデルに関して「開発者の事前の許諾を得ることで、部分的に許可される可能性」が明記されたことで、より柔軟な利用が可能になる変更となっています。
ただし、今後、許諾を得るための具体的な手続きや条件について、詳細なガイドラインを別途用意するとさらに明確になるかもしれません。website/document/guide/character/common.md (1)
67-67: コードブロックに言語指定が必要ですマークダウンのフェンスコードブロックに言語指定がありません。読みやすさと構文ハイライトのために言語指定(例:
bash)を追加することをお勧めします。-``` +```bash🧰 Tools
🪛 markdownlint-cli2 (0.17.2)
67-67: Fenced code blocks should have a language specified
null(MD040, fenced-code-language)
src/pages/api/services/utils.ts (1)
47-84: メッセージ統合機能の実装同じroleを持つ連続したメッセージを効率的に結合する関数が実装されています。テキストと画像の両方のコンテンツタイプを考慮した処理が含まれており、堅牢な設計です。
ただし、TypeScriptの型定義がやや複雑です。今後のメンテナンス性を考慮すると、型定義の部分を別途インターフェースとして定義することも検討してみてください。
.env.example (1)
79-79: surprised感情設定の追加新しい「surprised」感情の設定が追加されていますが、デフォルト値が「Neutral」になっています。これは意図的でしょうか?驚きの表情用に専用の値を設定した方が自然かもしれません。
Live2Dモデルに驚きの表情やモーションが実装されていない場合のフォールバックとして「Neutral」を使用しているのかもしれませんが、可能であれば専用の値を設定することをお勧めします。
Also applies to: 88-88
locales/th/translation.json (1)
56-61: プリセット設定情報の追加について
新たに追加された「characterpresetInfo」および「Characterpreset1〜5」のエントリは、キャラクタープリセット選択機能をユーザーに分かりやすく伝えるために重要です。キー名の大文字小文字の一貫性については、今後のメンテナンスで他ラング対応との整合性を確認してください。website/document/zh/guide/ai/multimodal.md (1)
93-96: 新規警告ノートの追加について
警告ノートが追加され、「APIは最新の画像のみ送信する」という重要な仕様が記載されています。これにより、ユーザーが入力コンテキストの最適化について十分に理解できるようになっており、ドキュメントの明瞭性が向上しています。ただし、警告内容がユーザーに対して具体的に影響を与える点(例:コスト増加の可能性など)について、必要に応じて追加の説明を検討しても良いかもしれません。src/components/toasts.tsx (1)
16-16: トースト通知のマージン変更の影響検証
classNameのマージンがm-6に更新されています。この変更がUI全体や他のコンポーネントとのレイアウトにどのような影響を及ぼすか、実際の動作を確認してください。src/utils/voiceLanguage.ts (1)
1-39: 新しい言語コード変換ユーティリティの追加この新しいユーティリティ関数は、言語コードを音声認識用の言語コードに適切に変換しています。多くの言語に対応しており、デフォルト値も設定されていて堅牢です。
1点のみ、テスト可能性を向上させるために関数のテストを追加することを検討してもよいでしょう。また、将来的に言語コードが増えた場合の拡張性も考慮されています。
// 言語コードと対応する音声認識コードのマッピングをオブジェクトとして定義すると、 // 将来的な拡張や変更が容易になります const LANGUAGE_CODE_MAP: Record<string, VoiceLanguage> = { ja: 'ja-JP', en: 'en-US', ko: 'ko-KR', zh: 'zh-TW', // その他の言語コードマッピング... } export const getVoiceLanguageCode = (selectLanguage: string): VoiceLanguage => { return LANGUAGE_CODE_MAP[selectLanguage] || 'ja-JP' }docs/README_ko.md (1)
46-47: 概要文章の強化について
この部分では、AITuberKitの機能や拡張性が具体的に記述され、利用者に対する魅力が効果的に伝えられています。マークアップ(例:<br>)の使用については問題ありませんが、読みやすさや改行の位置について最終的なデザイン確認を推奨します。website/document/guide/voice-settings.md (1)
5-5: 説明文の表現を改善できます「調整することができます」という表現は冗長です。「調整できます」とシンプルにすると文章がより簡潔になります。
-合成音声設定では、AIキャラクターの音声合成に関する設定を行います。様々な音声合成エンジンを選択し、声質やパラメータを調整することができます。 +合成音声設定では、AIキャラクターの音声合成に関する設定を行います。様々な音声合成エンジンを選択し、声質やパラメータを調整できます。🧰 Tools
🪛 LanguageTool
[uncategorized] ~5-~5: 「ことができる」という表現は冗長な可能性があります。
Context: ...関する設定を行います。様々な音声合成エンジンを選択し、声質やパラメータを調整することができます。 ```bash # 使用する音声合成エンジン # voicevox, ...(DOUSI_KOTOGADEKIRU)
website/document/en/guide/basic-settings.md (1)
101-101: スマートフォンでの設定画面表示方法の追加スマートフォンユーザー向けに画面左上を長押しすることで設定画面を表示できる情報が追加されており、モバイルユーザビリティが向上しています。
「top left corner」はハイフンで「top-left corner」とするとより正確です。
-If you are using a smartphone, you can also display it by long-pressing the top left corner of the screen (about 1 second). +If you are using a smartphone, you can also display it by long-pressing the top-left corner of the screen (about 1 second).🧰 Tools
🪛 LanguageTool
[uncategorized] ~101-~101: Consider adding a hyphen.
Context: ...an also display it by long-pressing the top left corner of the screen (about 1 second). ...(TOP_LEFT_CORNER)
src/hooks/useRealtimeVoiceAPI.ts (4)
16-21: 関数シグネチャの引数に関する注意点
onChatProcessStartをコールバックとして受け取っていますが、音声認識とチャット処理が密接に絡むことで、将来的にコールバックが増える可能性があります。複数の処理を想定するなら、オブジェクト経由で必要なハンドラをまとめて受け取る設計も検討すると保守性が向上します。
311-321: キーボードトリガーでの処理の拡張性に注意
toggleListening内でキーボード由来かどうかをisKeyboardTriggeredで判定していますが、今後ホットキーが増えたり、外部デバイス起因のトリガーが追加されると分岐が複雑化しがちです。将来的な拡張を見据えて、トリガー元の列挙やイベント管理を別モジュールで抽象化するとスケーラビリティが高まります。
334-339: 入力変更処理のエラーハンドリング現在は単純にstate更新のみですが、実際のアプリケーションで入力のバリデーションが必要になる場合があります。例えば、文字数制限や禁止ワードのフィルタ等が考えられるため、今後の要件拡大に応じて拡張できるよう余地を確保しておくと良いでしょう。
403-407: WebSocket接続状態のユーティリティ化を検討
isWebSocketReadyはwsManager?.websocket?.readyState === WebSocket.OPENを判定するだけなので、同様のパターンを他のファイルでも使うなら共通ユーティリティ化すると繰り返しのミスを防げます。docs/README_zh.md (1)
49-49: アーキテクチャ図リンクの拡充ここで
./images/architecture_en.svgを参照していますが、中国語ドキュメント向けに図自体の言語表記を変えたり、翻訳済みの画像を差し替えるかは検討の余地があります。別途多言語対応の画像を用意するか、共通化するか、ドキュメントの設計ポリシーを明確にするとよいでしょう。src/features/chat/handlers.ts (1)
271-271: 繰り返しのパターンをユーティリティ関数化する検討行112と同様の記述が行271でも行われています。共通化して
normalizeEmotion()のようなユーティリティ関数経由で実装すると、修正箇所をひとつにまとめることができ保守性が向上します。src/features/stores/toast.ts (1)
25-32: トースト管理の改善は素晴らしい実装です。同じタグを持つトーストを条件分岐で拒否するのではなく、フィルタリングして新しいトーストに置き換える実装に変更されています。これにより、トースト通知のユーザーエクスペリエンスが向上し、同じタグに対して最新の情報が常に表示されるようになりました。
しかし、
ToastStateインターフェースのaddToastメソッドの戻り値型は、現在もstring | nullとなっていますが、実装では常にstringを返すようになっています。型定義を修正するとさらに良いでしょう。interface ToastState { toasts: Toast[] - addToast: (toast: Omit<Toast, 'id'>) => string | null + addToast: (toast: Omit<Toast, 'id'>) => string removeToast: (identifier: string) => void closeToast: (identifier: string) => void }website/document/guide/usage-tips.md (1)
7-43: カラーテーマ変更に関するドキュメントの追加は有用です。tailwind.config.jsファイルを編集してカラーテーマを変更する方法を詳細に説明しています。コード例や視覚的な例(画像)も含まれており、ユーザーにとって非常に役立つ情報です。さらに、AIアシスタントに依頼する方法についてのヒントも便利です。
ただし、マイク入力に関するセクションが完全に削除されているようです。新しく追加された音声入力機能との関連性を考えると、マイク入力に関する情報も残しておくか、新しい音声入力機能についての説明を追加するとよいかもしれません。
新しい音声入力機能(SpeechInput)に関するセクションも追加することを検討してください。例:
## 音声入力機能の活用 AITuberKitの音声入力機能を使うことで、マイクを通じた対話が可能になります。設定画面の「音声入力設定」タブから各種設定を行えます。 ### 音声認識の精度を向上させるコツ ...src/pages/api/ai/custom.ts (1)
1-53: エンドポイント全体の設計についてこのエンドポイントは
handleCustomApi関数を活用して、カスタムAPIへのリクエスト処理を行う良い設計です。既存のAPI構造に一貫した形で統合されており、エラーハンドリングも徹底されています。しかし、カスタムAPIの使用に関するセキュリティ上の考慮点を検討する必要があるかもしれません。例えば、許可されたAPIのURLリストやレート制限などを将来的に実装することを検討してください。
src/pages/api/openAITTS.ts (2)
22-33: オプションオブジェクトの型定義を改善できますオプションオブジェクトの導入は良い改善ですが、型定義に
anyを使用しているため型安全性が低下しています。- const options: { - model: any - voice: any - speed: any - input: any - instructions?: any - } = { + const options: { + model: string + voice: string + speed: number + input: string + instructions?: string + } = {
35-37: GPT-4o モデル用の感情表現機能の追加 👍GPT-4o モデルに感情表現を追加する条件分岐は、ユーザー体験を向上させる素晴らしい機能です。しかし、非 GPT-4o モデルでは
emotionパラメータがどのように扱われるかが明確ではありません。他のモデルでも感情を活用したい場合は、以下のような実装も検討できます:
if (model.includes('gpt-4o')) { options.instructions = `Please speak "${message}" with rich emotional expression.` + } else if (emotion) { + options.instructions = `Please speak "${message}" with ${emotion} emotion.` }website/document/zh/guide/ai/model-provider.md (1)
239-255: カスタム API の新しいセクションを追加 👍カスタム API の設定に関する詳細な説明と注意事項が追加されています。ユーザーにとって有用な情報です。
注意事項セクションにカスタム API の期待されるレスポンス形式や具体的な例を追加すると、さらに有用なドキュメントになるでしょう。
src/components/characterPresetMenu.tsx (2)
18-50: キャラクタープリセット配列の最適化を検討してくださいプリセット配列が毎回のレンダリング時に再作成されています。パフォーマンスを向上させるために
useMemoを使用することを検討してください。- const characterPresets = [ + const characterPresets = useMemo(() => [ { key: 'characterPreset1', value: store.characterPreset1, nameKey: 'customPresetName1', customName: store.customPresetName1, }, // ... 他のプリセット - ] + ], [ + store.characterPreset1, + store.characterPreset2, + store.characterPreset3, + store.characterPreset4, + store.characterPreset5, + store.customPresetName1, + store.customPresetName2, + store.customPresetName3, + store.customPresetName4, + store.customPresetName5 + ])また、このメモ化をさらに最適化するためには、Zustand の selector パターンを使用して必要な状態だけを購読することも検討できます。
131-166: プリセットメニューの UI 実装プリセットメニューの UI 実装とアクセシビリティ属性の設定は適切です。選択状態の視覚的な表示も効果的です。
画面リーダーユーザー向けにプリセット切り替え時の通知を強化するため、以下のような
aria-live領域の追加を検討してください:+ // aria-live 領域の状態 + const [ariaMessage, setAriaMessage] = useState(''); const handlePresetClick = ( key: string, value: string, customName: string, index: number ) => { settingsStore.setState({ systemPrompt: value, selectedPresetIndex: index, }) + // アクセシビリティ通知を設定 + setAriaMessage(t('Toasts.PresetSwitching', { + presetName: customName, + })); toastStore.getState().addToast({ message: t('Toasts.PresetSwitching', { presetName: customName, }), type: 'info', tag: `character-preset-switching`, }) setIsOpen(false) } return ( <div className="fixed bottom-20 right-4 z-30"> + {/* アクセシビリティ通知 */} + <div className="sr-only" aria-live="polite"> + {ariaMessage} + </div> {/* メインボタン */} ...website/document/zh/guide/speech-input-settings.md (1)
56-56: 文法に関する軽微な提案
「更快的识别速度」という表現は、中国語として「更快地识别」のほうが自然と指摘されています。翻訳の文脈上問題がなければ、必要に応じて修正をご検討ください。🧰 Tools
🪛 LanguageTool
[uncategorized] ~56-~56: 动词的修饰一般为‘形容词(副词)+地+动词’。您的意思是否是:快"地"识别
Context: ...rning 注意 通常,推荐使用浏览器语音识别模式,因为它具有更高的准确性和更快的识别速度。但是,如果您使用的浏览器不支持WebSpeech API,如Firef...(wb4)
src/hooks/useWhisperRecognition.ts (2)
64-69: クライアント側でのAPIキー管理によるセキュリティリスク
OpenAI APIキーをクライアント側のstoreで保持・送信しているため、エンドユーザーの環境からキーが参照されるリスクがあります。もし機密度の高いキーである場合、サーバー側でプロキシ経由の呼び出しを行い、キーを隠蔽する方法もご検討ください。
79-89: 音声ファイルサイズ上限の考慮を推奨
録音時間が長くなるとファイルサイズが大きくなり、/api/whisperへの送信に時間やコストがかかる可能性があります。長時間の録音に対しては、ファイルの最大サイズや時間制限を設けるなどのガイドラインを追加すると、ユーザー体験が向上するかもしれません。website/document/guide/speech-input-settings.md (1)
53-53: より簡潔な表現に修正してはいかがでしょうか「ボタンをクリックして切り替えることができます」という表現は冗長かもしれません。「ボタンをクリックして切り替えられます」や「ボタンで切り替えられます」のような、より簡潔な表現にすることを検討してください。
🧰 Tools
🪛 LanguageTool
[uncategorized] ~53-~53: 「ことができる」という表現は冗長な可能性があります。
Context: ...るため、認識されるまでに少し時間がかかります。 ボタンをクリックして切り替えることができます。 ::: warning 注意 一般的にはブラウザの音声認識モードの方が...(DOUSI_KOTOGADEKIRU)
src/utils/textProcessing.ts (2)
65-65: 非同期処理の実装が最適ではありません非同期処理を実装するために
setTimeout(resolve, 0)を使用していますが、これは必ずしも最適なアプローチではありません。代わりにPromise.resolve().then()を使用すると、より効率的にマイクロタスクキューを活用できます。- await new Promise((resolve) => setTimeout(resolve, 0)) + await Promise.resolve()
31-53: パフォーマンス改善の余地があります現在の実装では、全ての共通単語に対して処理を行っていますが、入力テキストに英語が含まれているかを最初にチェックすることで、不要な処理をスキップできます。containsEnglish関数を活用するとさらに効率的になります。
export function convertEnglishToJapaneseReading(text: string): string { + // 英語が含まれていない場合は変換せずに返す + if (!containsEnglish(text)) { + return text + } // 大文字小文字を区別せずに変換するために、テキストを小文字化してキャッシュ const lowerText = text.toLowerCase() // 以下、現在の実装と同じ ... }src/components/settings/slideConvert.tsx (1)
98-120: ファイルアップロード部分のUI改善の余地ファイル名が長い場合の表示に
text-ellipsisとoverflow-hiddenを適用していますが、最大幅が指定されていないため、非常に長いファイル名はUIを崩す可能性があります。- <span className="ml-4 text-ellipsis overflow-hidden"> + <span className="ml-4 text-ellipsis overflow-hidden max-w-[200px] inline-block">website/document/en/guide/voice-settings.md (1)
103-136: Style-Bert-VITS2セクション新設
詳細な設定例が追加され、導入負担が軽減されます。なお、Generally not needed.の箇所にカンマを挿入するとより自然な英語表現となります。-This is required when launched with RunPod. Generally not needed. +This is required when launched with RunPod. Generally, not needed.🧰 Tools
🪛 LanguageTool
[typographical] ~128-~128: Consider adding a comma after ‘Generally’ for more clarity.
Context: ... is required when launched with RunPod. Generally not needed. ### Voice Parameter Adjust...(RB_LY_COMMA)
src/components/presetQuestionButtons.tsx (1)
51-72: UI実装が適切です、ただし水平スクロールのブラウザ互換性に注意UIのレイアウトとスタイリングは適切に実装されていますが、カスタムスクロールバースタイル(scrollbar-thin scrollbar-thumb-secondary scrollbar-track-transparent)のブラウザ互換性について確認することをお勧めします。
特にFirefoxやSafariなど異なるブラウザでのスクロールバーの表示をテストし、必要に応じて互換性のあるスタイリングに調整してください。
docs/character_model_licence_pl.md (1)
1-1: ポーランド語テキストの文法的・タイポグラフィー的な修正が必要ですポーランド語の文書にいくつかの文法的・タイポグラフィー的な問題があります。主な問題点:
- 21行目: 「Jednakże,」の後のカンマは不要
- 38行目と40行目: 「lub」の前にカンマが必要
- 42行目: 「W przypadku modeli Live2D,」の後のカンマは不要
- 47行目: 「jakiekolwiek」ではなく「żadne」を使用すべき
- 54行目: 「modeli,」の後のカンマは不要
ネイティブのポーランド語話者にレビューを依頼するか、ポーランド語の文法チェッカーで確認することをお勧めします。
Also applies to: 5-5, 13-13, 29-31, 40-43, 47-47, 55-55
website/document/en/guide/speech-input-settings.md (2)
1-31: 音声入力設定ドキュメントの構成が良いです環境変数の説明が明確で、各設定パラメータの目的と値の範囲が適切に記述されています。ただし、一点気になる点として、「OpenAI's Text-to-Speech API」という表現があります。これは通常、テキストを音声に変換するAPIを指しますが、ここでは音声認識のコンテキストで使用されています。
「OpenAI's Speech-to-Text API」または「OpenAI's Whisper API」のような、より正確な表現に修正することを検討してください。
95-110: OpenAIモデルの説明に費用情報の追加が望ましい各モデルの特性(whisper-1、gpt-4o-transcribe、gpt-4o-mini-transcribe)について説明されていますが、111行目で「Models differ in accuracy, speed, and cost」と言及されているにもかかわらず、具体的な費用の違いについての情報がありません。
各モデルの相対的なコスト情報を追加することで、ユーザーが適切なモデルを選択するための参考になります。例えば、「gpt-4o-transcribeは最も高性能ですが、最も高価です」などの情報を追加してください。
src/hooks/useBrowserSpeechRecognition.ts (2)
97-123: Firefox への対応方法の再検討をおすすめします。
行 98 付近でuserAgentによるブラウザ判別を行っていますが、UA 文字列は将来的に変更される可能性があります。Firefox でまだ検証不足のケースや、デスクトップ版との違いが出る可能性に注意してください。より汎用的かつ確実な判定基準やフィーチャー検出へ変更することを検討してください。
271-326: onstart イベント時のリスナー登録を最小化しましょう。
newRecognition.onstart内で初期音声検出のタイマー設定や無音検出の開始処理が行われていますが、大きな匿名関数に込み入ったロジックが集中しています。イベントリスナーは必要最低限の責務に留め、詳細な処理は別の関数やカスタムフックなどに切り出すとテスト・保守が容易になります。website/document/zh/guide/voice-settings.md (3)
80-81: 中国語文法の表記ゆれに注意してください。
項目「-10至10」について、数詞と名詞の間に量詞が必要である旨が静的解析ツールから指摘がありました。以下のように「-10 到 10 的范围内」など明確に書き換えることで可読性が向上します。- - **X轴**:在-10至10范围内调整声音质量 - - **Y轴**:在-10至10范围内调整声音质量 + - **X轴**:在 -10 到 10 的范围内调整声音质量 + - **Y轴**:在 -10 到 10 的范围内调整声音质量🧰 Tools
🪛 LanguageTool
[uncategorized] ~80-~80: 数词与名词之间一般应存在量词,可能缺少量词。
Context: ..."可爱"、"有活力"、"酷"和"深沉"等预设中选择 - X轴:在-10至10范围内调整声音质量 - Y轴:在-10至10范围内调整声音质量 ## Go...(wa5)
[uncategorized] ~81-~81: 数词与名词之间一般应存在量词,可能缺少量词。
Context: ...- X轴:在-10至10范围内调整声音质量 - Y轴:在-10至10范围内调整声音质量 ## Google Text-to-Speech ```ba...(wa5)
103-136: 新規の「Style-Bert-VITS2」セクションについて、導入部分をもう少し明確化してください。
「Style-Bert-VITS2」がどのようなバージョンやアドバンテージを持つのか読者がひと目で理解できるよう、概要を2~3行で説明するとドキュメントの分かりやすさが向上します。🧰 Tools
🪛 LanguageTool
[uncategorized] ~124-~124: 数词与名词之间一般应存在量词,可能缺少量词。
Context: ...日语、英语和中文。 ### 服务器URL 设置Style-Bert-VITS2服务器的URL。 ### API密钥 使用RunPod启动时需要此项。通常不需要设...(wa5)
236-237: 新モデルの説明追加を検討してください。
「gpt-4o-mini-tts」など新しく追加されたモデルに関する簡単な説明や用途が不足しているため、利用者がどのような特徴を持つモデルか迅速に把握できるよう、変更意図を追記することをおすすめします。src/components/menu.tsx (3)
19-39: カスタムフックの命名と実装方針について補足を検討してください。
useIsMobileは幅と UA 判定を組み合わせており、デバイスの実際の特性に依存します。プロジェクト全体で「モバイル判定」に一貫したアプローチを行うため、関数のドキュメントコメントやユニットテストで判定ロジックを明確化しておくと保守しやすくなります。
59-88: ロングタップ用ステート管理周りの共通化を検討しましょう。
touchStartTimeとtouchEndTimeをそれぞれ更新していますが、最終的には 800ms 以上かどうかのみを判定しています。実装を小さなカスタムフックに分割してonLongPressイベントを提供するなど、他のコンポーネントでも再利用できる形にすると保守性や拡張性が向上します。
189-199: ロングタップ用透明領域のアクセシビリティに配慮してください。
画面上部に重ねる透明なdivは、スクリーンリーダー利用者にとって誤解や操作の難しさを引き起こす可能性があります。タッチサポート専用である旨をaria-hidden属性や説明コメントで示すなど、視覚外のユーザーにも配慮した設計が望ましいです。src/pages/api/services/customApi.ts (4)
22-24: 型定義の改善推奨
parsedBodyの型としてRecord<string, any>を使用していますが、これは型安全性を低下させる可能性があります。可能であれば、より具体的な型を定義するか、少なくともunknown型を使用することを検討してください。- let parsedBody: Record<string, any> = {} + let parsedBody: Record<string, unknown> = {}
52-54: 本番環境でのロギングを見直し本番環境のコードには、APIヘッダーとボディをロギングする
console.log文が含まれています。これらのログは機密情報を含む可能性があるため、開発環境でのみ出力されるようにするか、完全に削除することを検討してください。- console.log('apiHeaders', apiHeaders) - console.log('apiBody', apiBody) + if (process.env.NODE_ENV !== 'production') { + console.log('apiHeaders', apiHeaders) + console.log('apiBody', apiBody) + }
62-96: エラー処理の簡略化を検討現在のエラー処理コードは、エラーレスポンスの内容を取得できなかった場合でも同じエラーオブジェクトを返し、内部のログ出力だけが異なります。このコードをより簡潔にすることを検討してください。
if (!apiResponse.ok) { console.error( `Custom API Error: Status ${apiResponse.status}, URL: ${customApiUrl}` ) try { // エラーレスポンスの内容も可能であればログに出力 const errorResponseText = await apiResponse.text() console.error(`Error Response: ${errorResponseText}`) - - // レスポンスを再作成するため、新しいResponseオブジェクトを作成 - return new Response( - JSON.stringify({ - error: `Custom API Error: ${apiResponse.status}`, - errorCode: 'CustomAPIError', - }), - { - status: apiResponse.status, - headers: { 'Content-Type': 'application/json' }, - } - ) } catch (e) { console.error('Failed to read error response body:', e) - return new Response( - JSON.stringify({ - error: `Custom API Error: ${apiResponse.status}`, - errorCode: 'CustomAPIError', - }), - { - status: apiResponse.status, - headers: { 'Content-Type': 'application/json' }, - } - ) } + + // エラーレスポンスを作成 + return new Response( + JSON.stringify({ + error: `Custom API Error: ${apiResponse.status}`, + errorCode: 'CustomAPIError', + }), + { + status: apiResponse.status, + headers: { 'Content-Type': 'application/json' }, + } + ) }
113-114: フォールバック処理に関するコメントの追加非ストリーミングレスポンスで
data.text || data.content || JSON.stringify(data)を使用しているフォールバックロジックの意図を説明するコメントがあると良いでしょう。JSON.stringify({ + // テキスト取得の優先順位: data.text → data.content → 完全なJSONデータ text: data.text || data.content || JSON.stringify(data), }),src/utils/audioProcessing.ts (2)
29-45: サンプルレートのハードコーディングに注意
processAudio関数では、ターゲットサンプルレートが24000Hzにハードコーディングされています。この値が適切かどうかはユースケースによって異なります。将来的な柔軟性を確保するために、この値を設定可能にすることを検討してください。- export const processAudio = (audioBuffer: AudioBuffer): Float32Array => { - const targetSampleRate = 24000 + export const processAudio = ( + audioBuffer: AudioBuffer, + targetSampleRate: number = 24000 + ): Float32Array => {
48-56: PCM変換関数の境界チェック
floatTo16BitPCM関数では、入力値が[-1, 1]の範囲に正しく収まっていることを確認していますが、入力のFloat32Array全体がこの範囲にあることを前提としています。より堅牢にするために、関数のドキュメントにこの前提条件を記載することをお勧めします。- // Float32Array を PCM16 ArrayBuffer に変換する関数 + // Float32Array を PCM16 ArrayBuffer に変換する関数 + // 注意: 入力のFloat32Arrayは[-1, 1]の範囲内の値であることを前提としています export const floatTo16BitPCM = (float32Array: Float32Array): ArrayBuffer => {docs/character_model_licence_en.md (1)
33-43: 禁止事項に関する例外の明確化VRMモデルと Live2D モデルで異なる例外ポリシーを設定している点は、ユーザーにとって重要な情報です。ただし、VRMモデルについて「開発者の事前の同意があれば部分的に許可される可能性がある」と述べていますが、その許可をどのように求めればよいかの具体的な方法(連絡先や申請プロセス)が明記されていないため、追加することをお勧めします。
src/components/settings/advancedSettings.tsx (2)
17-20: UIレイアウトの変更が明確です。
<div className="mb-10">および関連するクラス変更により、視覚的間隔を調整しているようですが、コンポーネントが非常に大きくなる場合は、セクションを分割するなどの対応を検討しても良いでしょう。
30-34: 背景動画切り替えのセクション配置がわかりやすいです。
ただし設定項目が増えた場合、折りたたみ可能なUIやタブを利用して整理するとユーザーが見やすくなるでしょう。src/components/settings/character.tsx (4)
3-4:next/imageの導入を確認しました。
アイコン表示箇所が複数に増える場合、コンポーネント化を検討すると保守性が向上します。
89-93: 驚きのモーションフィールドが追加されています。
defaultValue: 'Surprised'のみ指定されているため、要件に応じて複数アニメーションをサポートする場合は拡張も検討できます。
475-477: VRM・Live2D切り替えボタン周りの実装が分かりやすいです。
- クラス指定により選択中のボタンを強調しており、UI面で直感的に操作できます。
- ただし
bg-white hover:bg-white-hoverなど色指定が増えた場合、共通コンポーネント化を検討できます。Also applies to: 480-480, 487-487, 490-490
501-501: ファイル選択・Live2Dモデルのリスト表示が整合的です。
- 非同期処理のエラーハンドリングが
console.errorのみなので、ユーザーに明示的に通知する仕組みを導入すると親切です。Also applies to: 517-517, 539-539, 543-543, 556-556
src/pages/api/services/vercelAi.ts (3)
14-14:AIServiceConfig型定義の単純化により、プロバイダごとのパラメータ設定がわかりやすくなっています。
拡張時はPartial等で可変にするなども検討できます。
19-47:aiServiceConfigの各サービス設定がまとめられています。
custom-apiの箇所がnullを返しているため、利用側でのエラーハンドリングや代替処理が必要かもしれません。createOpenAIやcreateCohereなどの部分は共通化できる部分があれば抽象化を検討できます。
93-138:generateAiText関数がバッチテキスト生成を行う設計を確認しました。
- エラー時に JSON 形式で
errorCodeを返しており、フロントエンドでのハンドリングもしやすいでしょう。generateText呼び出し前後に付加的なバリデーションが必要なら、次のステップで追加実装が可能です。src/hooks/useVoiceRecognition.ts (6)
9-11:UseVoiceRecognitionProps型が明快で、コールバック引数のみを受け取る形にするアプローチがよいです。
追加入力パラメータが増える可能性がある場合は、拡張性を考えPartial等を検討してもよいでしょう。
20-25: 音声認識モードや関連設定の取得が、settingsStoreから明示的に行われています。
設定項目数が増える場合、ネストを深めずに複数のuseStore呼び出しを小分けにするとテストや型チェックがしやすい場合もあります。
37-44:currentHookの条件分岐が多段になっていますが、読みやすい範囲です。
speechRecognitionModeとrealtimeAPIModeの組み合わせが増える場合、マッピングテーブル方式も検討するとスッキリする可能性があります。
46-48: 音声停止のコールバックが小さくまとめられています。
すぐに停止できるようにシンプルな関数にしておくのは利点ですが、同時にストップ時の後処理ロジックがある場合、追加で呼び出す仕組みが必要になるかもしれません。
96-128: マイク自動起動のタイミングをコンポーネントマウント時に限定している点が明確です。
- コンポーネント再マウントが頻繁に起きる場合は、不要なリスニング開始が重ならないよう注意してください。
130-169: Altキーによる音声入力制御の実装が斬新で利便性が高そうです。
- 無意識のAltキー押下を想定して、誤送信を防ぐ仕組み(長押しなど)を今後検討しても良いかもしれません。
src/hooks/useSilenceDetection.ts (2)
67-77: 無音継続時間の計測ロジック
silenceDurationの計算・比較が明確で可読性も高いです。ただしログが増える場合は本番運用での負荷にも注意が必要です。
79-122: 長時間無音検出時の処理が細かく制御されています
タイムアウトの扱い、フラグ設定、stopListeningFn呼び出しの例外処理など、包括的に扱われています。処理フローがやや長いので、適度な関数分割による整理を検討しても良いでしょう。src/components/settings/speechInput.tsx (1)
38-46: モード制御ロジックの追加説明を検討
realtimeAPIModeまたはaudioModeが有効時にspeechRecognitionModeを強制上書きするロジックについて、UI上に説明や注釈がないとユーザーが混乱する可能性があります。切り替え不可の理由をUIやドキュメントに明記すると、ユーザー体験が向上します。src/components/chatLog.tsx (1)
32-33: レイアウト縮小の影響を確認
pb-16やpx-4 pt-24 pb-16への変更はチャットログ下部や左右余白を大幅に減らすものです。長文メッセージや複数画像を含む場合にスクロールの挙動がどう変化するか、視認性を再度確認してください。website/document/zh/guide/character/common.md (1)
16-29: 複数プリセット設定の操作ガイド追加を検討新しく追加された5つの字元預設変数 (
NEXT_PUBLIC_CUSTOM_PRESET_NAME1~5,NEXT_PUBLIC_CHARACTER_PRESET1~5) の内容や使い方を簡潔にまとめた手順・例があると、利用者がセットアップしやすくなります。src/pages/api/whisper.ts (2)
16-18: HTTPメソッド制限の明示的な例外処理405エラーを返す実装は適切ですが、もし将来的にGETリクエストでステータス確認やアップロードフォームを返す必要がある場合、
res.setHeader('Allow','POST')などの対応も考慮できるとより安全です。
121-138: 大容量音声ファイルのアップロードに対する制限
getRawBodyで受け取るデータサイズに上限がなさそうなので、大容量ファイルをアップロードされた場合、メモリの急激な消費が懸念されます。必要に応じてファイルサイズ上限の設定やストリーミング処理の導入をご検討ください。src/features/messages/speakCharacter.ts (3)
40-50: 記号のみで構成される文字列を排除する実装は妥当です。
大きめの正規表現を使用しているため、パフォーマンスが気になるケースがあれば最適化を検討しても良いかもしれません。
83-85:(!processedMessage && !talk.buffer) returnの分岐にログ検討も可能です。
早期リターンによって空のメッセージを抑止できますが、必要に応じてログ出力やユーザ通知があってもよいかもしれません。
90-104:.thenチェーンをasync/awaitに置き換えると可読性が向上する可能性があります。
同等の機能を保ちながら、より一貫したエラーハンドリングやフロー可読性が得られます。下記のような差分を参考にリファクタ可能です:
- asyncConvertEnglishToJapaneseReading(processedMessage) - .then((convertedText) => { - talk.message = convertedText - }) - .catch((error) => { - console.error('Error converting English to Japanese:', error) - }) + try { + const convertedText = await asyncConvertEnglishToJapaneseReading(processedMessage) + talk.message = convertedText + } catch (error) { + console.error('Error converting English to Japanese:', error) + }src/components/messageInputContainer.tsx (1)
32-41:toggleContinuousModeで常時マイク入力をオン/オフする実装はシンプルで理解しやすいです。
一方でwhisperモードの際は何も行わないため、ユーザーに対して切り替え不可を示すUI対応も検討の余地があります。src/features/chat/vercelAIChat.ts (1)
239-242: 不要なcontinueの削除を要検討
else ifチェーン内にあるため、ここでのcontinueは冗長となり処理結果に差がない可能性があります。下記パッチ適用により
continueを除去し、可読性を向上できます。動作影響がないかご確認ください。} else if (line.match(/^[a-z]:/)) { // "e:", "d:"などの形式のメタデータ行をスキップ - continue } else if (line.trim() !== '') { ...src/components/settings/voice.tsx (3)
22-22: 不要なimportのコメントアウト
使用しなくなったimportをコメントアウトしている点は適切です。最終的に不要なら削除も検討するとよいでしょう。
74-74: AIVISスピーカーのState管理
speakers_aivisをStateフックで管理するのは良いアプローチです。型定義をArray<any>からより具体的にすると、メンテナンス性が向上します。
94-103: AIVISスピーカー一覧取得関数
fetchAivisSpeakersでのエラー処理を含めた実装は適切です。ユーザーへのエラー表示やリトライ機構なども将来的に検討できます。website/document/guide/other/advanced-settings.md (1)
63-65: 質問の表示/非表示切り替えの説明が適切です。
こちらも「〜ことができます」の重複表現が若干多めなので、読みやすさ向上のために修正を検討いただくと良いでしょう。🧰 Tools
🪛 LanguageTool
[uncategorized] ~65-~65: 「ことができる」という表現は冗長な可能性があります。
Context: ...変更できます ### 表示/非表示の切り替え 質問の表示/非表示を切り替えることができます。この機能を使用しない場合は、このオプションをオフにすることでUIをシンプル...(DOUSI_KOTOGADEKIRU)
[uncategorized] ~65-~65: 「ことができる」という表現は冗長な可能性があります。
Context: ...この機能を使用しない場合は、このオプションをオフにすることでUIをシンプルに保つことができます。 環境変数: ```bash # プリセット質問の表示設定(t...(DOUSI_KOTOGADEKIRU)
website/document/en/guide/other/advanced-settings.md (1)
8-8: 設定リセットに関する説明が更新されています。リセット操作に関する警告メッセージが更新され、環境変数が設定されている場合の優先順位が明確化されています。ただし、静的解析ツールの指摘通り、カンマの追加を検討するとより読みやすくなります。
-When you perform a reset operation, all settings except conversation history will be restored to their default values, and the page will be reloaded. If environment variables are set, those values will take precedence. +When you perform a reset operation, all settings except conversation history will be restored to their default values, and the page will be reloaded. If environment variables are set, those values will take precedence.🧰 Tools
🪛 LanguageTool
[typographical] ~8-~8: Consider adding two commas here.
Context: ...When you perform a reset operation, all settings except conversation history will be restored to their default value...(UNLIKE_COMMA)
src/features/stores/settings.ts (1)
326-328: 条件式の簡略化が可能です。静的解析ツールが指摘しているように、boolean リテラルを使用した条件式は簡略化できます。
- showAssistantText: - process.env.NEXT_PUBLIC_SHOW_ASSISTANT_TEXT === 'true' ? true : false, - showCharacterName: - process.env.NEXT_PUBLIC_SHOW_CHARACTER_NAME === 'true' ? true : false, + showAssistantText: process.env.NEXT_PUBLIC_SHOW_ASSISTANT_TEXT === 'true', + showCharacterName: process.env.NEXT_PUBLIC_SHOW_CHARACTER_NAME === 'true',🧰 Tools
🪛 Biome (1.9.4)
[error] 326-326: Unnecessary use of boolean literals in conditional expression.
Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with(lint/complexity/noUselessTernary)
[error] 328-328: Unnecessary use of boolean literals in conditional expression.
Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with(lint/complexity/noUselessTernary)
🛑 Comments failed to post (10)
src/hooks/useRealtimeVoiceAPI.ts (2)
70-106: 🛠️ Refactor suggestion
WebSocket送信処理の冗長性に注意
sendTextToWebSocket内でwsManager?.websocket?.readyStateのチェック後に2回目のsendContent.length > 0チェックが入り、さらにJSON文字列生成を行うなど、if/elseブロックが複数存在しています。可読性と保守性を高めるために、早期returnや分岐簡素化でロジックをスリム化すると良いでしょう。
167-239: 🛠️ Refactor suggestion
stopListening内のリファクタを検討
stopListeningは複数ステップが混在しており、タイマークリア → 音声認識停止 → 音声処理 など多くのサブタスクを担っています。- 後半で鍵となる録音停止処理やバッファ変換、WebSocket送信が連続しているため、エラー補足が入り組んでいます。
- メソッドを分割してそれぞれの責務を明確化することで、将来的な変更に対応しやすくなるでしょう。
src/features/chat/handlers.ts (1)
313-313: 🛠️ Refactor suggestion
末尾でも同様のロジック重複
行313も同一パターンです。今後「surprised」以外にも感情が追加される場合、表記上の揺れを最小化するためにもユーティリティ化で一元的に処理することを強く推奨します。
src/components/settings/log.tsx (1)
28-28:
⚠️ Potential issueGridクラスが指定されていない可能性
Tailwind CSSで列レイアウトを指定するには、gridクラスを付与して"grid grid-cols-2"のように指定する必要があります。現状、grid-cols-2のみだとレイアウトが反映されない恐れがあります。下記のような修正をご検討ください。-<div className="mb-2 grid-cols-2"> +<div className="mb-2 grid grid-cols-2">📝 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.<div className="mb-2 grid grid-cols-2">src/pages/index.tsx (1)
56-89: 🛠️ Refactor suggestion
useEffectの依存配列に不足があります
useEffect内で使用している変数(characterPresetsとt)が依存配列に含まれていません。これにより、これらの変数が変更された際にキーボードイベントハンドラが古い値を参照し続ける可能性があります。
以下の修正を推奨します:
- }, []) + }, [characterPresets, t])📝 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.useEffect(() => { const handleKeyDown = (event: KeyboardEvent) => { if ((event.metaKey || event.ctrlKey) && event.shiftKey) { // shiftキーを押しながら数字キーを押すためのマッピング const keyMap: { [key: string]: number } = { Digit1: 1, Digit2: 2, Digit3: 3, Digit4: 4, Digit5: 5, } const keyNumber = keyMap[event.code] if (keyNumber) { settingsStore.setState({ systemPrompt: characterPresets[keyNumber - 1].value, }) toastStore.getState().addToast({ message: t('Toasts.PresetSwitching', { presetName: t(`Characterpreset${keyNumber}`), }), type: 'info', tag: `character-preset-switching`, }) } } } window.addEventListener('keydown', handleKeyDown) return () => { window.removeEventListener('keydown', handleKeyDown) } }, [characterPresets, t])src/hooks/useBrowserSpeechRecognition.ts (2)
58-94: 🛠️ Refactor suggestion
無音検出と初期化ロジックの集約を検討してください。
stopListening関数内でサイレンス検出や初期音声検出タイマーをクリアする処理が多重に実行されています。複数箇所で同様のクリア処理があるため、ロジックが煩雑化しやすいです。これらの初期化や停止処理を1つのヘルパーにまとめ、わかりやすく保守しやすい構造にすると良いでしょう。
126-154: 🛠️ Refactor suggestion
処理の再開・停止を State Machine で整理する案を検討ください。
startListening内でisListeningRef.currentをチェックしながらstop()→ 遅延 →start()という複雑なロジック分岐があります。状態管理をステートマシンやクリーンなフローチャートに落とし込むと、可読性・保守性の向上が見込めます。src/pages/api/services/customApi.ts (1)
18-21: 🛠️ Refactor suggestion
ストリーミングフラグの強制的な上書きについて検討が必要
20行目で
stream = trueとして強制的にストリーミングを有効にしていますが、この場合、パラメータとしてstreamを受け取る意味がなくなります。さらに、108-120行目の非ストリーミング処理部分が実行されなくなります。以下のいずれかの対応を検討してください:
- コメントと強制上書きを削除して、引数の
stream値を尊重するstreamパラメータを削除し、常にストリーミングモードで動作させるpackage.json (1)
33-33:
⚠️ Potential issue重複するドラッグ&ドロップライブラリの存在
@hello-pangea/dnd(18.0.1)とreact-beautiful-dnd(13.1.1)の両方が依存関係に含まれています。@hello-pangea/dndはreact-beautiful-dndのフォークであるため、両方を使用すると混乱やコンフリクトを引き起こす可能性があります。いずれか一方を選択し、コードベース全体で一貫して使用することをお勧めします。#!/bin/bash # ドラッグ&ドロップライブラリの使用状況をチェック echo "react-beautiful-dndの使用状況を確認:" rg -A 2 "from ['\"](react-beautiful-dnd|@hello-pangea/dnd)['\"]" --type tsx --type ts echo "インポートの競合を確認:" rg -e "import.*DragDropContext.*from" --type tsx --type tsAlso applies to: 39-39, 58-58
src/components/settings/character.tsx (1)
578-636: 🛠️ Refactor suggestion
キャラクタープリセットのタブ風UIをボタンで実装しています。
selectedPresetIndexの更新とトースト表示の組み合わせがユニークですが、連続クリックやすばやい切り替え時にもトーストが多重表示される可能性があります。- トーストの tag を活用し、古いトーストを上書きする等の工夫を加えるとUXが向上します。
新機能
ドキュメント
ライセンス
不具合
リファクタリング
Summary by CodeRabbit
新機能
- 音声認識・音声合成が強化され、ブラウザ認識とOpenAI TTSの切替、リアルタイムAPI対応が実現しました。
- キャラクタープリセットメニューや事前設定質問機能が追加され、感情表現に「surprised」が導入されました。
UI改善
- コンポーネントのレイアウト、パディング、マージンが調整され、操作性が向上。
- タッチジェスチャーの改善により、モバイルでの操作がより快適になりました。
ドキュメント
- 設定ガイドおよび翻訳文書が更新され、各機能や環境変数の説明が充実しました。
その他
- 依存関係の更新や内部処理の整理が実施され、全体のパフォーマンスが向上しました。