Skip to content

Commit c4d1cf6

Browse files
authored
Merge pull request #20878 from wordpress-mobile/issue/v2c-support-jetpack-ai-query
[Voice to Content] Implement Jetpack-ai-query into workflow
2 parents ba982f2 + 5eb2a46 commit c4d1cf6

5 files changed

Lines changed: 61 additions & 23 deletions

File tree

WordPress/src/main/java/org/wordpress/android/ui/main/MainActionListItem.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ sealed class MainActionListItem {
1414
CREATE_NEW_PAGE_FROM_PAGES_CARD,
1515
CREATE_NEW_POST,
1616
ANSWER_BLOGGING_PROMPT,
17-
CREATE_NEW_POST_FROM_AUDIO_AI
17+
CREATE_NEW_POST_FROM_AUDIO
1818
}
1919

2020
data class CreateAction(

WordPress/src/main/java/org/wordpress/android/ui/main/WPMainActivity.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -720,7 +720,7 @@ private void initViewModel() {
720720

721721
mViewModel.getCreateAction().observe(this, createAction -> {
722722
switch (createAction) {
723-
case CREATE_NEW_POST_FROM_AUDIO_AI:
723+
case CREATE_NEW_POST_FROM_AUDIO:
724724
launchVoiceToContent();
725725
break;
726726
case CREATE_NEW_POST:

WordPress/src/main/java/org/wordpress/android/ui/voicetocontent/VoiceToContentUseCase.kt

Lines changed: 57 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ import android.content.Context
44
import kotlinx.coroutines.Dispatchers
55
import kotlinx.coroutines.withContext
66
import org.wordpress.android.fluxc.model.SiteModel
7-
import org.wordpress.android.fluxc.network.rest.wpcom.jetpackai.JetpackAITranscriptionRestClient
7+
import org.wordpress.android.fluxc.network.rest.wpcom.jetpackai.JetpackAIQueryResponse
8+
import org.wordpress.android.fluxc.network.rest.wpcom.jetpackai.JetpackAITranscriptionResponse
89
import org.wordpress.android.fluxc.store.jetpackai.JetpackAIStore
910
import org.wordpress.android.viewmodel.ContextProvider
1011
import java.io.File
@@ -14,36 +15,76 @@ import javax.inject.Inject
1415

1516
class VoiceToContentUseCase @Inject constructor(
1617
private val jetpackAIStore: JetpackAIStore,
17-
private val contextProvider: ContextProvider
18+
private val fileHelperWrapper: VoiceToContentTempFileHelperWrapper
1819
) {
1920
companion object {
2021
const val FEATURE = "voice_to_content"
21-
private const val KILO_BYTE = 1024
22+
const val ROLE = "jetpack-ai"
23+
const val TYPE = "voice-to-content-simple-draft"
24+
const val JETPACK_AI_ERROR = "__JETPACK_AI_ERROR__"
2225
}
2326

2427
suspend fun execute(
2528
siteModel: SiteModel,
2629
): VoiceToContentResult =
2730
withContext(Dispatchers.IO) {
28-
val file = getAudioFile() ?: return@withContext VoiceToContentResult(isError = true)
29-
val response = jetpackAIStore.fetchJetpackAITranscription(
31+
val file = fileHelperWrapper.getAudioFile() ?: return@withContext VoiceToContentResult(isError = true)
32+
val transcriptionResponse = jetpackAIStore.fetchJetpackAITranscription(
3033
siteModel,
3134
FEATURE,
3235
file
3336
)
3437

35-
when(response) {
36-
is JetpackAITranscriptionRestClient.JetpackAITranscriptionResponse.Success -> {
37-
return@withContext VoiceToContentResult(content = response.model)
38+
val transcribedText: String? = when(transcriptionResponse) {
39+
is JetpackAITranscriptionResponse.Success -> {
40+
transcriptionResponse.model
3841
}
39-
is JetpackAITranscriptionRestClient.JetpackAITranscriptionResponse.Error -> {
40-
return@withContext VoiceToContentResult(isError = true)
42+
is JetpackAITranscriptionResponse.Error -> {
43+
null
4144
}
4245
}
46+
47+
transcribedText?.let {
48+
val response = jetpackAIStore.fetchJetpackAIQuery(
49+
site = siteModel,
50+
feature = FEATURE,
51+
role = ROLE,
52+
message = it,
53+
stream = false,
54+
type = TYPE
55+
)
56+
57+
when(response) {
58+
is JetpackAIQueryResponse.Success -> {
59+
val finalContent: String = response.choices[0].message.content
60+
// __JETPACK_AI_ERROR__ is a special marker we ask GPT to add to the request when it can’t
61+
// understand the request for any reason, so maybe something confused GPT on some requests.
62+
if (finalContent == JETPACK_AI_ERROR) {
63+
return@withContext VoiceToContentResult(isError = true)
64+
} else {
65+
return@withContext VoiceToContentResult(content = response.choices[0].message.content)
66+
}
67+
}
68+
69+
is JetpackAIQueryResponse.Error -> {
70+
return@withContext VoiceToContentResult(isError = true)
71+
}
72+
}
73+
} ?:return@withContext VoiceToContentResult(isError = true)
4374
}
75+
}
76+
77+
// todo: build out the result object
78+
data class VoiceToContentResult(
79+
val content: String? = null,
80+
val isError: Boolean = false
81+
)
4482

45-
// todo: The next three methods are temporary to support development - remove when the real impl is in place
46-
private fun getAudioFile(): File? {
83+
// todo: Remove this class when real impl is in place - it's here so I can start unit tests
84+
class VoiceToContentTempFileHelperWrapper @Inject constructor(
85+
private val contextProvider: ContextProvider
86+
) {
87+
fun getAudioFile(): File? {
4788
val result = runCatching {
4889
getFileFromAssets(contextProvider.getContext())
4990
}
@@ -53,7 +94,7 @@ class VoiceToContentUseCase @Inject constructor(
5394
}
5495
}
5596

56-
// todo: Do not forget to delete the test file from the asset directory - when the real impl is in place
97+
// todo: Do not forget to delete the test file from the asset directory
5798
private fun getFileFromAssets(context: Context): File {
5899
val fileName = "jetpack-ai-transcription-test-audio-file.m4a"
59100
val file = File(context.filesDir, fileName)
@@ -74,10 +115,7 @@ class VoiceToContentUseCase @Inject constructor(
74115
}
75116
inputStream.close()
76117
}
118+
companion object {
119+
const val KILO_BYTE = 1024
120+
}
77121
}
78-
79-
// todo: build out the result object
80-
data class VoiceToContentResult(
81-
val content: String? = null,
82-
val isError: Boolean = false
83-
)

WordPress/src/main/java/org/wordpress/android/viewmodel/main/WPMainActivityViewModel.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ class WPMainActivityViewModel @Inject constructor(
208208
if (voiceToContentFeatureUtils.isVoiceToContentEnabled() && hasFullAccessToContent(site)) {
209209
actionsList.add(
210210
CreateAction(
211-
actionType = ActionType.CREATE_NEW_POST_FROM_AUDIO_AI,
211+
actionType = ActionType.CREATE_NEW_POST_FROM_AUDIO,
212212
iconRes = R.drawable.ic_mic_white_24dp,
213213
labelRes = R.string.my_site_bottom_sheet_add_post_from_audio,
214214
onClickAction = ::onCreateActionClicked

build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ ext {
2525
automatticTracksVersion = '5.0.0'
2626
gutenbergMobileVersion = 'v1.119.0'
2727
wordPressAztecVersion = 'v2.1.3'
28-
wordPressFluxCVersion = '2.81.0'
28+
wordPressFluxCVersion = 'trunk-a018ee9062d23f3a9280a2bf1e87c6b782616b55'
2929
wordPressLoginVersion = '1.15.0'
3030
wordPressPersistentEditTextVersion = '1.0.2'
3131
wordPressUtilsVersion = '3.14.0'

0 commit comments

Comments
 (0)