From 93df39926fd37317af144c7d09eda746e2060839 Mon Sep 17 00:00:00 2001 From: alperozturk96 Date: Thu, 5 Nov 2026 15:24:28 +0300 Subject: [PATCH 1/4] fix fields and add missing action Signed-off-by: alperozturk96 --- .../chat/GenerateSessionRemoteOperation.kt | 11 ++++++++-- .../assistant/chat/model/AgencyAction.kt | 21 +++++++++++++++++++ .../assistant/chat/model/ChatMessage.kt | 3 ++- .../resources/assistant/chat/model/Session.kt | 9 ++++---- .../resources/assistant/v2/model/TaskList.kt | 4 ++-- .../resources/assistant/v2/model/TaskTypes.kt | 9 ++++---- 6 files changed, 42 insertions(+), 15 deletions(-) create mode 100644 library/src/main/java/com/owncloud/android/lib/resources/assistant/chat/model/AgencyAction.kt diff --git a/library/src/main/java/com/owncloud/android/lib/resources/assistant/chat/GenerateSessionRemoteOperation.kt b/library/src/main/java/com/owncloud/android/lib/resources/assistant/chat/GenerateSessionRemoteOperation.kt index a06062f329..9a3be896f0 100644 --- a/library/src/main/java/com/owncloud/android/lib/resources/assistant/chat/GenerateSessionRemoteOperation.kt +++ b/library/src/main/java/com/owncloud/android/lib/resources/assistant/chat/GenerateSessionRemoteOperation.kt @@ -17,11 +17,16 @@ import com.owncloud.android.lib.resources.assistant.chat.model.SessionTask import org.apache.commons.httpclient.HttpStatus class GenerateSessionRemoteOperation( - private val sessionId: String + private val sessionId: String, + private val agencyConfirm: Boolean? = null ) : RemoteOperation() { @Suppress("TooGenericExceptionCaught") override fun run(client: NextcloudClient): RemoteOperationResult { - val url = client.baseUri.toString() + "$BASE_URL/generate?sessionId=$sessionId" + val agencyConfirmParam = + agencyConfirm + ?.let { confirmed -> "&agencyConfirm=" + if (confirmed) AGENCY_CONFIRM else AGENCY_REJECT } + .orEmpty() + val url = client.baseUri.toString() + "$BASE_URL/generate?sessionId=$sessionId$agencyConfirmParam" val getMethod = GetMethod(url, true) val status = getMethod.execute(client) @@ -47,5 +52,7 @@ class GenerateSessionRemoteOperation( companion object { private const val TAG = "GenerateRemoteOperation" private const val BASE_URL = "/ocs/v2.php/apps/assistant/chat" + private const val AGENCY_CONFIRM = 1 + private const val AGENCY_REJECT = 0 } } diff --git a/library/src/main/java/com/owncloud/android/lib/resources/assistant/chat/model/AgencyAction.kt b/library/src/main/java/com/owncloud/android/lib/resources/assistant/chat/model/AgencyAction.kt new file mode 100644 index 0000000000..aeb2814c3c --- /dev/null +++ b/library/src/main/java/com/owncloud/android/lib/resources/assistant/chat/model/AgencyAction.kt @@ -0,0 +1,21 @@ +/* + * Nextcloud Android Library + * + * SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2026 Alper Ozturk + * SPDX-License-Identifier: MIT + */ + +package com.owncloud.android.lib.resources.assistant.chat.model + +import com.google.gson.annotations.SerializedName + +data class AgencyAction( + val id: Long?, + val name: String?, + val args: Map?, + val destructive: Boolean?, + @SerializedName("impulse_radius") + val impulseRadius: String?, + val icon: String? +) diff --git a/library/src/main/java/com/owncloud/android/lib/resources/assistant/chat/model/ChatMessage.kt b/library/src/main/java/com/owncloud/android/lib/resources/assistant/chat/model/ChatMessage.kt index 618eb95a68..412a5a2af1 100644 --- a/library/src/main/java/com/owncloud/android/lib/resources/assistant/chat/model/ChatMessage.kt +++ b/library/src/main/java/com/owncloud/android/lib/resources/assistant/chat/model/ChatMessage.kt @@ -20,5 +20,6 @@ data class ChatMessage( @SerializedName("ocp_task_id") val ocpTaskId: Any?, val sources: String, - val attachments: List + val attachments: List, + val sessionAgencyPendingActions: List? = null ) diff --git a/library/src/main/java/com/owncloud/android/lib/resources/assistant/chat/model/Session.kt b/library/src/main/java/com/owncloud/android/lib/resources/assistant/chat/model/Session.kt index e5b1048618..d963a1dff7 100644 --- a/library/src/main/java/com/owncloud/android/lib/resources/assistant/chat/model/Session.kt +++ b/library/src/main/java/com/owncloud/android/lib/resources/assistant/chat/model/Session.kt @@ -9,11 +9,10 @@ package com.owncloud.android.lib.resources.assistant.chat.model data class Session( - val messageTaskId: Int?, - val titleTaskId: Int?, - val sessionTitle: String, - val sessionAgencyPendingActions: Any?, - val taskId: Long + val messageTaskId: Long?, + val titleTaskId: Long?, + val sessionTitle: String?, + val sessionAgencyPendingActions: List? ) data class SessionTask( diff --git a/library/src/main/java/com/owncloud/android/lib/resources/assistant/v2/model/TaskList.kt b/library/src/main/java/com/owncloud/android/lib/resources/assistant/v2/model/TaskList.kt index 0660dcfe01..578e45c9a5 100644 --- a/library/src/main/java/com/owncloud/android/lib/resources/assistant/v2/model/TaskList.kt +++ b/library/src/main/java/com/owncloud/android/lib/resources/assistant/v2/model/TaskList.kt @@ -21,12 +21,12 @@ data class Task( val input: TaskInput?, val output: TaskOutput?, val completionExpectedAt: Int? = null, - var progress: Int? = null, + var progress: Double? = null, val lastUpdated: Int? = null, val scheduledAt: Int? = null, val endedAt: Int? = null ) { - fun isTranslate(): Boolean = (type == "core:text2text:translate") + fun isTranslate(): Boolean = (type == TaskTypeData.TRANSLATE_TASK_TYPE_ID) } data class TaskInput( diff --git a/library/src/main/java/com/owncloud/android/lib/resources/assistant/v2/model/TaskTypes.kt b/library/src/main/java/com/owncloud/android/lib/resources/assistant/v2/model/TaskTypes.kt index 20340fe2f5..53d5e21425 100644 --- a/library/src/main/java/com/owncloud/android/lib/resources/assistant/v2/model/TaskTypes.kt +++ b/library/src/main/java/com/owncloud/android/lib/resources/assistant/v2/model/TaskTypes.kt @@ -24,14 +24,13 @@ data class TaskTypeData( val outputShapeEnumValues: Map>? = null, val optionalOutputShapeEnumValues: Map>? = null ) { - private val chatTaskName = "Chat" - private val translateTaskName = "Translate" + fun isChat(): Boolean = (id == CHAT_TASK_TYPE_ID) - fun isChat(): Boolean = (name == chatTaskName) - - fun isTranslate(): Boolean = (name == translateTaskName) + fun isTranslate(): Boolean = (id == TRANSLATE_TASK_TYPE_ID) companion object { + const val CHAT_TASK_TYPE_ID = "core:text2text:chat" + const val TRANSLATE_TASK_TYPE_ID = "core:text2text:translate" private const val CONVERSATION_LIST_ID = "ConversationList" val conversationList = TaskTypeData( From 65e1a521275760391a4bd0b7becdb4b47c4ab2da Mon Sep 17 00:00:00 2001 From: alperozturk96 Date: Thu, 5 Nov 2026 15:34:51 +0300 Subject: [PATCH 2/4] wip Signed-off-by: alperozturk96 --- .../chat/GenerateSessionRemoteOperation.kt | 11 ++-------- .../assistant/chat/model/AgencyAction.kt | 21 ------------------- .../assistant/chat/model/ChatMessage.kt | 3 +-- .../resources/assistant/chat/model/Session.kt | 2 +- 4 files changed, 4 insertions(+), 33 deletions(-) delete mode 100644 library/src/main/java/com/owncloud/android/lib/resources/assistant/chat/model/AgencyAction.kt diff --git a/library/src/main/java/com/owncloud/android/lib/resources/assistant/chat/GenerateSessionRemoteOperation.kt b/library/src/main/java/com/owncloud/android/lib/resources/assistant/chat/GenerateSessionRemoteOperation.kt index 9a3be896f0..a06062f329 100644 --- a/library/src/main/java/com/owncloud/android/lib/resources/assistant/chat/GenerateSessionRemoteOperation.kt +++ b/library/src/main/java/com/owncloud/android/lib/resources/assistant/chat/GenerateSessionRemoteOperation.kt @@ -17,16 +17,11 @@ import com.owncloud.android.lib.resources.assistant.chat.model.SessionTask import org.apache.commons.httpclient.HttpStatus class GenerateSessionRemoteOperation( - private val sessionId: String, - private val agencyConfirm: Boolean? = null + private val sessionId: String ) : RemoteOperation() { @Suppress("TooGenericExceptionCaught") override fun run(client: NextcloudClient): RemoteOperationResult { - val agencyConfirmParam = - agencyConfirm - ?.let { confirmed -> "&agencyConfirm=" + if (confirmed) AGENCY_CONFIRM else AGENCY_REJECT } - .orEmpty() - val url = client.baseUri.toString() + "$BASE_URL/generate?sessionId=$sessionId$agencyConfirmParam" + val url = client.baseUri.toString() + "$BASE_URL/generate?sessionId=$sessionId" val getMethod = GetMethod(url, true) val status = getMethod.execute(client) @@ -52,7 +47,5 @@ class GenerateSessionRemoteOperation( companion object { private const val TAG = "GenerateRemoteOperation" private const val BASE_URL = "/ocs/v2.php/apps/assistant/chat" - private const val AGENCY_CONFIRM = 1 - private const val AGENCY_REJECT = 0 } } diff --git a/library/src/main/java/com/owncloud/android/lib/resources/assistant/chat/model/AgencyAction.kt b/library/src/main/java/com/owncloud/android/lib/resources/assistant/chat/model/AgencyAction.kt deleted file mode 100644 index aeb2814c3c..0000000000 --- a/library/src/main/java/com/owncloud/android/lib/resources/assistant/chat/model/AgencyAction.kt +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Nextcloud Android Library - * - * SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors - * SPDX-FileCopyrightText: 2026 Alper Ozturk - * SPDX-License-Identifier: MIT - */ - -package com.owncloud.android.lib.resources.assistant.chat.model - -import com.google.gson.annotations.SerializedName - -data class AgencyAction( - val id: Long?, - val name: String?, - val args: Map?, - val destructive: Boolean?, - @SerializedName("impulse_radius") - val impulseRadius: String?, - val icon: String? -) diff --git a/library/src/main/java/com/owncloud/android/lib/resources/assistant/chat/model/ChatMessage.kt b/library/src/main/java/com/owncloud/android/lib/resources/assistant/chat/model/ChatMessage.kt index 412a5a2af1..618eb95a68 100644 --- a/library/src/main/java/com/owncloud/android/lib/resources/assistant/chat/model/ChatMessage.kt +++ b/library/src/main/java/com/owncloud/android/lib/resources/assistant/chat/model/ChatMessage.kt @@ -20,6 +20,5 @@ data class ChatMessage( @SerializedName("ocp_task_id") val ocpTaskId: Any?, val sources: String, - val attachments: List, - val sessionAgencyPendingActions: List? = null + val attachments: List ) diff --git a/library/src/main/java/com/owncloud/android/lib/resources/assistant/chat/model/Session.kt b/library/src/main/java/com/owncloud/android/lib/resources/assistant/chat/model/Session.kt index d963a1dff7..d9d8150163 100644 --- a/library/src/main/java/com/owncloud/android/lib/resources/assistant/chat/model/Session.kt +++ b/library/src/main/java/com/owncloud/android/lib/resources/assistant/chat/model/Session.kt @@ -12,7 +12,7 @@ data class Session( val messageTaskId: Long?, val titleTaskId: Long?, val sessionTitle: String?, - val sessionAgencyPendingActions: List? + val sessionAgencyPendingActions: Any? ) data class SessionTask( From b62039db6e6cc19b57e521db7dd598478a1ac4ba Mon Sep 17 00:00:00 2001 From: alperozturk96 Date: Wed, 11 Nov 2026 13:05:26 +0100 Subject: [PATCH 3/4] use kotlinx Signed-off-by: alperozturk96 --- .../lib/resources/assistant/AssistantJson.kt | 16 +++++++ .../assistant/EmptyArrayAsObjectSerializer.kt | 20 +++++++++ .../chat/CheckGenerationRemoteOperation.kt | 3 +- .../chat/CheckSessionRemoteOperation.kt | 3 +- .../chat/CreateConversationRemoteOperation.kt | 19 ++++---- .../chat/CreateMessageRemoteOperation.kt | 8 ++-- .../chat/GenerateSessionRemoteOperation.kt | 3 +- .../GetConversationListRemoteOperation.kt | 5 +-- .../chat/GetMessagesRemoteOperation.kt | 5 +-- .../assistant/chat/model/ChatMessage.kt | 15 ++++--- .../chat/model/ChatMessageRequest.kt | 15 ++----- .../assistant/chat/model/Conversation.kt | 17 ++++--- .../chat/model/CreateConversation.kt | 3 ++ .../resources/assistant/chat/model/Session.kt | 13 ++++-- .../v1/CreateTaskRemoteOperationV1.kt | 18 ++++---- .../v1/GetTaskListRemoteOperationV1.kt | 14 +++--- .../v1/GetTaskTypesRemoteOperationV1.kt | 14 +++--- .../resources/assistant/v1/model/TaskList.kt | 22 ++++++---- .../resources/assistant/v1/model/TaskTypes.kt | 7 ++- .../v2/GetTaskListRemoteOperationV2.kt | 14 +++--- .../v2/GetTaskTypesRemoteOperationV2.kt | 44 ++++++++++++------- .../resources/assistant/v2/model/TaskList.kt | 25 ++++++++--- .../resources/assistant/v2/model/TaskTypes.kt | 35 +++++++++++++-- .../assistant/v2/model/Translation.kt | 7 ++- 24 files changed, 227 insertions(+), 118 deletions(-) create mode 100644 library/src/main/java/com/owncloud/android/lib/resources/assistant/AssistantJson.kt create mode 100644 library/src/main/java/com/owncloud/android/lib/resources/assistant/EmptyArrayAsObjectSerializer.kt diff --git a/library/src/main/java/com/owncloud/android/lib/resources/assistant/AssistantJson.kt b/library/src/main/java/com/owncloud/android/lib/resources/assistant/AssistantJson.kt new file mode 100644 index 0000000000..89e0fd7c8c --- /dev/null +++ b/library/src/main/java/com/owncloud/android/lib/resources/assistant/AssistantJson.kt @@ -0,0 +1,16 @@ +/* + * Nextcloud Android Library + * + * SPDX-FileCopyrightText: 2026 Alper Ozturk + * SPDX-License-Identifier: MIT + */ + +package com.owncloud.android.lib.resources.assistant + +import kotlinx.serialization.json.Json + +internal val assistantRequestJson = + Json { + encodeDefaults = true + explicitNulls = false + } diff --git a/library/src/main/java/com/owncloud/android/lib/resources/assistant/EmptyArrayAsObjectSerializer.kt b/library/src/main/java/com/owncloud/android/lib/resources/assistant/EmptyArrayAsObjectSerializer.kt new file mode 100644 index 0000000000..ae461fd8ad --- /dev/null +++ b/library/src/main/java/com/owncloud/android/lib/resources/assistant/EmptyArrayAsObjectSerializer.kt @@ -0,0 +1,20 @@ +/* + * Nextcloud Android Library + * + * SPDX-FileCopyrightText: 2026 Alper Ozturk + * SPDX-License-Identifier: MIT + */ + +package com.owncloud.android.lib.resources.assistant + +import kotlinx.serialization.KSerializer +import kotlinx.serialization.json.JsonArray +import kotlinx.serialization.json.JsonElement +import kotlinx.serialization.json.JsonObject +import kotlinx.serialization.json.JsonTransformingSerializer + +internal open class EmptyArrayAsObjectSerializer(serializer: KSerializer) : + JsonTransformingSerializer(serializer) { + override fun transformDeserialize(element: JsonElement): JsonElement = + if (element is JsonArray && element.isEmpty()) JsonObject(emptyMap()) else element +} diff --git a/library/src/main/java/com/owncloud/android/lib/resources/assistant/chat/CheckGenerationRemoteOperation.kt b/library/src/main/java/com/owncloud/android/lib/resources/assistant/chat/CheckGenerationRemoteOperation.kt index 138daf9b9e..28fa990f50 100644 --- a/library/src/main/java/com/owncloud/android/lib/resources/assistant/chat/CheckGenerationRemoteOperation.kt +++ b/library/src/main/java/com/owncloud/android/lib/resources/assistant/chat/CheckGenerationRemoteOperation.kt @@ -12,6 +12,7 @@ import com.nextcloud.operations.GetMethod import com.owncloud.android.lib.common.operations.RemoteOperation import com.owncloud.android.lib.common.operations.RemoteOperationResult import com.owncloud.android.lib.common.utils.Log_OC +import com.owncloud.android.lib.ocs.ocsJson import com.owncloud.android.lib.resources.assistant.chat.model.ChatMessage import org.apache.commons.httpclient.HttpStatus @@ -31,7 +32,7 @@ class CheckGenerationRemoteOperation( return try { if (status == HttpStatus.SC_OK) { val responseBody = getMethod.getResponseBodyAsString() - val jsonResponse = gson.fromJson(responseBody, ChatMessage::class.java) + val jsonResponse = ocsJson.decodeFromString(responseBody) val result = RemoteOperationResult(true, getMethod) result.resultData = jsonResponse diff --git a/library/src/main/java/com/owncloud/android/lib/resources/assistant/chat/CheckSessionRemoteOperation.kt b/library/src/main/java/com/owncloud/android/lib/resources/assistant/chat/CheckSessionRemoteOperation.kt index 98cedf3b7c..7b089c341d 100644 --- a/library/src/main/java/com/owncloud/android/lib/resources/assistant/chat/CheckSessionRemoteOperation.kt +++ b/library/src/main/java/com/owncloud/android/lib/resources/assistant/chat/CheckSessionRemoteOperation.kt @@ -13,6 +13,7 @@ import com.nextcloud.operations.GetMethod import com.owncloud.android.lib.common.operations.RemoteOperation import com.owncloud.android.lib.common.operations.RemoteOperationResult import com.owncloud.android.lib.common.utils.Log_OC +import com.owncloud.android.lib.ocs.ocsJson import com.owncloud.android.lib.resources.assistant.chat.model.Session import org.apache.commons.httpclient.HttpStatus @@ -31,7 +32,7 @@ class CheckSessionRemoteOperation( return try { if (status == HttpStatus.SC_OK) { val responseBody = getMethod.getResponseBodyAsString() - val jsonResponse = gson.fromJson(responseBody, Session::class.java) + val jsonResponse = ocsJson.decodeFromString(responseBody) val result = RemoteOperationResult(true, getMethod) result.resultData = jsonResponse diff --git a/library/src/main/java/com/owncloud/android/lib/resources/assistant/chat/CreateConversationRemoteOperation.kt b/library/src/main/java/com/owncloud/android/lib/resources/assistant/chat/CreateConversationRemoteOperation.kt index 51818f16cd..e9fb6889f1 100644 --- a/library/src/main/java/com/owncloud/android/lib/resources/assistant/chat/CreateConversationRemoteOperation.kt +++ b/library/src/main/java/com/owncloud/android/lib/resources/assistant/chat/CreateConversationRemoteOperation.kt @@ -8,13 +8,15 @@ package com.owncloud.android.lib.resources.assistant.chat -import com.google.gson.reflect.TypeToken import com.nextcloud.common.NextcloudClient import com.nextcloud.operations.PutMethod import com.owncloud.android.lib.common.operations.RemoteOperation import com.owncloud.android.lib.common.operations.RemoteOperationResult import com.owncloud.android.lib.common.utils.Log_OC +import com.owncloud.android.lib.ocs.ocsJson import com.owncloud.android.lib.resources.assistant.chat.model.CreateConversation +import kotlinx.serialization.json.buildJsonObject +import kotlinx.serialization.json.put import okhttp3.MediaType.Companion.toMediaTypeOrNull import okhttp3.RequestBody.Companion.toRequestBody import org.apache.commons.httpclient.HttpStatus @@ -25,13 +27,11 @@ class CreateConversationRemoteOperation( ) : RemoteOperation() { @Suppress("TooGenericExceptionCaught") override fun run(client: NextcloudClient): RemoteOperationResult { - val bodyMap = - hashMapOf( - "title" to title, - "timestamp" to timestamp - ) - - val json = gson.toJson(bodyMap) + val json = + buildJsonObject { + title?.let { put("title", it) } + put("timestamp", timestamp) + }.toString() val requestBody = json.toRequestBody("application/json".toMediaTypeOrNull()) val putMethod = PutMethod(client.baseUri.toString() + "$BASE_URL/new_session", true, requestBody) @@ -40,8 +40,7 @@ class CreateConversationRemoteOperation( return try { if (status == HttpStatus.SC_OK) { val responseBody = putMethod.getResponseBodyAsString() - val type = object : TypeToken() {}.type - val response: CreateConversation = gson.fromJson(responseBody, type) + val response = ocsJson.decodeFromString(responseBody) val result: RemoteOperationResult = RemoteOperationResult(true, putMethod) result.resultData = response result diff --git a/library/src/main/java/com/owncloud/android/lib/resources/assistant/chat/CreateMessageRemoteOperation.kt b/library/src/main/java/com/owncloud/android/lib/resources/assistant/chat/CreateMessageRemoteOperation.kt index 1bb98be677..75cac874fd 100644 --- a/library/src/main/java/com/owncloud/android/lib/resources/assistant/chat/CreateMessageRemoteOperation.kt +++ b/library/src/main/java/com/owncloud/android/lib/resources/assistant/chat/CreateMessageRemoteOperation.kt @@ -8,13 +8,14 @@ package com.owncloud.android.lib.resources.assistant.chat -import com.google.gson.reflect.TypeToken import com.nextcloud.common.NextcloudClient import com.nextcloud.operations.PutMethod import com.owncloud.android.lib.common.operations.RemoteOperation import com.owncloud.android.lib.common.operations.RemoteOperationResult import com.owncloud.android.lib.common.utils.Log_OC +import com.owncloud.android.lib.ocs.ocsJson import com.owncloud.android.lib.resources.assistant.chat.model.ChatMessage +import com.owncloud.android.lib.resources.assistant.assistantRequestJson import com.owncloud.android.lib.resources.assistant.chat.model.ChatMessageRequest import okhttp3.MediaType.Companion.toMediaTypeOrNull import okhttp3.RequestBody.Companion.toRequestBody @@ -25,7 +26,7 @@ class CreateMessageRemoteOperation( ) : RemoteOperation() { @Suppress("TooGenericExceptionCaught") override fun run(client: NextcloudClient): RemoteOperationResult { - val json = gson.toJson(messageRequest.bodyMap) + val json = assistantRequestJson.encodeToString(messageRequest) val requestBody = json.toRequestBody("application/json".toMediaTypeOrNull()) val putMethod = PutMethod(client.baseUri.toString() + "$BASE_URL/new_message", true, requestBody) @@ -34,8 +35,7 @@ class CreateMessageRemoteOperation( return try { if (status == HttpStatus.SC_OK) { val responseBody = putMethod.getResponseBodyAsString() - val type = object : TypeToken() {}.type - val response: ChatMessage = gson.fromJson(responseBody, type) + val response = ocsJson.decodeFromString(responseBody) val result: RemoteOperationResult = RemoteOperationResult(true, putMethod) result.resultData = response result diff --git a/library/src/main/java/com/owncloud/android/lib/resources/assistant/chat/GenerateSessionRemoteOperation.kt b/library/src/main/java/com/owncloud/android/lib/resources/assistant/chat/GenerateSessionRemoteOperation.kt index a06062f329..d4f125bfe4 100644 --- a/library/src/main/java/com/owncloud/android/lib/resources/assistant/chat/GenerateSessionRemoteOperation.kt +++ b/library/src/main/java/com/owncloud/android/lib/resources/assistant/chat/GenerateSessionRemoteOperation.kt @@ -13,6 +13,7 @@ import com.nextcloud.operations.GetMethod import com.owncloud.android.lib.common.operations.RemoteOperation import com.owncloud.android.lib.common.operations.RemoteOperationResult import com.owncloud.android.lib.common.utils.Log_OC +import com.owncloud.android.lib.ocs.ocsJson import com.owncloud.android.lib.resources.assistant.chat.model.SessionTask import org.apache.commons.httpclient.HttpStatus @@ -28,7 +29,7 @@ class GenerateSessionRemoteOperation( return try { if (status == HttpStatus.SC_OK) { val responseBody = getMethod.getResponseBodyAsString() - val jsonResponse = gson.fromJson(responseBody, SessionTask::class.java) + val jsonResponse = ocsJson.decodeFromString(responseBody) val result = RemoteOperationResult(true, getMethod) result.resultData = jsonResponse diff --git a/library/src/main/java/com/owncloud/android/lib/resources/assistant/chat/GetConversationListRemoteOperation.kt b/library/src/main/java/com/owncloud/android/lib/resources/assistant/chat/GetConversationListRemoteOperation.kt index a2f9db9d4a..aaaf179272 100644 --- a/library/src/main/java/com/owncloud/android/lib/resources/assistant/chat/GetConversationListRemoteOperation.kt +++ b/library/src/main/java/com/owncloud/android/lib/resources/assistant/chat/GetConversationListRemoteOperation.kt @@ -8,12 +8,12 @@ package com.owncloud.android.lib.resources.assistant.chat -import com.google.gson.reflect.TypeToken import com.nextcloud.common.NextcloudClient import com.nextcloud.operations.GetMethod import com.owncloud.android.lib.common.operations.RemoteOperation import com.owncloud.android.lib.common.operations.RemoteOperationResult import com.owncloud.android.lib.common.utils.Log_OC +import com.owncloud.android.lib.ocs.ocsJson import com.owncloud.android.lib.resources.assistant.chat.model.Conversation import org.apache.commons.httpclient.HttpStatus @@ -26,8 +26,7 @@ class GetConversationListRemoteOperation : RemoteOperation>() return try { if (status == HttpStatus.SC_OK) { val responseBody = getMethod.getResponseBodyAsString() - val type = object : TypeToken>() {}.type - val conversationList: List = gson.fromJson(responseBody, type) + val conversationList = ocsJson.decodeFromString>(responseBody) val result = RemoteOperationResult>(true, getMethod) result.resultData = conversationList diff --git a/library/src/main/java/com/owncloud/android/lib/resources/assistant/chat/GetMessagesRemoteOperation.kt b/library/src/main/java/com/owncloud/android/lib/resources/assistant/chat/GetMessagesRemoteOperation.kt index ff26c18d36..d559361156 100644 --- a/library/src/main/java/com/owncloud/android/lib/resources/assistant/chat/GetMessagesRemoteOperation.kt +++ b/library/src/main/java/com/owncloud/android/lib/resources/assistant/chat/GetMessagesRemoteOperation.kt @@ -8,12 +8,12 @@ package com.owncloud.android.lib.resources.assistant.chat -import com.google.gson.reflect.TypeToken import com.nextcloud.common.NextcloudClient import com.nextcloud.operations.GetMethod import com.owncloud.android.lib.common.operations.RemoteOperation import com.owncloud.android.lib.common.operations.RemoteOperationResult import com.owncloud.android.lib.common.utils.Log_OC +import com.owncloud.android.lib.ocs.ocsJson import com.owncloud.android.lib.resources.assistant.chat.model.ChatMessage import org.apache.commons.httpclient.HttpStatus @@ -32,8 +32,7 @@ class GetMessagesRemoteOperation( return try { if (status == HttpStatus.SC_OK) { val responseBody = getMethod.getResponseBodyAsString() - val type = object : TypeToken>() {}.type - val response: List = gson.fromJson(responseBody, type) + val response = ocsJson.decodeFromString>(responseBody) val result: RemoteOperationResult> = RemoteOperationResult(true, getMethod) result.resultData = response result diff --git a/library/src/main/java/com/owncloud/android/lib/resources/assistant/chat/model/ChatMessage.kt b/library/src/main/java/com/owncloud/android/lib/resources/assistant/chat/model/ChatMessage.kt index 618eb95a68..e137d43462 100644 --- a/library/src/main/java/com/owncloud/android/lib/resources/assistant/chat/model/ChatMessage.kt +++ b/library/src/main/java/com/owncloud/android/lib/resources/assistant/chat/model/ChatMessage.kt @@ -8,17 +8,20 @@ package com.owncloud.android.lib.resources.assistant.chat.model -import com.google.gson.annotations.SerializedName +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable +import kotlinx.serialization.json.JsonElement +@Serializable data class ChatMessage( val id: Long, - @SerializedName("session_id") + @SerialName("session_id") val sessionId: Long, val role: String, val content: String, val timestamp: Long, - @SerializedName("ocp_task_id") - val ocpTaskId: Any?, - val sources: String, - val attachments: List + @SerialName("ocp_task_id") + val ocpTaskId: Long? = null, + val sources: String? = null, + val attachments: List = emptyList() ) diff --git a/library/src/main/java/com/owncloud/android/lib/resources/assistant/chat/model/ChatMessageRequest.kt b/library/src/main/java/com/owncloud/android/lib/resources/assistant/chat/model/ChatMessageRequest.kt index a6f3792e8f..00fa073a64 100644 --- a/library/src/main/java/com/owncloud/android/lib/resources/assistant/chat/model/ChatMessageRequest.kt +++ b/library/src/main/java/com/owncloud/android/lib/resources/assistant/chat/model/ChatMessageRequest.kt @@ -8,6 +8,9 @@ package com.owncloud.android.lib.resources.assistant.chat.model +import kotlinx.serialization.Serializable + +@Serializable data class ChatMessageRequest( val sessionId: String, val role: String, @@ -15,14 +18,4 @@ data class ChatMessageRequest( val timestamp: Long, val attachments: List? = null, val firstHumanMessage: Boolean = false -) { - val bodyMap = - hashMapOf( - "sessionId" to sessionId, - "role" to role, - "content" to content, - "timestamp" to timestamp, - "firstHumanMessage" to firstHumanMessage, - "attachments" to attachments - ) -} +) diff --git a/library/src/main/java/com/owncloud/android/lib/resources/assistant/chat/model/Conversation.kt b/library/src/main/java/com/owncloud/android/lib/resources/assistant/chat/model/Conversation.kt index a2c394869f..6734a4b9ad 100644 --- a/library/src/main/java/com/owncloud/android/lib/resources/assistant/chat/model/Conversation.kt +++ b/library/src/main/java/com/owncloud/android/lib/resources/assistant/chat/model/Conversation.kt @@ -8,7 +8,9 @@ package com.owncloud.android.lib.resources.assistant.chat.model -import com.google.gson.annotations.SerializedName +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable +import kotlinx.serialization.json.JsonElement import java.time.ZoneId import java.time.format.DateTimeFormatter import java.util.Locale @@ -16,16 +18,17 @@ import kotlin.time.ExperimentalTime import kotlin.time.Instant import kotlin.time.toJavaInstant +@Serializable data class Conversation( val id: Long, - @SerializedName("user_id") + @SerialName("user_id") val userId: String, - val title: String?, + val title: String? = null, val timestamp: Long, - @SerializedName("agency_conversation_token") - val agencyConversationToken: String, - @SerializedName("agency_pending_actions") - val agencyPendingActions: Any? + @SerialName("agency_conversation_token") + val agencyConversationToken: String? = null, + @SerialName("agency_pending_actions") + val agencyPendingActions: JsonElement? = null ) { companion object { private const val TITLE_PRESENTATION_TIME_PATTERN = "MMMM dd, yyyy HH:mm" diff --git a/library/src/main/java/com/owncloud/android/lib/resources/assistant/chat/model/CreateConversation.kt b/library/src/main/java/com/owncloud/android/lib/resources/assistant/chat/model/CreateConversation.kt index a05d6094f1..7f04237d80 100644 --- a/library/src/main/java/com/owncloud/android/lib/resources/assistant/chat/model/CreateConversation.kt +++ b/library/src/main/java/com/owncloud/android/lib/resources/assistant/chat/model/CreateConversation.kt @@ -8,6 +8,9 @@ package com.owncloud.android.lib.resources.assistant.chat.model +import kotlinx.serialization.Serializable + +@Serializable data class CreateConversation( val session: Conversation ) diff --git a/library/src/main/java/com/owncloud/android/lib/resources/assistant/chat/model/Session.kt b/library/src/main/java/com/owncloud/android/lib/resources/assistant/chat/model/Session.kt index d9d8150163..c3c3610751 100644 --- a/library/src/main/java/com/owncloud/android/lib/resources/assistant/chat/model/Session.kt +++ b/library/src/main/java/com/owncloud/android/lib/resources/assistant/chat/model/Session.kt @@ -8,13 +8,18 @@ package com.owncloud.android.lib.resources.assistant.chat.model +import kotlinx.serialization.Serializable +import kotlinx.serialization.json.JsonElement + +@Serializable data class Session( - val messageTaskId: Long?, - val titleTaskId: Long?, - val sessionTitle: String?, - val sessionAgencyPendingActions: Any? + val messageTaskId: Long? = null, + val titleTaskId: Long? = null, + val sessionTitle: String? = null, + val sessionAgencyPendingActions: JsonElement? = null ) +@Serializable data class SessionTask( val taskId: Long ) diff --git a/library/src/main/java/com/owncloud/android/lib/resources/assistant/v1/CreateTaskRemoteOperationV1.kt b/library/src/main/java/com/owncloud/android/lib/resources/assistant/v1/CreateTaskRemoteOperationV1.kt index 09dbae62bf..228696a421 100644 --- a/library/src/main/java/com/owncloud/android/lib/resources/assistant/v1/CreateTaskRemoteOperationV1.kt +++ b/library/src/main/java/com/owncloud/android/lib/resources/assistant/v1/CreateTaskRemoteOperationV1.kt @@ -12,6 +12,8 @@ import com.nextcloud.common.NextcloudClient import com.nextcloud.operations.PostMethod import com.owncloud.android.lib.common.operations.RemoteOperation import com.owncloud.android.lib.common.operations.RemoteOperationResult +import kotlinx.serialization.json.buildJsonObject +import kotlinx.serialization.json.put import okhttp3.MediaType.Companion.toMediaTypeOrNull import okhttp3.RequestBody.Companion.toRequestBody import org.apache.commons.httpclient.HttpStatus @@ -21,15 +23,13 @@ class CreateTaskRemoteOperationV1( private val type: String ) : RemoteOperation() { override fun run(client: NextcloudClient): RemoteOperationResult { - val requestBody = - hashMapOf( - "input" to input, - "type" to type, - "appId" to "assistant", - "identifier" to "" - ) - - val json = gson.toJson(requestBody) + val json = + buildJsonObject { + put("input", input) + put("type", type) + put("appId", "assistant") + put("identifier", "") + }.toString() val request = json.toRequestBody("application/json".toMediaTypeOrNull()) diff --git a/library/src/main/java/com/owncloud/android/lib/resources/assistant/v1/GetTaskListRemoteOperationV1.kt b/library/src/main/java/com/owncloud/android/lib/resources/assistant/v1/GetTaskListRemoteOperationV1.kt index b865e2d876..d401b55477 100644 --- a/library/src/main/java/com/owncloud/android/lib/resources/assistant/v1/GetTaskListRemoteOperationV1.kt +++ b/library/src/main/java/com/owncloud/android/lib/resources/assistant/v1/GetTaskListRemoteOperationV1.kt @@ -8,12 +8,12 @@ package com.owncloud.android.lib.resources.assistant.v1 -import com.google.gson.reflect.TypeToken import com.nextcloud.common.NextcloudClient import com.nextcloud.operations.GetMethod import com.owncloud.android.lib.common.operations.RemoteOperationResult import com.owncloud.android.lib.common.utils.Log_OC -import com.owncloud.android.lib.ocs.ServerResponse +import com.owncloud.android.lib.ocs.OcsKotlinResponse +import com.owncloud.android.lib.ocs.ocsJson import com.owncloud.android.lib.resources.OCSRemoteOperation import com.owncloud.android.lib.resources.assistant.v1.model.TaskList import org.apache.commons.httpclient.HttpStatus @@ -30,11 +30,11 @@ class GetTaskListRemoteOperationV1( GetMethod(client.baseUri.toString() + DIRECT_ENDPOINT + appId + JSON_FORMAT, true) val status = client.execute(getMethod) if (status == HttpStatus.SC_OK) { - val taskTypes: TaskList? = - getServerResponse( - getMethod, - object : TypeToken>() {} - )?.ocs?.data + val taskTypes = + ocsJson + .decodeFromString>(getMethod.getResponseBodyAsString()) + .ocs + .data result = RemoteOperationResult(true, getMethod) result.setResultData(taskTypes) } else { diff --git a/library/src/main/java/com/owncloud/android/lib/resources/assistant/v1/GetTaskTypesRemoteOperationV1.kt b/library/src/main/java/com/owncloud/android/lib/resources/assistant/v1/GetTaskTypesRemoteOperationV1.kt index 7047022e22..ae4b016c3b 100644 --- a/library/src/main/java/com/owncloud/android/lib/resources/assistant/v1/GetTaskTypesRemoteOperationV1.kt +++ b/library/src/main/java/com/owncloud/android/lib/resources/assistant/v1/GetTaskTypesRemoteOperationV1.kt @@ -8,12 +8,12 @@ package com.owncloud.android.lib.resources.assistant.v1 -import com.google.gson.reflect.TypeToken import com.nextcloud.common.NextcloudClient import com.nextcloud.operations.GetMethod import com.owncloud.android.lib.common.operations.RemoteOperationResult import com.owncloud.android.lib.common.utils.Log_OC -import com.owncloud.android.lib.ocs.ServerResponse +import com.owncloud.android.lib.ocs.OcsKotlinResponse +import com.owncloud.android.lib.ocs.ocsJson import com.owncloud.android.lib.resources.OCSRemoteOperation import com.owncloud.android.lib.resources.assistant.v1.model.TaskTypes import org.apache.commons.httpclient.HttpStatus @@ -28,11 +28,11 @@ class GetTaskTypesRemoteOperationV1 : OCSRemoteOperation() { GetMethod(client.baseUri.toString() + DIRECT_ENDPOINT + JSON_FORMAT, true) val status = client.execute(getMethod) if (status == HttpStatus.SC_OK) { - val taskTypes: TaskTypes? = - getServerResponse( - getMethod, - object : TypeToken>() {} - )?.ocs?.data + val taskTypes = + ocsJson + .decodeFromString>(getMethod.getResponseBodyAsString()) + .ocs + .data result = RemoteOperationResult(true, getMethod) result.setResultData(taskTypes) } else { diff --git a/library/src/main/java/com/owncloud/android/lib/resources/assistant/v1/model/TaskList.kt b/library/src/main/java/com/owncloud/android/lib/resources/assistant/v1/model/TaskList.kt index ef19a21036..16fd0b8383 100644 --- a/library/src/main/java/com/owncloud/android/lib/resources/assistant/v1/model/TaskList.kt +++ b/library/src/main/java/com/owncloud/android/lib/resources/assistant/v1/model/TaskList.kt @@ -8,20 +8,24 @@ package com.owncloud.android.lib.resources.assistant.v1.model +import kotlinx.serialization.Serializable + +@Serializable data class TaskList( var tasks: List ) +@Serializable data class Task( val id: Long, - val type: String?, - val status: Long?, - val userId: String?, - val appId: String?, - val input: String?, - val output: String?, - val identifier: String?, - val completionExpectedAt: String? = null + val type: String? = null, + val status: Long? = null, + val userId: String? = null, + val appId: String? = null, + val input: String? = null, + val output: String? = null, + val identifier: String? = null, + val completionExpectedAt: Long? = null ) fun TaskList.toV2(): com.owncloud.android.lib.resources.assistant.v2.model.TaskList = @@ -44,7 +48,7 @@ fun TaskList.toV2(): com.owncloud.android.lib.resources.assistant.v2.model.TaskL com.owncloud.android.lib.resources.assistant.v2.model .TaskOutput(output = it) }, - completionExpectedAt = task.completionExpectedAt?.toIntOrNull(), + completionExpectedAt = task.completionExpectedAt?.toInt(), progress = null, lastUpdated = null, scheduledAt = null, diff --git a/library/src/main/java/com/owncloud/android/lib/resources/assistant/v1/model/TaskTypes.kt b/library/src/main/java/com/owncloud/android/lib/resources/assistant/v1/model/TaskTypes.kt index 9f2dedf851..0d514af576 100644 --- a/library/src/main/java/com/owncloud/android/lib/resources/assistant/v1/model/TaskTypes.kt +++ b/library/src/main/java/com/owncloud/android/lib/resources/assistant/v1/model/TaskTypes.kt @@ -9,15 +9,18 @@ package com.owncloud.android.lib.resources.assistant.v1.model import com.owncloud.android.lib.resources.assistant.v2.model.TaskTypeData +import kotlinx.serialization.Serializable +@Serializable data class TaskTypes( var types: List ) +@Serializable data class TaskType( - val id: String?, + val id: String? = null, val name: String, - val description: String? + val description: String? = null ) fun TaskTypes.toV2(): List = diff --git a/library/src/main/java/com/owncloud/android/lib/resources/assistant/v2/GetTaskListRemoteOperationV2.kt b/library/src/main/java/com/owncloud/android/lib/resources/assistant/v2/GetTaskListRemoteOperationV2.kt index c72ff9ed37..2d7cae32c3 100644 --- a/library/src/main/java/com/owncloud/android/lib/resources/assistant/v2/GetTaskListRemoteOperationV2.kt +++ b/library/src/main/java/com/owncloud/android/lib/resources/assistant/v2/GetTaskListRemoteOperationV2.kt @@ -8,12 +8,12 @@ package com.owncloud.android.lib.resources.assistant.v2 -import com.google.gson.reflect.TypeToken import com.nextcloud.common.NextcloudClient import com.nextcloud.operations.GetMethod import com.owncloud.android.lib.common.operations.RemoteOperationResult import com.owncloud.android.lib.common.utils.Log_OC -import com.owncloud.android.lib.ocs.ServerResponse +import com.owncloud.android.lib.ocs.OcsKotlinResponse +import com.owncloud.android.lib.ocs.ocsJson import com.owncloud.android.lib.resources.OCSRemoteOperation import com.owncloud.android.lib.resources.assistant.v2.model.TaskList import org.apache.commons.httpclient.HttpStatus @@ -30,11 +30,11 @@ class GetTaskListRemoteOperationV2( GetMethod(client.baseUri.toString() + DIRECT_ENDPOINT + taskType + "&format=json", true) val status = client.execute(getMethod) if (status == HttpStatus.SC_OK) { - val taskTypes: TaskList? = - getServerResponse( - getMethod, - object : TypeToken>() {} - )?.ocs?.data + val taskTypes = + ocsJson + .decodeFromString>(getMethod.getResponseBodyAsString()) + .ocs + .data result = RemoteOperationResult(true, getMethod) result.setResultData(taskTypes) } else { diff --git a/library/src/main/java/com/owncloud/android/lib/resources/assistant/v2/GetTaskTypesRemoteOperationV2.kt b/library/src/main/java/com/owncloud/android/lib/resources/assistant/v2/GetTaskTypesRemoteOperationV2.kt index 96a7372f21..75afd2bc23 100644 --- a/library/src/main/java/com/owncloud/android/lib/resources/assistant/v2/GetTaskTypesRemoteOperationV2.kt +++ b/library/src/main/java/com/owncloud/android/lib/resources/assistant/v2/GetTaskTypesRemoteOperationV2.kt @@ -8,15 +8,16 @@ package com.owncloud.android.lib.resources.assistant.v2 -import com.google.gson.reflect.TypeToken import com.nextcloud.common.NextcloudClient import com.nextcloud.operations.GetMethod import com.owncloud.android.lib.common.operations.RemoteOperationResult import com.owncloud.android.lib.common.utils.Log_OC -import com.owncloud.android.lib.ocs.ServerResponse +import com.owncloud.android.lib.ocs.OcsKotlinResponse +import com.owncloud.android.lib.ocs.ocsJson import com.owncloud.android.lib.resources.OCSRemoteOperation import com.owncloud.android.lib.resources.assistant.v2.model.TaskTypeData -import com.owncloud.android.lib.resources.assistant.v2.model.TaskTypes +import kotlinx.serialization.json.JsonElement +import kotlinx.serialization.json.JsonObject import org.apache.commons.httpclient.HttpStatus /** @@ -58,21 +59,20 @@ class GetTaskTypesRemoteOperationV2 : OCSRemoteOperation>() { GetMethod(client.baseUri.toString() + DIRECT_ENDPOINT + JSON_FORMAT, true) val status = client.execute(getMethod) if (status == HttpStatus.SC_OK) { - val response = - getServerResponse( - getMethod, - object : TypeToken>() {} - ) + val response = getMethod.getResponseBodyAsString() + val types = + ocsJson + .decodeFromString>>(response) + .ocs + .data[TYPES_KEY] as? JsonObject val taskTypeList = - response - ?.ocs - ?.data - ?.types - ?.map { (key, value) -> value.copy(id = value.id ?: key) } - ?.filter { taskType -> + types + .orEmpty() + .mapNotNull { (key, value) -> decodeTaskType(key, value) } + .filter { taskType -> isSingleTextInputOutput(taskType) || taskType.isChat() || taskType.isTranslate() - }?.sortedByDescending { it.isChat() } + }.sortedByDescending { it.isChat() } result = RemoteOperationResult(true, getMethod) result.resultData = taskTypeList @@ -92,6 +92,19 @@ class GetTaskTypesRemoteOperationV2 : OCSRemoteOperation>() { return result } + @Suppress("TooGenericExceptionCaught") + private fun decodeTaskType( + key: String, + value: JsonElement + ): TaskTypeData? = + try { + val taskType = ocsJson.decodeFromJsonElement(TaskTypeData.serializer(), value) + taskType.copy(id = taskType.id ?: key) + } catch (e: Exception) { + Log_OC.w(TAG, "Skipping task type $key: ${e.message}") + null + } + private fun isSingleTextInputOutput(taskType: TaskTypeData): Boolean { val inputShape = taskType.inputShape val outputShape = taskType.outputShape @@ -110,5 +123,6 @@ class GetTaskTypesRemoteOperationV2 : OCSRemoteOperation>() { companion object { private val TAG = GetTaskTypesRemoteOperationV2::class.java.simpleName private const val DIRECT_ENDPOINT = "/ocs/v2.php/taskprocessing/tasktypes" + private const val TYPES_KEY = "types" } } diff --git a/library/src/main/java/com/owncloud/android/lib/resources/assistant/v2/model/TaskList.kt b/library/src/main/java/com/owncloud/android/lib/resources/assistant/v2/model/TaskList.kt index 578e45c9a5..9d4f2a01da 100644 --- a/library/src/main/java/com/owncloud/android/lib/resources/assistant/v2/model/TaskList.kt +++ b/library/src/main/java/com/owncloud/android/lib/resources/assistant/v2/model/TaskList.kt @@ -8,18 +8,25 @@ package com.owncloud.android.lib.resources.assistant.v2.model +import com.owncloud.android.lib.resources.assistant.EmptyArrayAsObjectSerializer +import kotlinx.serialization.Serializable + +@Serializable data class TaskList( var tasks: List ) +@Serializable data class Task( val id: Long, - val type: String?, - val status: String?, - val userId: String?, - val appId: String?, - val input: TaskInput?, - val output: TaskOutput?, + val type: String? = null, + val status: String? = null, + val userId: String? = null, + val appId: String? = null, + @Serializable(with = TaskInputSerializer::class) + val input: TaskInput? = null, + @Serializable(with = TaskOutputSerializer::class) + val output: TaskOutput? = null, val completionExpectedAt: Int? = null, var progress: Double? = null, val lastUpdated: Int? = null, @@ -29,10 +36,16 @@ data class Task( fun isTranslate(): Boolean = (type == TaskTypeData.TRANSLATE_TASK_TYPE_ID) } +@Serializable data class TaskInput( var input: String? = null ) +@Serializable data class TaskOutput( var output: String? = null ) + +internal object TaskInputSerializer : EmptyArrayAsObjectSerializer(TaskInput.serializer()) + +internal object TaskOutputSerializer : EmptyArrayAsObjectSerializer(TaskOutput.serializer()) diff --git a/library/src/main/java/com/owncloud/android/lib/resources/assistant/v2/model/TaskTypes.kt b/library/src/main/java/com/owncloud/android/lib/resources/assistant/v2/model/TaskTypes.kt index 53d5e21425..68088d15ee 100644 --- a/library/src/main/java/com/owncloud/android/lib/resources/assistant/v2/model/TaskTypes.kt +++ b/library/src/main/java/com/owncloud/android/lib/resources/assistant/v2/model/TaskTypes.kt @@ -8,20 +8,36 @@ package com.owncloud.android.lib.resources.assistant.v2.model +import com.owncloud.android.lib.resources.assistant.EmptyArrayAsObjectSerializer +import kotlinx.serialization.Serializable +import kotlinx.serialization.builtins.ListSerializer +import kotlinx.serialization.builtins.MapSerializer +import kotlinx.serialization.builtins.serializer +import kotlinx.serialization.json.JsonObject + +@Serializable data class TaskTypes( val types: Map ) +@Serializable data class TaskTypeData( - val id: String?, + val id: String? = null, val name: String, - val description: String?, + val description: String? = null, + @Serializable(with = ShapeMapSerializer::class) val inputShape: Map, + @Serializable(with = ShapeMapSerializer::class) val outputShape: Map, - val optionalInputShapeDefaults: Map? = null, + @Serializable(with = ShapeDefaultsSerializer::class) + val optionalInputShapeDefaults: JsonObject? = null, + @Serializable(with = EnumValuesMapSerializer::class) val optionalInputShapeEnumValues: Map>? = null, + @Serializable(with = EnumValuesMapSerializer::class) val inputShapeEnumValues: Map>? = null, + @Serializable(with = EnumValuesMapSerializer::class) val outputShapeEnumValues: Map>? = null, + @Serializable(with = EnumValuesMapSerializer::class) val optionalOutputShapeEnumValues: Map>? = null ) { fun isChat(): Boolean = (id == CHAT_TASK_TYPE_ID) @@ -43,13 +59,26 @@ data class TaskTypeData( } } +@Serializable data class EnumValue( val name: String, val value: String ) +@Serializable data class Shape( val name: String, val description: String, val type: String ) + +internal object ShapeMapSerializer : + EmptyArrayAsObjectSerializer>(MapSerializer(String.serializer(), Shape.serializer())) + +internal object EnumValuesMapSerializer : + EmptyArrayAsObjectSerializer>>( + MapSerializer(String.serializer(), ListSerializer(EnumValue.serializer())) + ) + +internal object ShapeDefaultsSerializer : + EmptyArrayAsObjectSerializer(JsonObject.serializer()) diff --git a/library/src/main/java/com/owncloud/android/lib/resources/assistant/v2/model/Translation.kt b/library/src/main/java/com/owncloud/android/lib/resources/assistant/v2/model/Translation.kt index ab0ad8c870..aff68dc0d7 100644 --- a/library/src/main/java/com/owncloud/android/lib/resources/assistant/v2/model/Translation.kt +++ b/library/src/main/java/com/owncloud/android/lib/resources/assistant/v2/model/Translation.kt @@ -10,6 +10,9 @@ package com.owncloud.android.lib.resources.assistant.v2.model import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable +import kotlinx.serialization.json.JsonPrimitive +import kotlinx.serialization.json.contentOrNull +import kotlinx.serialization.json.doubleOrNull data class TranslationLanguage( val name: String, @@ -51,7 +54,7 @@ fun TaskTypeData.toTranslationLanguages(): TranslationLanguages { } fun TaskTypeData.toTranslationModel(): TranslationModel? { - val model = optionalInputShapeDefaults?.get("model") as? String - val maxTokens = optionalInputShapeDefaults?.get("max_tokens") as? Double + val model = (optionalInputShapeDefaults?.get("model") as? JsonPrimitive)?.contentOrNull + val maxTokens = (optionalInputShapeDefaults?.get("max_tokens") as? JsonPrimitive)?.doubleOrNull return if (model != null && maxTokens != null) TranslationModel(model, maxTokens) else null } From dfdff84c30e86db0282abaa821e1f08234017266 Mon Sep 17 00:00:00 2001 From: alperozturk96 Date: Wed, 11 Nov 2026 13:15:33 +0100 Subject: [PATCH 4/4] use kotlinx Signed-off-by: alperozturk96 --- .../lib/resources/assistant/EmptyArrayAsObjectSerializer.kt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/library/src/main/java/com/owncloud/android/lib/resources/assistant/EmptyArrayAsObjectSerializer.kt b/library/src/main/java/com/owncloud/android/lib/resources/assistant/EmptyArrayAsObjectSerializer.kt index ae461fd8ad..0fa609b60f 100644 --- a/library/src/main/java/com/owncloud/android/lib/resources/assistant/EmptyArrayAsObjectSerializer.kt +++ b/library/src/main/java/com/owncloud/android/lib/resources/assistant/EmptyArrayAsObjectSerializer.kt @@ -13,8 +13,9 @@ import kotlinx.serialization.json.JsonElement import kotlinx.serialization.json.JsonObject import kotlinx.serialization.json.JsonTransformingSerializer -internal open class EmptyArrayAsObjectSerializer(serializer: KSerializer) : - JsonTransformingSerializer(serializer) { +internal open class EmptyArrayAsObjectSerializer( + serializer: KSerializer +) : JsonTransformingSerializer(serializer) { override fun transformDeserialize(element: JsonElement): JsonElement = if (element is JsonArray && element.isEmpty()) JsonObject(emptyMap()) else element }