Skip to content
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

RealtimeAPI不具合修正 #209

Merged
merged 5 commits into from
Oct 27, 2024
Merged

Conversation

tegnike
Copy link
Owner

@tegnike tegnike commented Oct 27, 2024

Summary by CodeRabbit

  • 新機能

    • プロジェクトのライセンスと貢献ガイドラインを更新し、v2.0.0からのカスタムライセンスを導入。
    • 新しい言語を追加するための詳細な貢献手順を追加。
    • リアルタイムAPIに関連する新しい音声タイプと設定更新オプションを追加。
  • バグ修正

    • WebSocket接続のエラーハンドリングを改善。
  • ドキュメント

    • READMEファイルを更新し、ライセンスと使用条件の明確化。
    • 各言語のREADMEファイルを更新し、機能や設定に関する詳細を追加。

Copy link

vercel bot commented Oct 27, 2024

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
aituber-kit ✅ Ready (Inspect) Visit Preview 💬 Add feedback Oct 27, 2024 1:50pm

Copy link

coderabbitai bot commented Oct 27, 2024

Walkthrough

このプルリクエストでは、プロジェクトのREADMEファイルとローカライズファイルに関する重要な変更が行われています。READMEには、バージョンv2.0.0からのカスタムライセンスの導入と、商業利用に関するガイドラインが追加されました。また、多言語サポートに関する貢献ガイドラインが強化され、新しい言語を追加するための手順が詳細に説明されています。ローカライズファイルでは、リアルタイムAPIに関連する新しいエントリが追加され、WebSocket接続や音声データ処理に関する機能が強化されています。

Changes

ファイル 変更の概要
docs/README_en.md カスタムライセンスの導入、貢献ガイドラインの強化、新しい言語追加手順の詳細化。
docs/README_ko.md カスタムライセンスの導入、開発環境やAIキャラクターとの対話に関する詳細な手順の追加。
docs/README_zh.md カスタムライセンスの導入、商業利用に関するガイドラインの明確化。
locales/en/translation.json リアルタイムAPI機能に関連する新しいエントリの追加。
locales/ja/translation.json リアルタイムAPI設定および音声タイプに関する新しいエントリの追加。
locales/ko/translation.json リアルタイムAPI設定および音声タイプに関する新しいエントリの追加。
locales/zh/translation.json リアルタイムAPI設定および音声タイプに関する新しいエントリの追加。
src/components/realtimeAPIUtils.tsx WebSocket接続管理およびリアルタイムオーディオデータ処理に関する機能の追加。
src/components/settings/index.tsx フッターのテキスト内容の更新。
src/components/settings/modelProvider.tsx リアルタイムAPI関連の新しい設定の追加とWebSocket再接続のエラーハンドリングの強化。
src/components/settings/voice.tsx Azure TTSオプションの追加と構成の拡張。
src/components/useRealtimeAPI.tsx オーディオバッファ処理に関連する関数の削除とWebSocket管理の再構成。
src/features/chat/handlers.ts リアルタイムAPIモードに関する新しい条件分岐の追加。
src/features/constants/settings.ts リアルタイムAPIモードに関連する新しい型の追加。
src/features/stores/settings.ts 設定の型定義の強化と新しいプロパティの追加。

Possibly related PRs


🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

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)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

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: 13

🧹 Outside diff range and nitpick comments (4)
docs/README_en.md (1)

Line range hint 157-378: Realtime APIモードのドキュメント改善提案

Realtime APIモードのセクションについて、以下の改善を提案します:

  1. 機能の具体的なユースケース
  2. 関数実行の詳細な例
  3. トラブルシューティングガイド
  4. パフォーマンスに関する注意事項

以下のような内容の追加を検討してください:

### Realtime API Mode

- This is a mode where you can interact with the character with low latency using OpenAI's Realtime API.
- Function execution can be defined.

+#### Key Features
+- リアルタイムの音声認識と応答
+- カスタム関数の実行機能
+- 低レイテンシーな対話処理
+
+#### Performance Considerations
+- 推奨されるネットワーク帯域幅
+- メモリ使用量の目安
+- 同時接続数の制限
+
 #### Usage
 1. Select OpenAI or Azure OpenAI as the AI service.
 2. Turn on Realtime API mode.
 3. Use the microphone to talk to the character.
