Skip to content

Commit 027df5a

Browse files
committed
feature: create audio translations entrypoint
1 parent d521c63 commit 027df5a

File tree

8 files changed

+161
-0
lines changed

8 files changed

+161
-0
lines changed

ychat/src/commonMain/kotlin/co/yml/ychat/YChat.kt

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package co.yml.ychat
22

33
import co.yml.ychat.entrypoint.features.AudioTranscriptions
4+
import co.yml.ychat.entrypoint.features.AudioTranslations
45
import co.yml.ychat.entrypoint.features.ChatCompletions
56
import co.yml.ychat.entrypoint.features.Completion
67
import co.yml.ychat.entrypoint.features.Edits
@@ -152,6 +153,20 @@ interface YChat {
152153
*/
153154
fun audioTranscriptions(): AudioTranscriptions
154155

156+
/**
157+
* The audioTranscriptions api is used to translates audio into English.
158+
*
159+
* You can configure the parameters before executing it. Example:
160+
* ```
161+
* val result = YChat.create(apiKey).audioTranslations()
162+
* .setTemperature(0.0)
163+
* .setResponseFormat("json")
164+
* .set...
165+
* .execute("file.mp4", byteArrayFile)
166+
* ```
167+
*/
168+
fun audioTranslations(): AudioTranslations
169+
155170
/**
156171
* Callback is an interface used for handling the results of an operation.
157172
* It provides two methods, `onSuccess` and `onError`, for handling the success

ychat/src/commonMain/kotlin/co/yml/ychat/data/api/ChatGptApi.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,6 @@ internal interface ChatGptApi {
2929
suspend fun model(id: String): ApiResult<ModelDto>
3030

3131
suspend fun audioTranscriptions(audioParamsDto: AudioParamsDto): ApiResult<AudioResultDto>
32+
33+
suspend fun audioTranslations(audioParamsDto: AudioParamsDto): ApiResult<AudioResultDto>
3234
}

ychat/src/commonMain/kotlin/co/yml/ychat/data/api/impl/ChatGptApiImpl.kt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,16 @@ internal class ChatGptApiImpl(private val apiExecutor: ApiExecutor) : ChatGptApi
7676
return apiBuilder.execute()
7777
}
7878

79+
override suspend fun audioTranslations(audioParamsDto: AudioParamsDto): ApiResult<AudioResultDto> {
80+
val byteArray = audioParamsDto.byteArray.toByteArray()
81+
val apiBuilder = apiExecutor
82+
.setEndpoint("$VERSION/audio/translations")
83+
.setHttpMethod(HttpMethod.Post)
84+
.addFormPart("file", audioParamsDto.filename, byteArray)
85+
audioParamsDto.getMap().forEach { apiBuilder.addFormPart(it.key, it.value) }
86+
return apiBuilder.execute()
87+
}
88+
7989
companion object {
8090
private const val VERSION = "v1"
8191
}

ychat/src/commonMain/kotlin/co/yml/ychat/di/module/LibraryModule.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,15 @@ import co.yml.ychat.domain.usecases.ImageGenerationsUseCase
1313
import co.yml.ychat.domain.usecases.ListModelsUseCase
1414
import co.yml.ychat.domain.usecases.RetrieveModelUseCase
1515
import co.yml.ychat.entrypoint.features.AudioTranscriptions
16+
import co.yml.ychat.entrypoint.features.AudioTranslations
1617
import co.yml.ychat.entrypoint.features.ChatCompletions
1718
import co.yml.ychat.entrypoint.features.Completion
1819
import co.yml.ychat.entrypoint.features.Edits
1920
import co.yml.ychat.entrypoint.features.ImageGenerations
2021
import co.yml.ychat.entrypoint.features.ListModels
2122
import co.yml.ychat.entrypoint.features.RetrieveModel
2223
import co.yml.ychat.entrypoint.impl.AudioTranscriptionsImpl
24+
import co.yml.ychat.entrypoint.impl.AudioTranslationsImpl
2325
import co.yml.ychat.entrypoint.impl.ChatCompletionsImpl
2426
import co.yml.ychat.entrypoint.impl.CompletionImpl
2527
import co.yml.ychat.entrypoint.impl.EditsImpl
@@ -43,6 +45,7 @@ internal class LibraryModule(private val apiKey: String) {
4345
factory<ImageGenerations> { ImageGenerationsImpl(Dispatchers.Default, get()) }
4446
factory<Edits> { EditsImpl(Dispatchers.Default, get()) }
4547
factory<AudioTranscriptions> { AudioTranscriptionsImpl(Dispatchers.Default, get()) }
48+
factory<AudioTranslations> { AudioTranslationsImpl(Dispatchers.Default, get()) }
4649
}
4750

4851
private val domainModule = module {

ychat/src/commonMain/kotlin/co/yml/ychat/domain/usecases/AudioUseCase.kt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,14 @@ internal class AudioUseCase(private val chatGptApi: ChatGptApi) {
1616
val response = chatGptApi.audioTranscriptions(requestDto)
1717
return response.getBodyOrThrow().text
1818
}
19+
20+
suspend fun requestAudioTranslations(
21+
filename: String,
22+
audioFile: FileBytes,
23+
params: AudioParams
24+
): String {
25+
val requestDto = params.toAudioParamsDto(filename, audioFile)
26+
val response = chatGptApi.audioTranslations(requestDto)
27+
return response.getBodyOrThrow().text
28+
}
1929
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
package co.yml.ychat.entrypoint.features
2+
3+
import co.yml.ychat.YChat
4+
import co.yml.ychat.data.exception.ChatGptException
5+
import co.yml.ychat.domain.model.FileBytes
6+
import kotlin.coroutines.cancellation.CancellationException
7+
8+
interface AudioTranslations {
9+
10+
/**
11+
* Sets the ID of the model to use. The default value is "whisper-1".
12+
* @param model The ID of the model to use.
13+
* @return The updated [AudioTranslations] object with the new model ID.
14+
*/
15+
fun setModel(model: String): AudioTranslations
16+
17+
/**
18+
* Sets an optional text to guide the model's style or continue a previous audio segment.
19+
* The [prompt] should be in English.
20+
* @param prompt The prompt to use.
21+
* @return The updated [AudioTranslations] object with the new prompt.
22+
*/
23+
fun setPrompt(prompt: String): AudioTranslations
24+
25+
/**
26+
* Sets the format of the transcript output.
27+
* @param format The format of the transcript output, in one of these options:
28+
* json, text, srt, verbose_json, or vtt.
29+
* @return The updated [AudioTranslations] object with the new response format.
30+
*/
31+
fun setResponseFormat(format: String): AudioTranslations
32+
33+
/**
34+
* Sets the sampling temperature, between 0 and 1. Higher values like 0.8 will make the output
35+
* more random, while lower values like 0.2 will make it more focused and deterministic.
36+
* If set to 0, the model will use log probability to automatically increase the temperature
37+
* until certain thresholds are hit.
38+
* @param temperature The sampling temperature to use.
39+
* @return The updated [AudioTranslations] object with the new temperature.
40+
*/
41+
fun setTemperature(temperature: Double): AudioTranslations
42+
43+
/**
44+
* Translates audio into English.
45+
* @param filename The name of the audio file.
46+
* @param audioFile The audio file to translate, in one of these formats: mp3, mp4, mpeg,
47+
* mpga, m4a, wav, or webm.
48+
* @return The transcript output in the specified format.
49+
* @throws CancellationException if the operation is cancelled.
50+
* @throws ChatGptException if there is an error transcribing the audio file.
51+
*/
52+
@Throws(CancellationException::class, ChatGptException::class)
53+
suspend fun execute(filename: String, audioFile: FileBytes): String
54+
55+
/**
56+
* Translates audio into English and passes it to the provided [callback].
57+
* @param filename The name of the audio file.
58+
* @param audioFile The audio file to translate, in one of these formats:
59+
* mp3, mp4, mpeg, mpga, m4a, wav, or webm.
60+
* @param callback The callback to receive the transcript output in the specified format.
61+
*/
62+
fun execute(filename: String, audioFile: FileBytes, callback: YChat.Callback<String>)
63+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package co.yml.ychat.entrypoint.impl
2+
3+
import co.yml.ychat.YChat
4+
import co.yml.ychat.domain.model.AudioParams
5+
import co.yml.ychat.domain.model.FileBytes
6+
import co.yml.ychat.domain.usecases.AudioUseCase
7+
import co.yml.ychat.entrypoint.features.AudioTranslations
8+
import kotlinx.coroutines.CoroutineDispatcher
9+
import kotlinx.coroutines.CoroutineScope
10+
import kotlinx.coroutines.SupervisorJob
11+
import kotlinx.coroutines.launch
12+
13+
internal class AudioTranslationsImpl(
14+
private val dispatcher: CoroutineDispatcher,
15+
private val audioUseCase: AudioUseCase,
16+
) : AudioTranslations {
17+
18+
private val scope by lazy { CoroutineScope(SupervisorJob() + dispatcher) }
19+
20+
private val params: AudioParams = AudioParams()
21+
22+
override fun setModel(model: String): AudioTranslations {
23+
params.model = model
24+
return this
25+
}
26+
27+
override fun setPrompt(prompt: String): AudioTranslations {
28+
params.prompt = prompt
29+
return this
30+
}
31+
32+
override fun setResponseFormat(format: String): AudioTranslations {
33+
params.responseFormat = format
34+
return this
35+
}
36+
37+
override fun setTemperature(temperature: Double): AudioTranslations {
38+
params.temperature = temperature
39+
return this
40+
}
41+
42+
override suspend fun execute(filename: String, audioFile: FileBytes): String {
43+
return audioUseCase.requestAudioTranslations(filename, audioFile, params)
44+
}
45+
46+
override fun execute(filename: String, audioFile: FileBytes, callback: YChat.Callback<String>) {
47+
scope.launch {
48+
runCatching { execute(filename, audioFile) }
49+
.onSuccess { callback.onSuccess(it) }
50+
.onFailure { callback.onError(it) }
51+
}
52+
}
53+
}

ychat/src/commonMain/kotlin/co/yml/ychat/entrypoint/impl/YChatImpl.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package co.yml.ychat.entrypoint.impl
33
import co.yml.ychat.YChat
44
import co.yml.ychat.di.module.LibraryModule
55
import co.yml.ychat.entrypoint.features.AudioTranscriptions
6+
import co.yml.ychat.entrypoint.features.AudioTranslations
67
import co.yml.ychat.entrypoint.features.ChatCompletions
78
import co.yml.ychat.entrypoint.features.Completion
89
import co.yml.ychat.entrypoint.features.Edits
@@ -47,4 +48,8 @@ internal class YChatImpl(apiKey: String) : YChat {
4748
override fun audioTranscriptions(): AudioTranscriptions {
4849
return koinApp.koin.get()
4950
}
51+
52+
override fun audioTranslations(): AudioTranslations {
53+
return koinApp.koin.get()
54+
}
5055
}

0 commit comments

Comments
 (0)