Skip to content
This repository has been archived by the owner on Sep 17, 2023. It is now read-only.

Commit

Permalink
Fix bard chat
Browse files Browse the repository at this point in the history
Signed-off-by: PranavPurwar <[email protected]>
  • Loading branch information
PranavPurwar committed Jun 29, 2023
1 parent f7bdd98 commit 0f6a65b
Show file tree
Hide file tree
Showing 10 changed files with 90 additions and 62 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import com.google.android.material.shape.MaterialShapeDrawable
import com.google.android.material.shape.ShapeAppearanceModel
import com.pkslow.ai.AIClient
import com.pkslow.ai.GoogleBardClient
import com.pkslow.ai.util.NetworkUtils
import com.pkslow.ai.utils.NetworkUtils
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
Expand Down
1 change: 0 additions & 1 deletion feature/bardapi/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,4 @@ tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile> {
dependencies {
implementation("com.squareup.okhttp3:okhttp:5.0.0-alpha.11")
implementation("com.google.code.gson:gson:2.10.1")
implementation("com.google.guava:guava:32.0.1-android")
}
18 changes: 8 additions & 10 deletions feature/bardapi/src/main/java/com/pkslow/ai/GoogleBardClient.kt
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@ import com.pkslow.ai.domain.Answer
import com.pkslow.ai.domain.AnswerStatus
import com.pkslow.ai.domain.BardRequest
import com.pkslow.ai.domain.BardResponse
import com.pkslow.ai.util.BardUtils.createPostRequestForAsk
import com.pkslow.ai.util.BardUtils.createRequestForSNlM0e
import com.pkslow.ai.util.BardUtils.fetchSNlM0eFromBody
import com.pkslow.ai.util.BardUtils.renderBardResponseFromResponse
import com.pkslow.ai.util.Constants.EMPTY_STRING
import com.pkslow.ai.util.WebUtils.okHttpClientWithTimeout
import com.pkslow.ai.utils.BardUtils.createPostRequestForAsk
import com.pkslow.ai.utils.BardUtils.createRequestForSNlM0e
import com.pkslow.ai.utils.BardUtils.fetchSNlM0eFromBody
import com.pkslow.ai.utils.BardUtils.renderBardResponseFromResponse
import com.pkslow.ai.utils.Constants.EMPTY_STRING
import com.pkslow.ai.utils.WebUtils.okHttpClientWithTimeout
import okhttp3.OkHttpClient
import okhttp3.Request
import java.io.IOException
Expand Down Expand Up @@ -83,10 +83,8 @@ class GoogleBardClient : AIClient {
val responseString =
Objects.requireNonNull(response.body).string()
check(statusCode == 200) { "Can't get the answer" }
val result =
responseString.split("\\n".toRegex()).dropLastWhile { it.isEmpty() }
.toTypedArray()[3]
return result
return responseString.split("\\n".toRegex()).dropLastWhile { it.isEmpty() }
.toTypedArray<String>()[3]
}
} catch (e: IOException) {
throw RuntimeException(e)
Expand Down
25 changes: 9 additions & 16 deletions feature/bardapi/src/main/java/com/pkslow/ai/domain/Answer.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,27 +6,20 @@
*/
package com.pkslow.ai.domain

import com.pkslow.ai.util.BardUtils

class Answer(
var status: AnswerStatus = AnswerStatus.NO_ANSWER,
var chosenAnswer: String? = null,
var imageURL: String? = null,
var articleURL: String? = null,
var chosenAnswer: String = "",
var images: List<Image> = listOf(),
) {
val answers = mutableListOf<String>()
fun markdown(): String {
val sb = StringBuilder()
sb.append(chosenAnswer)
if (!BardUtils.isEmpty(imageURL)) {
sb.append("\n\n")
sb.append("[![](")
sb.append(imageURL)
sb.append(")](")
sb.append(articleURL)
sb.append(")")
var markdown = this.chosenAnswer

if (images.isNotEmpty()) {
for (image in images) {
markdown = markdown.replaceFirst(image.labelRegex(), image.markdown())
}
}
return sb.toString()
return markdown
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
*/
package com.pkslow.ai.domain

import com.pkslow.ai.util.Constants.EMPTY_STRING
import com.pkslow.ai.utils.Constants.EMPTY_STRING
import java.util.Objects

class BardRequest(
Expand Down
27 changes: 27 additions & 0 deletions feature/bardapi/src/main/java/com/pkslow/ai/domain/Image.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* This file is part of Cosmic IDE.
* Cosmic IDE is a free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
* Cosmic IDE is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
* You should have received a copy of the GNU General Public License along with Foobar. If not, see <https://www.gnu.org/licenses/>.
*/
package com.pkslow.ai.domain

data class Image(val url: String, val label: String, val article: String) {
fun markdown(): String {
val sb = StringBuilder()
sb.append("\n")
sb.append("[!")
sb.append(label)
sb.append("(")
sb.append(url)
sb.append(")](")
sb.append(article)
sb.append(")")
return sb.toString()
}

fun labelRegex(): String {
val temp = label.substring(1, label.length - 1)
return "\\[$temp\\]"
}
}
66 changes: 39 additions & 27 deletions feature/bardapi/src/main/java/com/pkslow/ai/utils/BardUtils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,22 @@
* Cosmic IDE is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
* You should have received a copy of the GNU General Public License along with Foobar. If not, see <https://www.gnu.org/licenses/>.
*/
package com.pkslow.ai.util
package com.pkslow.ai.utils

import com.google.gson.Gson
import com.google.gson.JsonArray
import com.pkslow.ai.domain.Answer
import com.pkslow.ai.domain.AnswerStatus
import com.pkslow.ai.domain.BardRequest
import com.pkslow.ai.domain.BardResponse
import com.pkslow.ai.util.Constants.ASK_QUESTION_PATH
import com.pkslow.ai.util.Constants.BARD_VERSION
import com.pkslow.ai.util.Constants.BASE_URL
import com.pkslow.ai.util.Constants.CONTENT_TYPE
import com.pkslow.ai.util.Constants.HOSTNAME
import com.pkslow.ai.util.Constants.TOKEN_COOKIE_NAME
import com.pkslow.ai.util.Constants.USER_AGENT
import com.pkslow.ai.domain.Image
import com.pkslow.ai.utils.Constants.ASK_QUESTION_PATH
import com.pkslow.ai.utils.Constants.BARD_VERSION
import com.pkslow.ai.utils.Constants.BASE_URL
import com.pkslow.ai.utils.Constants.CONTENT_TYPE
import com.pkslow.ai.utils.Constants.HOSTNAME
import com.pkslow.ai.utils.Constants.TOKEN_COOKIE_NAME
import com.pkslow.ai.utils.Constants.USER_AGENT
import okhttp3.FormBody
import okhttp3.HttpUrl
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
Expand Down Expand Up @@ -58,11 +59,11 @@ object BardUtils {
}

fun genQueryStringParamsForAsk(): Map<String, String> {
var randonNum = ThreadLocalRandom.current().nextInt(0, 10000)
randonNum = randonNum + 100000
var randomNum = ThreadLocalRandom.current().nextInt(0, 10000)
randomNum += 100000
val params: MutableMap<String, String> = HashMap()
params["bl"] = BARD_VERSION
params["_reqid"] = randonNum.toString()
params["_reqid"] = randomNum.toString()
params["rt"] = "c"
return params
}
Expand All @@ -81,8 +82,8 @@ object BardUtils {
/**
* remove backslash \ in answer string
*/
fun removeBackslash(answerStr: String): String {
var answerStr = answerStr
fun removeBackslash(answer: String): String {
var answerStr = answer
answerStr = answerStr.replace("\\\\n", "\n")
answerStr = answerStr.replace("\\", "\"")
return answerStr
Expand All @@ -98,11 +99,13 @@ object BardUtils {
}

fun buildRequestBodyForAsk(bardRequest: BardRequest): RequestBody {
val question: String = bardRequest.question.replace("\"", "\\\\\\\"")

return FormBody.Builder()
.add(
"f.req", String.format(
"[null,\"[[\\\"%s\\\"],null,[\\\"%s\\\",\\\"%s\\\",\\\"%s\\\"]]\"]",
bardRequest.question,
question,
bardRequest.conversationId,
bardRequest.responseId,
bardRequest.choiceId
Expand All @@ -125,28 +128,37 @@ object BardUtils {
)
val element3 = (jsonArray[0] as JsonArray)[2]
val content3 = element3.asString
val jsonArray3 = Gson().fromJson(
val chatData = Gson().fromJson(
content3,
JsonArray::class.java
)
conversationId = (jsonArray3[1] as JsonArray)[0].asString
responseId = (jsonArray3[1] as JsonArray)[1].asString
var chosenAnswer = (jsonArray3[0] as JsonArray)[0].asString
conversationId = (chatData[1] as JsonArray)[0].asString
responseId = (chatData[1] as JsonArray)[1].asString
var chosenAnswer = ((chatData[4] as JsonArray)[0] as JsonArray)[1].asString
chosenAnswer = removeBackslash(chosenAnswer)
answer.chosenAnswer = chosenAnswer

// somehow get the other drafts
// ???
choiceId = ((jsonArray3[4] as JsonArray)[0] as JsonArray)[0].asString
choiceId = ((chatData[4] as JsonArray)[0] as JsonArray)[0].asString

val images = mutableListOf<Image>()
try {
val imageURL =
((((((jsonArray3[4] as JsonArray)[0] as JsonArray)[4] as JsonArray)[0] as JsonArray)[3] as JsonArray)[0] as JsonArray)[0].asString
val articleURL =
((((((jsonArray3[4] as JsonArray)[0] as JsonArray)[4] as JsonArray)[0] as JsonArray)[1] as JsonArray)[0] as JsonArray)[0].asString
answer.imageURL = imageURL
answer.articleURL = articleURL
} catch (e: Exception) {
val imagesJson = ((chatData[4] as JsonArray)[0] as JsonArray)[4] as JsonArray

for (i in 0 until imagesJson.size()) {
val imageJson = imagesJson[i] as JsonArray
val url = ((imageJson[0] as JsonArray)[0] as JsonArray)[0].asString
val markdownLabel = imageJson[2].asString
val articleURL = ((imageJson[1] as JsonArray)[0] as JsonArray)[0].asString
val image = Image(url, markdownLabel, articleURL)
// log.debug("Received image: {}", image);
images.add(image)
}
} catch (_: Exception) {
}

answer.images = images
} catch (e: Exception) {
answer.status = AnswerStatus.NO_ANSWER
return BardResponse(conversationId!!, responseId!!, choiceId!!, answer)
Expand All @@ -156,6 +168,6 @@ object BardUtils {
}

fun isEmpty(str: String?): Boolean {
return str == null || str.length == 0
return str.isNullOrEmpty()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* Cosmic IDE is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
* You should have received a copy of the GNU General Public License along with Foobar. If not, see <https://www.gnu.org/licenses/>.
*/
package com.pkslow.ai.util
package com.pkslow.ai.utils

object Constants {
const val HOSTNAME = "bard.google.com"
Expand All @@ -15,6 +15,6 @@ object Constants {
const val USER_AGENT =
"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36"
const val TOKEN_COOKIE_NAME = "__Secure-1PSID"
const val BARD_VERSION = "boq_assistant-bard-web-server_20230530.14_p0"
const val BARD_VERSION = "boq_assistant-bard-web-server_20230625.15_p0"
const val EMPTY_STRING = ""
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* Cosmic IDE is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
* You should have received a copy of the GNU General Public License along with Foobar. If not, see <https://www.gnu.org/licenses/>.
*/
package com.pkslow.ai.util
package com.pkslow.ai.utils

object NetworkUtils {
fun setUpProxy(host: String?, port: String?) {
Expand Down
5 changes: 2 additions & 3 deletions feature/bardapi/src/main/java/com/pkslow/ai/utils/WebUtils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,17 @@
* Cosmic IDE is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
* You should have received a copy of the GNU General Public License along with Foobar. If not, see <https://www.gnu.org/licenses/>.
*/
package com.pkslow.ai.util
package com.pkslow.ai.utils

import okhttp3.OkHttpClient
import java.time.Duration

object WebUtils {
fun okHttpClientWithTimeout(timeout: Duration): OkHttpClient {
val client: OkHttpClient = OkHttpClient.Builder()
return OkHttpClient.Builder()
.callTimeout(timeout)
.readTimeout(timeout)
.connectTimeout(timeout)
.build()
return client
}
}

0 comments on commit 0f6a65b

Please sign in to comment.