-
Notifications
You must be signed in to change notification settings - Fork 194
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Allowing users to play the recordings of their memories + upload them to their own GCP cloud storage bucket (optional)
- Loading branch information
Showing
11 changed files
with
636 additions
and
320 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,57 +1,67 @@ | ||
### Tasks | ||
|
||
- [ ] It shouldn't require to reconnect every time that you open the app, it should | ||
- [ ] It shouldn't require to reconnect every time that you open the app, it should | ||
load `ConnectDeviceWidget` and in there listen/reconnect to the device. | ||
- [ ] Device disconnected, display dialog to user asking to reconnect, or take the user back | ||
- [ ] Device disconnected, display dialog to user asking to reconnect, or take the user back | ||
to `find_devices` page. | ||
- [ ] Settings bottom sheet, improve way of handling `***` blurring of api keys, as if you save it | ||
- [x] Settings bottom sheet, improve way of handling `***` blurring of api keys, as if you save it | ||
while is blurred with *, it sets the key to that value, and you have to set them again | ||
- [ ] [iOS] memories and chat page on the bottom do not have the blurred colors pattern, but plain | ||
- [ ] [iOS] memories and chat page on the bottom do not have the blurred colors pattern, but plain | ||
primary color | ||
- [ ] Improve structured memory results performance by sending n previous memories as part of the | ||
structuring but as context, not as part of the structure, so that if there's some reference to a | ||
- [ ] Improve structured memory results performance by sending n previous memories as part of the | ||
structuring but as context, not as part of the structure, so that if there's some reference to a | ||
person, and then you use a pronoun, the LLM understands what you are referring to. | ||
- [ ] Migrate MemoryRecord from SharedPreferences to sqlite | ||
- [ ] Implement [similarity search](https://www.pinecone.io/learn/vector-similarity/) locally | ||
- [ ] Use from the AppStandalone `_ragContext` function as a baseline for creating the query | ||
- [ ] Use from the AppStandalone `_ragContext` function as a baseline for creating the query | ||
embedding. | ||
- [ ] When a memory is created, compute the vector embedding and store it locally. | ||
- [ ] When the user sends a question in the chat, extract from the AppStandalone | ||
the `function_calling` that determines if the message requires context, if that's the case, | ||
retrieve the top 10 most similar vectors ~~ For an initial version we can read all memories | ||
- [ ] When the user sends a question in the chat, extract from the AppStandalone | ||
the `function_calling` that determines if the message requires context, if that's the case, | ||
retrieve the top 10 most similar vectors ~~ For an initial version we can read all memories | ||
from sqlite or SharedPreferences, and compute the formula between the query and each vector. | ||
- [ ] Use that as context, and ask to the LLM. Retrieve the prompt from the AppStandalone. | ||
- [X] ----- | ||
- [ ] Another option is to use one of the vector db libraries available for | ||
dart https://github.com/FastCodeAI/DVDB or https://pub.dev/packages/chromadb | ||
- [X] ----- | ||
- [ ] Another option is to use one of the vector db libraries available for | ||
dart https://github.com/FastCodeAI/DVDB or https://pub.dev/packages/chromadb | ||
- [ ] Settings Deepgram + openAI key are forced to be set | ||
- [ ] In case an API key fails, either Deepgram WebSocket connection fails, or GPT requests, let the | ||
- [ ] In case an API key fails, either Deepgram WebSocket connection fails, or GPT requests, let | ||
the | ||
user know the error message, either has no more credits, api key is invalid, etc. | ||
- [ ] Improve connected device page UI, including transcription text, and when memory creates after | ||
- [ ] Improve connected device page UI, including transcription text, and when memory creates | ||
after | ||
30 seconds, let the user know | ||
- [ ] Structure the memory asking JSON output `{"title", "summary"}`, in that way we can have better | ||
- [ ] Structure the memory asking JSON output `{"title", "summary"}`, in that way we can have | ||
better | ||
parsed data. | ||
- [ ] Test/Implement [speaker diarization](https://developers.deepgram.com/docs/diarization) to | ||
recognize multiple speakers in transcription, use that for better context when creating the | ||
- [x] Test/Implement [speaker diarization](https://developers.deepgram.com/docs/diarization) to | ||
recognize multiple speakers in transcription, use that for better context when creating the | ||
structured memory. | ||
- [x] Better `AppWithWerable` folders structure. | ||
- [ ] Define flutter code style rules. | ||
- [ ] Include documentation on how to run `AppWithWearable`. | ||
- [ ] If only 1 speaker, set memory prompt creation, explain those are your thoughts, not a | ||
conversation, also, remove Speaker $i in transcript. | ||
- [ ] Allow users who don't have a GCP bucket to store their recordings locally. | ||
- [ ] Improve recordings player. | ||
--- | ||
|
||
--- | ||
|
||
- [x] Multilanguage option, implement settings selector, and use that for the deepgram websocket | ||
- [x] Multilanguage option, implement settings selector, and use that for the deepgram websocket | ||
creation | ||
- [ ] Option for storing your transcripts somewhere in the cloud, user inputs their own GCP storage | ||
bucket + auth key, and the files are uploaded there + a reference is stored in the MemoryRecord | ||
- [x] Option for storing your transcripts somewhere in the cloud, user inputs their own GCP | ||
storage | ||
bucket + auth key, and the files are uploaded there + a reference is stored in the MemoryRecord | ||
object. | ||
- [ ] `createWavFile` remove empty sounds without words, and saves that fixed file. | ||
|
||
- [ ] ~~ (Idea) Detect a keyword or special order e.g. "Hey Friend" (but not so generic) and | ||
triggers a prompt execution + response. This would require a few hardware updates (could also be a | ||
- [ ] ~~ (Idea) Detect a keyword or special order e.g. "Hey Friend" (but not so generic) and | ||
triggers a prompt execution + response. This would require a few hardware updates (could also be | ||
a | ||
button on the device), and it's way bigger than it seems. | ||
- [ ] ~~ (Idea) Store the location at which the memory was created, and have saved places, like "at | ||
- [ ] ~~ (Idea) Store the location at which the memory was created, and have saved places, like " | ||
at | ||
Home you were chatting about x and y" | ||
- [ ] ~~ (Idea) Speaker detection, use something like the python | ||
library [librosa](https://github.com/librosa/librosa), so that friend recognizes when is you the | ||
one speaking and creates memories better considering that. Maybe even later learns to recognize | ||
- [ ] ~~ (Idea) Speaker detection, use something like the python | ||
library [librosa](https://github.com/librosa/librosa), so that friend recognizes when is you the | ||
one speaking and creates memories better considering that. Maybe even later learns to recognize | ||
other people. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
93 changes: 93 additions & 0 deletions
93
apps/AppWithWearable/lib/backend/api_requests/cloud_storage.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
import 'dart:convert'; | ||
import 'dart:io'; | ||
import 'package:flutter/material.dart'; | ||
import 'package:shared_preferences/shared_preferences.dart'; | ||
import 'package:http/http.dart' as http; | ||
import 'package:googleapis_auth/auth_io.dart'; | ||
import 'package:path_provider/path_provider.dart'; | ||
|
||
AuthClient? authClient; | ||
|
||
void authenticateGCP() async { | ||
var prefs = await SharedPreferences.getInstance(); | ||
var credentialsBase64 = prefs.getString('gcpCredentials') ?? ''; | ||
if (credentialsBase64.isEmpty) { | ||
debugPrint('No GCP credentials found'); | ||
return; | ||
} | ||
final credentialsBytes = base64Decode(credentialsBase64); | ||
String decodedString = utf8.decode(credentialsBytes); | ||
final credentials = ServiceAccountCredentials.fromJson(jsonDecode(decodedString)); | ||
var scopes = ['https://www.googleapis.com/auth/devstorage.full_control']; | ||
authClient = await clientViaServiceAccount(credentials, scopes); | ||
debugPrint('Authenticated'); | ||
} | ||
|
||
Future<String?> uploadFile(File file) async { | ||
var prefs = await SharedPreferences.getInstance(); | ||
String bucketName = prefs.getString('gcpBucketName') ?? ''; | ||
if (bucketName.isEmpty) { | ||
debugPrint('No bucket name found'); | ||
return null; | ||
} | ||
String fileName = file.path.split('/')[file.path.split('/').length - 1]; | ||
String url = 'https://storage.googleapis.com/upload/storage/v1/b/$bucketName/o?uploadType=media&name=$fileName'; | ||
|
||
try { | ||
var response = await http.post( | ||
Uri.parse(url), | ||
headers: { | ||
'Authorization': 'Bearer ${authClient?.credentials.accessToken.data}', | ||
'Content-Type': 'audio/wav', | ||
}, | ||
body: file.readAsBytesSync(), | ||
); | ||
|
||
if (response.statusCode == 200) { | ||
// var json = jsonDecode(response.body); | ||
debugPrint('Upload successful'); | ||
return fileName; | ||
} else { | ||
debugPrint('Failed to upload'); | ||
} | ||
} catch (e) { | ||
debugPrint('Error uploading file: $e'); | ||
} | ||
return null; | ||
} | ||
|
||
// Download file method | ||
Future<File?> downloadFile(String objectName, String saveFileName) async { | ||
final directory = await getApplicationDocumentsDirectory(); | ||
String saveFilePath = '${directory.path}/$saveFileName'; | ||
if (File(saveFilePath).existsSync()) { | ||
debugPrint('File already exists: $saveFileName'); | ||
return File(saveFilePath); | ||
} | ||
|
||
var prefs = await SharedPreferences.getInstance(); | ||
String bucketName = prefs.getString('gcpBucketName') ?? ''; | ||
if (bucketName.isEmpty) { | ||
debugPrint('No bucket name found'); | ||
return null; | ||
} | ||
|
||
try { | ||
var response = await http.get( | ||
Uri.parse('https://storage.googleapis.com/storage/v1/b/$bucketName/o/$objectName?alt=media'), | ||
headers: {'Authorization': 'Bearer ${authClient?.credentials.accessToken.data}'}, | ||
); | ||
|
||
if (response.statusCode == 200) { | ||
final file = File('${directory.path}/$saveFileName'); | ||
await file.writeAsBytes(response.bodyBytes); | ||
debugPrint('Download successful: $saveFileName'); | ||
return file; | ||
} else { | ||
debugPrint('Failed to download: ${response.body}'); | ||
} | ||
} catch (e) { | ||
debugPrint('Error downloading file: $e'); | ||
} | ||
return null; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.