AIスタックチャン機能 - #302
Conversation
ec6d28d to
1e5021b
Compare
|
すみません、modの本体コミット漏れていたので追加しました |
meganetaaan
left a comment
There was a problem hiding this comment.
まだ実機で動作確認できていませんが、 testを使ってSTTは確認できました。
I/Fと実装で気になった点をコメントしました。
はい!ご認識のとおり、長期的には録音+STTを同時に行うメソッドを1個用意したいと考えています。というのも、レビューコメントにもあるとおり一旦bufferへの保存を挟まずに直接STTサーバに送れるとメモリ効率が格段によくなるためです。
class Robot {
async listen(void): Promise<Maybe<string>> () {}
} |
|
@meganetaaan メモリ効率と他に録音が必要な機能のために録音周りは、ちょうどECMA-419のAudioInが公開されたので、これを適用時に整理はしたいですね。
これを実現しようと思うとSTTをTTS同様にrobotに登録した方が良さそうでしょうか。 |
|
中長期的な対応項目はありますがひとまず指摘対応ができたので、draftはずして 🐇 レビューにかけてみます |
WalkthroughThe changes introduce several new files and modifications to the firmware's structure, particularly focusing on audio input and transcription functionalities. A new Changes
Possibly related PRs
Suggested reviewers
Poem
Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? 🪧 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.
Actionable comments posted: 10
🧹 Outside diff range and nitpick comments (21)
firmware/stackchan/transcriptions/manifest_transcription.json (3)
2-6: LGTM! Consider adding comments for clarity.The "include" section appropriately references necessary manifest files for UUID functionality, data headers, and TCP fetch capabilities, which are relevant for a transcription module.
Consider adding brief comments to explain the purpose of each included manifest file for better maintainability:
"include": [ - "$(MODDABLE)/modules/base/uuid/manifest.json", - "$(MODDABLE)/modules/data/headers/manifest.json", - "$(MODDABLE)/examples/io/tcp/fetch/manifest_fetch.json" + "$(MODDABLE)/modules/base/uuid/manifest.json", // For generating unique identifiers + "$(MODDABLE)/modules/data/headers/manifest.json", // For handling data headers + "$(MODDABLE)/examples/io/tcp/fetch/manifest_fetch.json" // For network operations ],
7-9: LGTM! Consider more specific module inclusion if needed.The "modules" section efficiently includes all modules from the current directory, providing flexibility for future additions.
If not all files in the directory are meant to be modules, consider using a more specific pattern or explicitly listing the required modules for better control:
"modules": { - "*": ["./*"] + "*": [ + "./stt-whisper", + "./other-module" + ] },
11-13: LGTM! Consider more granular data security configuration if needed.The "data" section appropriately specifies a cryptographic data path for all data entries, ensuring consistent security measures.
If different types of data require varying levels of security, consider a more granular configuration:
"data": { - "*": ["$(MODULES)/crypt/data/ca236"] + "sensitive_data": ["$(MODULES)/crypt/data/ca236"], + "public_data": ["$(MODULES)/data/public"] }firmware/tests/transcriptions/stt-whisper/manifest.json (5)
1-8: LGTM! Consider adding comments for clarity.The "include" section is well-structured and includes necessary manifest files for the project. It demonstrates a modular approach to configuration and includes type definitions, which is a good practice.
Consider adding comments to explain the purpose of each included manifest file, especially for project-specific ones like
manifest_utility.jsonandmanifest_transcription.json. This would improve readability and maintainability.
9-11: LGTM! Consider being more specific with module inclusion.The "modules" section correctly specifies the main module for this component.
If there are or might be multiple modules in the future, consider being more specific in module inclusion rather than using a wildcard. This can prevent unintended module inclusions and make the manifest more explicit about its dependencies.
17-19: LGTM! Consider specifying data inclusions more precisely.The "data" section includes necessary resources for the module's operation, including cryptographic data and a sample audio file.
- Consider being more specific with data inclusions rather than using a wildcard. This can prevent unintended file inclusions and make the manifest more explicit about its data dependencies.
- It might be beneficial to add a comment explaining the purpose of the
speak.wavfile (e.g., if it's a test sample).
20-22: LGTM! Consider enhancing token management and providing usage instructions.The "config" section correctly includes a placeholder for the API token, which is a good practice for security.
Consider the following enhancements:
- Add a comment explaining how to replace the placeholder with the actual API key securely.
- Consider using environment variables or a separate, gitignored configuration file for managing sensitive data like API keys.
- Provide instructions in the project's README on how to obtain and configure the API key for different environments (development, testing, production).
1-23: Overall, the manifest file is well-structured but could benefit from additional documentation and specificity.The manifest file provides a solid foundation for the STT Whisper module, incorporating necessary configurations and resources. It demonstrates good practices in modular design and security considerations.
To further improve the manifest:
- Add comments throughout the file to explain the purpose of each section and key configurations.
- Be more specific in module and data inclusions to prevent unintended inclusions and improve clarity.
- Enhance the README or create a separate CONTRIBUTING.md file with detailed instructions on how to set up and use this module, including API key management and any environment-specific configurations.
- Consider creating a schema for this manifest file to ensure consistency and catch potential errors early in the development process.
firmware/tests/transcriptions/stt-whisper/main.ts (3)
7-7: Consider making the audio file path configurable.The audio file path is currently hardcoded. To improve flexibility, consider making it configurable, either through a constant at the top of the file or as a parameter passed to the transcription function.
Example implementation:
const AUDIO_FILE_PATH = 'speak.wav'; // ... later in the code ... const audio = new Resource(AUDIO_FILE_PATH);
10-12: Add error handling for STT instance creation.While the STT instance creation looks correct, it's good practice to add error handling in case of initialization failures.
Consider wrapping the instance creation in a try-catch block:
let stt; try { stt = new STT({ apiKey: token, }); } catch (error) { trace(`Failed to initialize STT: ${error.message}`); // Handle the error appropriately, e.g., exit the process }
14-23: Consider how the transcription result will be used in a real application.Currently, the transcription result is only being logged. In a real application, you might want to process or return this result for further use.
Consider adding a function to handle the successful transcription result, for example:
function handleTranscriptionResult(transcription: string) { // Process the transcription, e.g., send it to another service, store it, etc. trace(`Processed transcription: ${transcription}`); } // In the try block: if (result.success === true) { handleTranscriptionResult(result.value); } else { // ... existing error handling ... }firmware/stackchan/manifest_microphone.json (1)
6-11: LGTM: Audio input configuration is appropriate for speech recognition.The sample rate (16kHz) and bit depth (16-bit) are well-suited for speech recognition tasks, aligning with common requirements for systems like OpenAI's Whisper.
Consider adding a comment to explain the rationale behind these audio settings, e.g.:
"defines": { "audioIn": { "sampleRate": 16000, // 16kHz, optimal for speech recognition "bitsPerSample": 16 // 16-bit, provides good audio quality for speech } }firmware/stackchan/manifest.json (1)
17-20: LGTM! Consider grouping related manifests.The additions of transcription and microphone manifests align well with the PR objectives. However, for better organization, consider grouping related manifests together. For example, you could move
./manifest_microphone.jsonnext to./transcriptions/manifest_transcription.json.firmware/stackchan/main.ts (2)
107-107: LGTM: Conditional microphone initialization.The microphone is correctly initialized only when the 'pins/audioin' module is available. This approach prevents errors on devices without microphone support.
Consider adding a comment explaining the purpose of this conditional initialization for better code readability:
// Initialize microphone only if audio input hardware is available const microphone = Modules.has('pins/audioin') ? new Microphone() : undefined
Line range hint
20-116: Overall assessment: Microphone support successfully integrated.The changes in this file effectively introduce microphone support to the project:
- The Microphone module is imported.
- Microphone initialization is conditionally performed based on hardware availability.
- The microphone is added to the Robot constructor.
These changes align well with the PR objectives and maintain compatibility with devices that may not have microphone support. The implementation is clean and well-integrated into the existing codebase.
As the project continues to evolve with new hardware capabilities, consider implementing a more modular approach for hardware initialization. This could involve creating a separate configuration file or using dependency injection to manage hardware dependencies, which would make it easier to add or remove hardware components in the future without modifying the main file.
firmware/stackchan/robot.ts (2)
254-259: LGTM with minor suggestion: record method added to Robot class.The record method is well-implemented, correctly handling the case where the microphone is not available and delegating the recording functionality to the microphone object. However, there's a minor issue to address:
The
durationSecparameter is defined but not used in the method implementation. Consider either:
- Removing the parameter if it's not needed, or
- Passing it to the microphone's record method if it should be used to control the recording duration.
Example fix:
- async record(durationSec?: number): Promise<ArrayBuffer> { + async record(): Promise<ArrayBuffer> { if (!this.#microphone) { throw Error('This device does not support a microphone.') } return this.#microphone.record() }Or, if the duration should be used:
async record(durationSec?: number): Promise<ArrayBuffer> { if (!this.#microphone) { throw Error('This device does not support a microphone.') } - return this.#microphone.record() + return this.#microphone.record(durationSec) }Please choose the appropriate option based on the intended functionality.
Line range hint
1-460: Overall assessment: Well-implemented microphone integration.The changes to integrate microphone functionality into the Robot class are well-structured and consistent with the existing codebase. The new features are added in a way that maintains backwards compatibility. The only minor suggestion is to address the unused
durationSecparameter in therecordmethod.Consider the following architectural advice for future improvements:
- If the microphone functionality becomes more complex, consider creating a separate
MicrophoneManagerclass to encapsulate all microphone-related operations.- In the future, you might want to add error handling for cases where the microphone fails during recording, not just when it's unavailable.
- As the Robot class grows, consider breaking it down into smaller, more focused classes to maintain separation of concerns.
firmware/stackchan/transcriptions/stt-whisper.ts (1)
32-32: Use correct MIME type for WAV file in multipart/form-dataCurrently, the
Content-Typefor the WAV file is set to'application/octet-stream'. Consider changing it to'audio/wav'to specify the correct MIME type for WAV files.Apply this diff:
'Content-Disposition: form-data; name="file"; filename="speak.wav"\r\n' + -'Content-Type: application/octet-stream\r\n\r\n' +'Content-Type: audio/wav\r\n\r\n'firmware/mods/ai_stackchan/mod.js (3)
64-64: Correct the comment typo: 'dace' to 'face'.There's a typo in the comment on line 64. It should be 'face' instead of 'dace'.
Apply this diff:
// set up thinking dace + // set up thinking face
81-81: Correct the comment typo: 'speeching' to 'speaking'.The comment on line 81 should use 'speaking' instead of 'speeching'.
Apply this diff:
// set up speeching face + // set up speaking face
95-95: Remove unnecessary return statement at the end of the function.The
returnstatement on line 95 at the end of thetalkfunction is unnecessary and can be safely removed.Apply this diff:
return - } + }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
⛔ Files ignored due to path filters (1)
firmware/tests/transcriptions/stt-whisper/speak.wavis excluded by!**/*.wav
📒 Files selected for processing (12)
- firmware/mods/ai_stackchan/manifest.json (1 hunks)
- firmware/mods/ai_stackchan/mod.js (1 hunks)
- firmware/stackchan/main.ts (3 hunks)
- firmware/stackchan/manifest.json (2 hunks)
- firmware/stackchan/manifest_microphone.json (1 hunks)
- firmware/stackchan/microphone.ts (1 hunks)
- firmware/stackchan/robot.ts (5 hunks)
- firmware/stackchan/transcriptions/manifest_transcription.json (1 hunks)
- firmware/stackchan/transcriptions/stt-whisper.ts (1 hunks)
- firmware/tests/transcriptions/stt-whisper/main.ts (1 hunks)
- firmware/tests/transcriptions/stt-whisper/manifest.json (1 hunks)
- firmware/tsconfig.json (1 hunks)
✅ Files skipped from review due to trivial changes (1)
- firmware/mods/ai_stackchan/manifest.json
🧰 Additional context used
🔇 Additional comments (18)
firmware/stackchan/transcriptions/manifest_transcription.json (2)
10-10: LGTM! Preloading STT module enhances performance.Preloading the "stt-whisper" module is a good practice for ensuring immediate availability of the speech-to-text functionality, which aligns with the PR objectives.
1-14: Overall, the manifest file is well-structured and aligns with the PR objectives.The
manifest_transcription.jsonfile effectively sets up the necessary configurations for the transcription module. It includes relevant dependencies, efficiently manages module inclusion, preloads the STT module for performance, and establishes data security measures. The suggestions provided in the review are minor improvements for clarity and potential future scalability.firmware/tests/transcriptions/stt-whisper/manifest.json (1)
12-16: LGTM! Async configuration is appropriate.The "defines" section correctly configures the main module to operate asynchronously, which is suitable for audio processing tasks.
firmware/tests/transcriptions/stt-whisper/main.ts (3)
1-8: LGTM: Imports and configuration setup look good.The import statements are appropriate, and the token check is a good practice to ensure the API key is properly set before proceeding.
14-23: LGTM: Comprehensive error handling and logging.The try-catch block and error handling for the transcription process are well-implemented. The use of strict equality for the success check and informative error messages are good practices.
1-23: Overall assessment: Well-implemented STT functionality with room for minor enhancements.The implementation of the STT functionality is solid, with good error handling and logging practices. The suggestions made (configurable audio file path, error handling for STT instance creation, and result processing) are minor enhancements that could improve the flexibility and real-world applicability of this code.
Great job on implementing this new feature! The code is clean, easy to understand, and follows good practices.
firmware/stackchan/manifest_microphone.json (3)
1-5: LGTM: Modules and preload configuration looks good.The configuration correctly sets up the microphone module for global access and preloading, which is appropriate for a core feature like audio input.
1-32: Overall, excellent configuration for audio input functionality.This manifest file provides a robust and flexible configuration for audio input, effectively supporting both hardware-specific implementations and simulated environments. It aligns well with the PR objectives for implementing Speech-to-Text (STT) functionality.
Key strengths:
- Appropriate audio settings for speech recognition tasks.
- Platform-specific configuration for ESP32/M5Stack Core2.
- Well-structured fallback configuration for simulation and testing.
The file demonstrates good practices in terms of modularity, cross-platform support, and development flexibility.
12-17: LGTM: Platform-specific configuration for ESP32/M5Stack Core2 looks correct.The configuration appropriately maps the audio input module to an ESP32-specific implementation, which is crucial for hardware-dependent functionality.
To ensure the specified module path is correct, please run the following verification script:
#!/bin/bash # Verify the existence of the ESP32 audio input module MODDABLE_PATH=$(grep MODDABLE= $HOME/.moddable/env.sh | cut -d'=' -f2) MODULE_PATH="$MODDABLE_PATH/modules/pins/audioin/esp32/audioin" if [ -d "$MODULE_PATH" ]; then echo "ESP32 audio input module found at: $MODULE_PATH" else echo "Warning: ESP32 audio input module not found at expected path: $MODULE_PATH" fifirmware/tsconfig.json (1)
27-27: LGTM: Path added for new transcriptions functionalityThe addition of
"./stackchan/transcriptions/*"to thepathsconfiguration is appropriate and aligns with the PR objectives. This change enables TypeScript to resolve modules in the newtranscriptionsdirectory, which is likely where the STT (Speech-to-Text) related files will be located.firmware/stackchan/manifest.json (2)
78-92: Approve memory allocation changes. Please clarify the significant increases.The memory allocation changes, particularly the increase in static memory from 110592 to 442368 bytes and the larger chunk sizes, seem appropriate for handling new audio processing features. However, could you provide more context on:
- The specific requirements driving these significant increases?
- Any potential impact on other system functionalities?
- Whether these changes have been tested for stability across different usage scenarios?
Line range hint
93-150: Verify impact on other platformsThe memory allocation changes are specific to the esp32/m5stack_core2 platform. To ensure consistency and prevent potential issues:
- Confirm that these changes don't negatively impact other platforms.
- Consider if similar adjustments are needed for other platforms, especially esp32/m5stack_cores3.
- Verify that the new features (STT, microphone) work correctly on all supported platforms with their current configurations.
✅ Verification successful
Verified: Changes are isolated to
esp32/m5stack_core2and do not impact other platforms. All platform configurations remain consistent.🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Check for potential inconsistencies across platform configurations # Test 1: Compare creation objects across platforms echo "Platforms with 'creation' object:" jq '.platforms | to_entries[] | select(.value.creation != null) | .key' firmware/stackchan/manifest.json # Test 2: Check for microphone-related configs across platforms echo "\nPlatforms with microphone-related configs:" jq '.platforms | to_entries[] | select(.value.config.microphone != null or .value.config.audio != null) | .key' firmware/stackchan/manifest.json # Test 3: List unique config keys across all platforms echo "\nUnique config keys across all platforms:" jq '.platforms | map(.config | keys) | flatten | unique' firmware/stackchan/manifest.jsonLength of output: 699
firmware/stackchan/main.ts (2)
20-20: LGTM: Microphone import added.The import statement for the Microphone module is correctly placed and aligns with the project's intention to add audio input capabilities.
116-116: LGTM: Microphone added to Robot initialization.The microphone is correctly added to the Robot constructor, allowing the Robot instance to access microphone functionality when available.
Please ensure that the Robot class is updated to handle the new microphone property. Run the following script to verify the Robot class definition:
firmware/stackchan/robot.ts (3)
6-6: LGTM: Microphone type import added correctly.The import statement for the Microphone type is correctly placed and follows the existing import conventions in the file.
68-68: LGTM: Microphone property added to RobotConstructorParam.The optional microphone property is correctly typed and added to the RobotConstructorParam type. This addition maintains backwards compatibility while allowing for the new microphone functionality.
92-92: LGTM: Private microphone property added to Robot class.The private #microphone property is correctly declared and placed within the Robot class, following the existing code structure and conventions.
firmware/stackchan/microphone.ts (1)
59-60: Temporary//@ts-ignoreforaudio.readis acceptableAcknowledged that
audio.readrequires a//@ts-ignoredue to mismatched type definitions. Thank you for proactively addressing this issue by submitting a PR to the Moddable repository to update the type definitions.
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Outside diff range and nitpick comments (1)
firmware/stackchan/transcriptions/stt-whisper.ts (1)
56-60: Validate the presence of 'text' in the API responseWhile the API is expected to return a
textfield upon a successful response, adding a validation ensures robustness against unexpected response formats or partial failures. This helps prevent runtime errors if the response structure changes.Consider adding a check:
const obj = await response.json(); if (!obj.text) { return { success: false, reason: 'Invalid response from transcription API' }; } return { success: true, value: obj.text, };
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
📒 Files selected for processing (4)
- firmware/mods/ai_stackchan/mod.js (1 hunks)
- firmware/stackchan/manifest_microphone.json (1 hunks)
- firmware/stackchan/microphone.ts (1 hunks)
- firmware/stackchan/transcriptions/stt-whisper.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
- firmware/mods/ai_stackchan/mod.js
- firmware/stackchan/manifest_microphone.json
- firmware/stackchan/microphone.ts
🧰 Additional context used
|
@meganetaaan 🐇 対応も完了しました |
meganetaaan
left a comment
There was a problem hiding this comment.
Core2本体のみを使って動作確認しました。めっちゃいいですね!コードの修正もLGTMです!
Core2だと裏蓋のマイクが必須なので、CoreS3やPDMマイクユニット後付け等、スタックチャンのボディと合わせて動作できるか試してみます。
STT -> LLM -> TTS を使った一連の所謂AIスタックチャン実現に必要な機能追加のPRです。
大きな機能追加ごとにコミットを分けており、その概要と実装途中で気になったこと、本PRで議論したいことを記載してます。
STT追加
今回STTクラスを新規追加するので、STTクラスのインターフェース仕様について確認をいただきたいです
Micorphone追加
creationでのメモリ確保量を増やす必要があるかもしれません。recordメソッドとして利用可能になっています。robotクラスとして公開するメソッドの追加は
recordのみですが、STTクラスと組み合わせメソッドを用意した方が良いかなど、robotクラスの拡張方針を確認いただきたいですModdable 5.1.0でECMA-419のAudioInクラスが追加されてますが、型定義など揃ったらいずれ移行したいです。
mods/ai_stackchan 追加
今回追加した機能の想定する使い方となっています。modアプリケーションの書き振りで気になるところがあればコメントをいただきたいです
Summary by CodeRabbit
Release Notes
New Features
Bug Fixes
Documentation
Chores