+4. 必要に応じて音声認識の設定を調整
+5. カスタム関数の動作確認
+
+#### Troubleshooting
+- 音声認識が機能しない場合の対処法
+- エラーメッセージの説明
+- よくある問題と解決方法
 
 #### Function Execution
 - Define new functions in src/components/realtimeAPITools.tsx and src/components/realtimeAPITools.json.
 - Refer to the existing get_current_weather function as an example.
+
+Example of a custom function:
+\`\`\`typescript
+{
+  "name": "get_current_weather",
+  "description": "天気情報を取得する関数",
+  "parameters": {
+    "type": "object",
+    "properties": {
+      "location": {
+        "type": "string",
+        "description": "天気を確認する場所"
+      }
+    },
+    "required": ["location"]
+  }
+}
+\`\`\`
src/components/realtimeAPIUtils.tsx (3)

156-160: console.log のメッセージを詳細化しましょう

エラーデータを受信した際のログメッセージが一般的です。受信したエラー内容を含めると、デバッグが容易になります。

 case 'error':
-  console.log('Received error data', jsonData)
+  console.error('Received error data:', jsonData)
  break

238-239: 条件式をわかりやすく整理しましょう

複雑な条件式は可読性を下げる可能性があります。条件を変数に分けることで、コードの読みやすさを向上させましょう。

const isAudioDeltaLarge =
  jsonData.type === 'response.audio.delta' &&
  accumulatedAudioDataRef.current?.buffer?.byteLength > 100_000
const isAudioDone = jsonData.type === 'response.audio.done'

-if (
-  (jsonData.type === 'response.audio.delta' &&
-    accumulatedAudioDataRef.current?.buffer?.byteLength > 100_000) ||
-  jsonData.type === 'response.audio.done'
-) {
+if (isAudioDeltaLarge || isAudioDone) {

115-119: トーストの削除処理を簡潔にしましょう

複数のトーストを削除する際、配列とループを使ってコードを簡潔にできます。

export function removeToast() {
- toastStore.getState().removeToast('websocket-connection-error')
- toastStore.getState().removeToast('websocket-connection-close')
- toastStore.getState().removeToast('websocket-connection-info')
+ const toastTags = [
+   'websocket-connection-error',
+   'websocket-connection-close',
+   'websocket-connection-info',
+ ]
+ toastTags.forEach((tag) => {
+   toastStore.getState().removeToast(tag)
+ })
}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 7fa9f8c and d32f018.

📒 Files selected for processing (15)
  • docs/README_en.md (2 hunks)
  • docs/README_ko.md (0 hunks)
  • docs/README_zh.md (0 hunks)
  • locales/en/translation.json (1 hunks)
  • locales/ja/translation.json (1 hunks)
  • locales/ko/translation.json (1 hunks)
  • locales/zh/translation.json (1 hunks)
  • src/components/realtimeAPIUtils.tsx (1 hunks)
  • src/components/settings/index.tsx (1 hunks)
  • src/components/settings/modelProvider.tsx (5 hunks)
  • src/components/settings/voice.tsx (1 hunks)
  • src/components/useRealtimeAPI.tsx (4 hunks)
  • src/features/chat/handlers.ts (1 hunks)
  • src/features/constants/settings.ts (1 hunks)
  • src/features/stores/settings.ts (4 hunks)
💤 Files with no reviewable changes (2)
  • docs/README_ko.md
  • docs/README_zh.md
✅ Files skipped from review due to trivial changes (1)
  • src/components/settings/index.tsx
🧰 Additional context used
🪛 Biome
src/components/realtimeAPIUtils.tsx

[error] 181-182: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

🔇 Additional comments (20)
src/features/constants/settings.ts (1)

60-60: 型の定義が適切です!

RealtimeAPIModeContentTypeの型定義は、入力形式を明確に制限しており、型安全性が確保されています。

locales/zh/translation.json (2)

145-145: 音声タイプの翻訳が追加されました

リアルタイムAPIモードの音声タイプ設定のための翻訳が適切に追加されています。


148-149: WebSocketセッション更新に関する重要な説明が追加されました

リアルタイムAPI設定の更新に関する重要な情報が追加されています。以下の点で適切な実装となっています:

  • 設定更新ボタンの説明が明確
  • 更新が必要なパラメータ(APIキー、Azureエンドポイント、音声タイプ、システムプロンプト)が具体的に列挙されている
  • WebSocketセッションの再開始に関する説明が含まれている

他の言語ファイルでも同様の変更が行われているか確認するスクリプトを実行します:

✅ Verification successful

Let me verify the content of these translation files to ensure consistency.


翻訳の整合性が確認できました

すべての言語ファイル(英語、日本語、韓国語、中国語)で以下の点が確認できました:

  • 各言語でUpdateRealtimeAPISettingsUpdateRealtimeAPISettingsInfoのキーが適切に実装されています
  • 翻訳の内容が一貫しており、各言語で同じ意味が正確に伝えられています
  • WebSocketセッションの更新に関する重要な情報が、それぞれの言語で適切に表現されています
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# 説明: 他の言語ファイルでも同じキーが追加されているか確認します

echo "各言語ファイルでの新規キーの存在確認:"
for key in "RealtimeAPIModeVoice" "UpdateRealtimeAPISettings" "UpdateRealtimeAPISettingsInfo"; do
  echo "キー: $key"
  rg -l "\"$key\":" locales/
done

Length of output: 1219


Script:

#!/bin/bash
# 各言語ファイルの該当キーの内容を確認
for key in "UpdateRealtimeAPISettings" "UpdateRealtimeAPISettingsInfo"; do
  echo "キー: $key の各言語での内容:"
  echo "-----------------------------------"
  for lang in en ja ko zh; do
    echo "$lang:"
    rg "\"$key\":" "locales/$lang/translation.json" -A 1
    echo
  done
done

Length of output: 2850

locales/ja/translation.json (2)

146-146: 翻訳の追加を承認

「ボイスタイプ」という訳語は適切で、UIの一貫性が保たれています。


149-150: 設定更新に関する翻訳の追加を承認

設定更新に関する翻訳が追加され、ユーザーに対して明確な指示が提供されています。WebSocketセッションの再開始に関する説明も適切に含まれています。

以下の点について確認をお願いします:

  • この変更に関連して、エラーメッセージやトースト通知の翻訳も必要ではないでしょうか
  • 設定更新後のフィードバックメッセージの翻訳も必要かもしれません
✅ Verification successful

WebSocket関連のエラーメッセージと通知の翻訳は既に完備されています

検証の結果、以下の翻訳が既に実装されていることを確認しました:

  • WebSocket接続に関するトースト通知
    • 接続エラー
    • 接続終了
    • 接続試行中
    • 接続成功
  • 一般的なエラーメッセージ
    • APIエラー
    • TTSサービスエラー
    • 実行失敗通知

設定更新に関する翻訳は適切に実装されており、関連するエラーメッセージや通知も十分にカバーされています。追加の翻訳は必要ありません。

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# 関連するエラーメッセージやトースト通知の翻訳の有無を確認
rg "RealtimeAPI.*Error|UpdateRealtimeAPI.*Failed" locales/

Length of output: 60


Script:

#!/bin/bash
# エラーメッセージやトースト通知に関連する翻訳を広く検索
rg -i "realtime.*api|websocket" locales/ja/translation.json -A 2 -B 2

Length of output: 1040


Script:

#!/bin/bash
# 設定更新関連のメッセージを検索
rg -i "update.*settings?|settings?.*updated" locales/ja/translation.json -A 2 -B 2

Length of output: 349


Script:

#!/bin/bash
# エラー関連の翻訳を検索
rg -i "error|failed|failure" locales/ja/translation.json -A 2 -B 2

Length of output: 1107

locales/ko/translation.json (2)

145-145: 音声タイプの翻訳が追加されました

翻訳の追加は適切で、既存の韓国語のトーンと一貫性が保たれています。


148-149: リアルタイムAPI設定の更新に関する翻訳が追加されました

翻訳は明確で、ユーザーに必要なアクションを適切に伝えています。WebSocketセッションの更新に関する技術的な説明も正確に翻訳されています。

以下の点について確認をお願いします:

  • 他の言語ファイル(en/ja/zh)でも同様の翻訳が追加されているか
  • 翻訳キーが他の言語ファイルと完全に一致しているか
✅ Verification successful

リアルタイムAPI設定の翻訳キーの検証が完了しました

検証結果:

  • すべての言語ファイル(en/ja/zh/ko)で必要な翻訳キーが存在することを確認
  • 各言語で翻訳の内容が適切に対応していることを確認
  • 翻訳キーの命名規則が統一されていることを確認
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# 他の言語ファイルで同じキーが存在するか確認
for lang in en ja zh; do
  echo "Checking ${lang} translation..."
  rg "RealtimeAPIModeVoice|UpdateRealtimeAPISettings|UpdateRealtimeAPISettingsInfo" "locales/${lang}/translation.json"
done

Length of output: 1256

src/features/stores/settings.ts (2)

12-13: 型の定義が適切に更新されています!

RealtimeAPIModeContentTypeRealtimeAPIModeVoiceの型を導入することで、型安全性が向上し、実行時エラーを防ぐことができます。

Also applies to: 96-97


274-274: 永続化の設定を確認してください

realtimeAPIModeVoiceの状態が正しく永続化されていることを確認してください。特に以下の点に注意が必要です:

  • アプリケーションのリロード後も設定が保持されること
  • 初期値が正しく反映されること
✅ Verification successful

Let me gather more information about the persistence implementation.


Let me check one more aspect of the persistence implementation to ensure completeness.


Based on the previous results, I can now provide the final response:

realtimeAPIModeVoiceの永続化は適切に実装されています

  • 初期値は環境変数NEXT_PUBLIC_REALTIME_API_MODE_VOICEから設定され、デフォルト値は'shimmer'です
  • stateのpartialize関数で正しく永続化対象として含まれています
  • 型定義とstore実装の整合性が取れています
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# 永続化に関連するファイルの検索
rg -l "realtimeAPIModeVoice" --type ts

Length of output: 148


Script:

#!/bin/bash
# Check the persistence implementation in settings store
rg "realtimeAPIModeVoice" src/features/stores/settings.ts -C 5

# Check the initial state definition
ast-grep --pattern 'const initialState = {
  $$$
}'  src/features/stores/settings.ts

Length of output: 1432


Script:

#!/bin/bash
# Check the store creation and persistence setup
rg "create\(" src/features/stores/settings.ts -A 10

# Check the type definition
ast-grep --pattern 'type $_ = {
  $$$
  realtimeAPIModeVoice: $_
  $$$
}'

Length of output: 129

locales/en/translation.json (2)

145-145: 音声タイプの選択オプションが適切に追加されています

RealtimeAPIモードでの音声タイプ選択機能が正しく実装されており、UIの一貫性が保たれています。


148-149: WebSocketセッション管理の改善提案

設定更新時のWebSocketセッション再接続に関する説明文が追加されていますが、以下の点について確認・改善をお願いします:

  1. ユーザーが設定を変更した際に、自動的にWebSocketセッションを再接続する仕組みの実装を検討してください
  2. 設定更新ボタンを押し忘れた場合のフォールバック処理や警告メッセージの追加を推奨します

以下のスクリプトで関連する実装を確認します:

docs/README_en.md (2)

157-157: セクション区切りの一貫性について

スライドモードセクションの後の空行は、ドキュメントの構造を明確にする上で適切です。他のセクションでも同様の区切りを維持することを推奨します。


378-378: ファイル末尾の空行について

ファイル末尾の空行は、多くのエディタで推奨される標準的なプラクティスに従っています。

src/components/settings/voice.tsx (1)

227-227: スタイリングの改善を承認!

VoiceVoxの設定セクションにfont-boldクラスを追加することで、視覚的な階層構造が改善され、他のセクションとの一貫性が保たれています。

src/components/useRealtimeAPI.tsx (4)

6-13: 必要なインポートが追加されています

./realtimeAPIUtilsからの機能や型のインポートが適切に追加されています。コードの再利用性と保守性が向上しています。


48-48: セッション更新の送信が適切に行われています

WebSocket接続が開かれた際にsendSessionUpdate(ws)を呼び出しており、セッション情報の更新が適切に実装されています。


74-79: WebSocket接続の設定とメッセージハンドリングが適切です

setupWebsocket(t)を使用してWebSocketを設定し、handleMessage関数でメッセージを処理しています。リアルタイムなデータ処理が正しく構成されています。


77-78: handleMessageの呼び出しにおける引数の順序と型を確認してください

handleMessage関数に渡している引数が正しい順序と型であることを確認してください。特に、ws!tの順序や必要性を再確認してください。

必要であれば、関数シグネチャを確認し、適切な引数の順序を提案することができます。

src/components/realtimeAPIUtils.tsx (2)

293-343: WebSocket 再接続のロジックが適切です

reconnectWebSocket 関数では、WebSocket の再接続処理が適切に実装されています。イベントリスナーの設定と状態管理が正しく行われています。


221-231: ⚠️ Potential issue

エラーハンドリングを強化しましょう

JSON.parse 中にエラーが発生した場合、ユーザーに適切なフィードバックを提供するためにトースト通知を確実に表示しましょう。

} catch (error) {
  console.error('Error parsing function arguments:', error)
  if (toastId) {
    toastStore.getState().removeToast(toastId)
  }
- toastId = toastStore.getState().addToast({
+ toastStore.getState().addToast({
    message: t('Toasts.FunctionExecutionFailed', { funcName }),
    type: 'error',
    duration: 3000,
    tag: `run-${funcName}`,
  })
}

Likely invalid or redundant comment.

@@ -56,3 +56,6 @@ export type OpenAITTSVoice =
| 'nova'
| 'shimmer'
export type OpenAITTSModel = 'tts-1' | 'tts-1-hd'

export type RealtimeAPIModeContentType = 'input_text' | 'input_audio'
export type RealtimeAPIModeVoice = 'alloy' | 'echo' | 'shimmer'
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

既存の型定義の再利用を推奨します

RealtimeAPIModeVoiceで定義されている音声オプションは、既にOpenAITTSVoice型に含まれています。コードの重複を避けるため、以下のようなリファクタリングを提案します。

-export type RealtimeAPIModeVoice = 'alloy' | 'echo' | 'shimmer'
+export type RealtimeAPIModeVoice = Extract<OpenAITTSVoice, 'alloy' | 'echo' | 'shimmer'>

この変更により:

  • コードの重複が解消されます
  • OpenAITTSVoice型との一貫性が保たれます
  • 将来的な保守性が向上します

Committable suggestion was skipped due to low confidence.

Comment on lines +213 to +219
(process.env
.NEXT_PUBLIC_REALTIME_API_MODE_CONTENT_TYPE as RealtimeAPIModeContentType) ||
'input_text',
realtimeAPIModeVoice:
(process.env
.NEXT_PUBLIC_REALTIME_API_MODE_VOICE as RealtimeAPIModeVoice) ||
'shimmer',
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

環境変数の参照方法を改善することを推奨します

現在の実装は複数行に分かれており、可読性が低下しています。以下のようにリファクタリングすることで、コードの可読性が向上します。

-      realtimeAPIModeContentType:
-        (process.env
-          .NEXT_PUBLIC_REALTIME_API_MODE_CONTENT_TYPE as RealtimeAPIModeContentType) ||
-        'input_text',
-      realtimeAPIModeVoice:
-        (process.env
-          .NEXT_PUBLIC_REALTIME_API_MODE_VOICE as RealtimeAPIModeVoice) ||
-        'shimmer',
+      realtimeAPIModeContentType: (process.env.NEXT_PUBLIC_REALTIME_API_MODE_CONTENT_TYPE as RealtimeAPIModeContentType) || 'input_text',
+      realtimeAPIModeVoice: (process.env.NEXT_PUBLIC_REALTIME_API_MODE_VOICE as RealtimeAPIModeVoice) || 'shimmer',
📝 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.

Suggested change
(process.env
.NEXT_PUBLIC_REALTIME_API_MODE_CONTENT_TYPE as RealtimeAPIModeContentType) ||
'input_text',
realtimeAPIModeVoice:
(process.env
.NEXT_PUBLIC_REALTIME_API_MODE_VOICE as RealtimeAPIModeVoice) ||
'shimmer',
realtimeAPIModeContentType: (process.env.NEXT_PUBLIC_REALTIME_API_MODE_CONTENT_TYPE as RealtimeAPIModeContentType) || 'input_text',
realtimeAPIModeVoice: (process.env.NEXT_PUBLIC_REALTIME_API_MODE_VOICE as RealtimeAPIModeVoice) || 'shimmer',

Comment on lines +399 to +409
} else if (ss.realtimeAPIMode) {
if (hs.ws?.readyState === WebSocket.OPEN) {
// ユーザーの発言を追加して表示
const updateLog: Message[] = [
...hs.chatLog,
{ role: 'user', content: newMessage },
]
homeStore.setState({
chatLog: updateLog,
})
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

RealtimeAPIモードの実装が不完全です

以下の問題点が見られます:

  1. WebSocket接続が閉じている場合のエラーハンドリングが実装されていません
  2. チャットログの更新のみで、実際のAPI通信処理が実装されていません
  3. 他のモード(webSocketModeなど)と比較して、実装パターンに一貫性がありません

以下のような実装を提案します:

 } else if (ss.realtimeAPIMode) {
   if (hs.ws?.readyState === WebSocket.OPEN) {
     // ユーザーの発言を追加して表示
     const updateLog: Message[] = [
       ...hs.chatLog,
       { role: 'user', content: newMessage },
     ]
     homeStore.setState({
       chatLog: updateLog,
     })
+    
+    // RealtimeAPI通信処理
+    try {
+      hs.ws.send(JSON.stringify({
+        content: newMessage,
+        type: 'realtime_chat'
+      }))
+    } catch (error) {
+      console.error('RealtimeAPI通信エラー:', error)
+      homeStore.setState({
+        assistantMessage: errors['APIError'],
+        chatProcessing: false
+      })
+    }
+  } else {
+    homeStore.setState({
+      assistantMessage: errors['NotConnectedToExternalAssistant'],
+      chatProcessing: false
+    })
   }
📝 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.

Suggested change
} else if (ss.realtimeAPIMode) {
if (hs.ws?.readyState === WebSocket.OPEN) {
// ユーザーの発言を追加して表示
const updateLog: Message[] = [
...hs.chatLog,
{ role: 'user', content: newMessage },
]
homeStore.setState({
chatLog: updateLog,
})
}
} else if (ss.realtimeAPIMode) {
if (hs.ws?.readyState === WebSocket.OPEN) {
// ユーザーの発言を追加して表示
const updateLog: Message[] = [
...hs.chatLog,
{ role: 'user', content: newMessage },
]
homeStore.setState({
chatLog: updateLog,
})
// RealtimeAPI通信処理
try {
hs.ws.send(JSON.stringify({
content: newMessage,
type: 'realtime_chat'
}))
} catch (error) {
console.error('RealtimeAPI通信エラー:', error)
homeStore.setState({
assistantMessage: errors['APIError'],
chatProcessing: false
})
}
} else {
homeStore.setState({
assistantMessage: errors['NotConnectedToExternalAssistant'],
chatProcessing: false
})
}

@@ -224,7 +224,7 @@ const Voice = () => {
{t('TestVoice')}
</TextButton>
</div>
<div className="my-24">
<div className="my-24 font-bold">
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Azure TTSの実装に関する重要な問題

現在の実装には以下の問題があります:

  1. OpenAI TTSのstate(openaiTTSVoice、openaiTTSModel、openaiTTSSpeed)を誤って再利用しています
  2. Azure固有の音声オプションが実装されていません
  3. UIの構造が一貫していません

以下の修正を提案します:

- const openaiTTSVoice = settingsStore((s) => s.openaiTTSVoice)
- const openaiTTSModel = settingsStore((s) => s.openaiTTSModel)
- const openaiTTSSpeed = settingsStore((s) => s.openaiTTSSpeed)
+ const azureTTSVoice = settingsStore((s) => s.azureTTSVoice)
+ const azureTTSSpeed = settingsStore((s) => s.azureTTSSpeed)

// Azureセクション内で
- <select
-   value={openaiTTSVoice}
-   onChange={(e) =>
-     settingsStore.setState({
-       openaiTTSVoice: e.target.value as OpenAITTSVoice,
-     })
-   }
+ <select
+   value={azureTTSVoice}
+   onChange={(e) =>
+     settingsStore.setState({
+       azureTTSVoice: e.target.value as AzureTTSVoice,
+     })
+   }
  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>
+   <option value="ja-JP-NanamiNeural">Nanami (女性)</option>
+   <option value="ja-JP-KeitaNeural">Keita (男性)</option>
+   <option value="ja-JP-AoiNeural">Aoi (女性)</option>
</select>

- <div className="mt-16 font-bold">{t('OpenAITTSModel')}</div>

- <div className="mt-16 font-bold">
-   {t('OpenAITTSSpeed')}: {openaiTTSSpeed}
+ <div className="mt-16 font-bold">
+   {t('AzureTTSSpeed')}: {azureTTSSpeed}
</div>
<input
  type="range"
  min={0.25}
  max={4.0}
  step={0.01}
-  value={openaiTTSSpeed}
+  value={azureTTSSpeed}
  className="mt-8 mb-16 input-range"
  onChange={(e) => {
    settingsStore.setState({
-     openaiTTSSpeed: Number(e.target.value),
+     azureTTSSpeed: Number(e.target.value),
    })
  }}
/>

また、以下の型定義の追加も必要です:

export type AzureTTSVoice =
  | 'ja-JP-NanamiNeural'
  | 'ja-JP-KeitaNeural'
  | 'ja-JP-AoiNeural'

Also applies to: 590-676

Comment on lines +11 to +16
import {
RealtimeAPIModeContentType,
RealtimeAPIModeVoice,
} from '@/features/constants/settings'
import toastStore from '@/features/stores/toast'
import { sendSessionUpdate } from '@/components/realtimeAPIUtils'
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

新しい状態管理とWebSocket関連の実装について

新しく追加されたRealtimeAPI関連の実装について、以下の改善を提案します:

  1. WebSocketインスタンスの型安全性が確保されていません
  2. 状態管理の初期値が明示的に設定されていません

以下の修正を提案します:

+// WebSocket型の定義
+type CustomWebSocket = WebSocket & {
+  // 必要に応じて追加のプロパティを定義
+};

-const ws = homeStore((s) => s.ws)
+const ws = homeStore((s) => s.ws as CustomWebSocket | null)

+// 初期状態の設定
+const initialState = {
+  realtimeAPIModeVoice: 'alloy' as RealtimeAPIModeVoice,
+  // 他の初期値
+};

Also applies to: 25-25, 45-46

Comment on lines +39 to +40
// chatLogを空配列に初期化
homeStore.setState({ ws: ws, chatLog: [] })
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

chatLogの初期化に注意が必要です

handleOpen関数内でchatLogを空の配列に初期化していますが、これにより既存のチャット履歴が失われる可能性があります。WebSocket接続が再確立されるたびにチャット履歴がリセットされることは、ユーザーエクスペリエンスに影響を与える可能性があります。必要に応じて、chatLogの初期化を再検討してください。

Comment on lines +96 to +110
ws = setupWebsocket(t)
if (ws) {
ws.addEventListener('open', handleOpen)
ws.addEventListener('message', (event) =>
handleMessage(
event,
accumulatedAudioDataRef,
processMessage,
ws!,
t
)
)
ws.addEventListener('error', handleError)
ws.addEventListener('close', handleClose)
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

⚠️ Potential issue

再接続ロジックの改善を検討してください

再接続時に新しいWebSocket接続を設定していますが、イベントリスナーの重複登録に注意が必要です。再接続ごとにイベントリスナーを追加しているため、同一のリスナーが複数回登録され、予期しない動作を引き起こす可能性があります。イベントリスナーを登録する前に、既存のリスナーを適切に削除するか、再接続時に新しいWebSocketインスタンスを作成する方法を検討してください。

修正案として、再接続時に古いWebSocketのイベントリスナーをクリアし、新しい接続に対してリスナーを再登録することを提案します。

ws.close()
+ ws.removeEventListener('open', handleOpen)
+ ws.removeEventListener('message', messageHandler)
+ ws.removeEventListener('error', handleError)
+ ws.removeEventListener('close', handleClose)
ws = setupWebsocket(t)
if (ws) {
-   ws.addEventListener('open', handleOpen)
+   ws.addEventListener('open', handleOpen)
+   const messageHandler = (event) =>
+     handleMessage(event, accumulatedAudioDataRef, processMessage, ws!, t)
+   ws.addEventListener('message', messageHandler)
    ws.addEventListener('error', handleError)
    ws.addEventListener('close', handleClose)
}

この修正の実装について、さらにサポートが必要な場合はお知らせください。

Committable suggestion was skipped due to low confidence.

Comment on lines +181 to +182
if (jsonData.part && jsonData.part.transcript) {
await processMessage({
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

オプショナルチェイニングを使用してコードを簡潔にしましょう

jsonData.partjsonData.part.transcript の存在チェックをオプショナルチェイニングで簡潔に表現できます。

-if (jsonData.part && jsonData.part.transcript) {
+if (jsonData.part?.transcript) {
📝 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.

Suggested change
if (jsonData.part && jsonData.part.transcript) {
await processMessage({
if (jsonData.part?.transcript) {
await processMessage({
🧰 Tools
🪛 Biome

[error] 181-182: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

Comment on lines +301 to +305
const newWs = setupWebsocket(t)
if (newWs) {
newWs.addEventListener('open', (event) => {
console.log('WebSocket connection opened:', event)
removeToast()
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

setupWebsocketnull を返す場合の処理を追加しましょう

setupWebsocket 関数が null を返す可能性がありますが、その場合のエラーハンドリングがありません。接続に失敗した場合のユーザーへの通知を追加しましょう。

const newWs = setupWebsocket(t)
-if (newWs) {
+if (newWs !== null) {
  newWs.addEventListener('open', (event) => {
    // 既存のコード
  })
+} else {
+  console.error('Failed to establish WebSocket connection.')
+  toastStore.getState().addToast({
+    message: t('Toasts.WebSocketConnectionFailed'),
+    type: 'error',
+    duration: 5000,
+    tag: 'websocket-connection-failed',
+  })
}
📝 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.

Suggested change
const newWs = setupWebsocket(t)
if (newWs) {
newWs.addEventListener('open', (event) => {
console.log('WebSocket connection opened:', event)
removeToast()
const newWs = setupWebsocket(t)
if (newWs !== null) {
newWs.addEventListener('open', (event) => {
console.log('WebSocket connection opened:', event)
removeToast()
} else {
console.error('Failed to establish WebSocket connection.')
toastStore.getState().addToast({
message: t('Toasts.WebSocketConnectionFailed'),
type: 'error',
duration: 5000,
tag: 'websocket-connection-failed',
})
}

Comment on lines +28 to +29
;(wsConfig.session as any).tools = realtimeAPIToolsConfig
;(wsConfig.session as any).tool_choice = 'auto'
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

as any の使用を避けて型安全性を向上させましょう

wsConfig.session に対して as any を使用していますが、session の型を適切に定義することで、as any を避けることができます。これにより、型安全性が高まり、将来的なバグを防止できます。

// Session 型を定義します
interface SessionConfig {
  modalities: string[];
  instructions: string;
  voice: string;
  input_audio_format: string;
  output_audio_format: string;
  input_audio_transcription: {
    model: string;
  };
  turn_detection: null;
  temperature: number;
  max_response_output_tokens: number;
  // ↓ 追加
+ tools?: typeof realtimeAPIToolsConfig;
+ tool_choice?: string;
}

// wsConfig の型を SessionConfig を使用して更新します
const wsConfig = {
  type: 'session.update',
  session: {
    // 既存のプロパティ...
+   tools: realtimeAPIToolsConfig,
+   tool_choice: 'auto',
  } as SessionConfig,
};

-;(wsConfig.session as any).tools = realtimeAPIToolsConfig
-;(wsConfig.session as any).tool_choice = 'auto'

Committable suggestion was skipped due to low confidence.

@tegnike tegnike merged commit 60037bb into develop Oct 27, 2024
3 checks passed
@coderabbitai coderabbitai bot mentioned this pull request Oct 27, 2024
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.

1 participant