You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@kyuubi.apache.org by ch...@apache.org on 2023/03/17 13:49:09 UTC
[kyuubi] branch master updated: [KYUUBI #4548] Kyuubi Chat Engine supports Chinese questions and HTTP proxy
This is an automated email from the ASF dual-hosted git repository.
chengpan pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/kyuubi.git
The following commit(s) were added to refs/heads/master by this push:
new 6ded07974 [KYUUBI #4548] Kyuubi Chat Engine supports Chinese questions and HTTP proxy
6ded07974 is described below
commit 6ded07974eebcbd8cbba4167a25c80e4549014d6
Author: sychen <sy...@ctrip.com>
AuthorDate: Fri Mar 17 21:48:58 2023 +0800
[KYUUBI #4548] Kyuubi Chat Engine supports Chinese questions and HTTP proxy
### _Why are the changes needed?_
- Support Chinese question
- Support proxy settings
- Support setting timeout
<img width="1228" alt="image" src="https://user-images.githubusercontent.com/3898450/225851246-8762a451-9743-4c1d-8a33-cc49a926dfec.png">
### _How was this patch tested?_
- [ ] Add some test cases that check the changes thoroughly including negative and positive cases if possible
- [x] Add screenshots for manual tests if appropriate
- [x] [Run test](https://kyuubi.readthedocs.io/en/master/develop_tools/testing.html#running-tests) locally before make a pull request
Closes #4548 from cxzl25/chatgpt_followup.
Closes #4548
1d5715442 [Cheng Pan] Update externals/kyuubi-chat-engine/src/main/scala/org/apache/kyuubi/engine/chat/provider/ChatGPTProvider.scala
7add6a733 [Cheng Pan] Update externals/kyuubi-chat-engine/src/main/scala/org/apache/kyuubi/engine/chat/provider/ChatGPTProvider.scala
55974f298 [sychen] fix
2d360e102 [sychen] typo
19b5d0814 [sychen] doc
bdf8e29b6 [sychen] 1.utf8;2.proxy;timeout
Lead-authored-by: sychen <sy...@ctrip.com>
Co-authored-by: Cheng Pan <pa...@gmail.com>
Signed-off-by: Cheng Pan <ch...@apache.org>
---
docs/deployment/settings.md | 3 ++
.../engine/chat/provider/ChatGPTProvider.scala | 33 ++++++++++++++++------
.../org/apache/kyuubi/config/KyuubiConf.scala | 25 ++++++++++++++++
3 files changed, 53 insertions(+), 8 deletions(-)
diff --git a/docs/deployment/settings.md b/docs/deployment/settings.md
index 9c5f76712..db6e3d246 100644
--- a/docs/deployment/settings.md
+++ b/docs/deployment/settings.md
@@ -122,6 +122,9 @@ You can configure the Kyuubi properties in `$KYUUBI_HOME/conf/kyuubi-defaults.co
|----------------------------------------------------------|---------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- [...]
| kyuubi.engine.chat.extra.classpath | <undefined> | The extra classpath for the Chat engine, for configuring the location of the SDK and etc. [...]
| kyuubi.engine.chat.gpt.apiKey | <undefined> | The key to access OpenAI open API, which could be got at https://platform.openai.com/account/api-keys [...]
+| kyuubi.engine.chat.gpt.http.connect.timeout | PT2M | The timeout[ms] for establishing the connection with the Chat GPT server. A timeout value of zero is interpreted as an infinite timeout. [...]
+| kyuubi.engine.chat.gpt.http.proxy | <undefined> | HTTP proxy url for API calling in Chat GPT engine. e.g. http://127.0.0.1:1087 [...]
+| kyuubi.engine.chat.gpt.http.socket.timeout | PT2M | The timeout[ms] for waiting for data packets after Chat GPT server connection is established. A timeout value of zero is interpreted as an infinite timeout. [...]
| kyuubi.engine.chat.java.options | <undefined> | The extra Java options for the Chat engine [...]
| kyuubi.engine.chat.memory | 1g | The heap memory for the Chat engine [...]
| kyuubi.engine.chat.provider | ECHO | The provider for the Chat engine. Candidates: <ul> <li>ECHO: simply replies a welcome message.</li> <li>GPT: a.k.a ChatGPT, powered by OpenAI.</li></ul> [...]
diff --git a/externals/kyuubi-chat-engine/src/main/scala/org/apache/kyuubi/engine/chat/provider/ChatGPTProvider.scala b/externals/kyuubi-chat-engine/src/main/scala/org/apache/kyuubi/engine/chat/provider/ChatGPTProvider.scala
index f948eb154..28ef36bb4 100644
--- a/externals/kyuubi-chat-engine/src/main/scala/org/apache/kyuubi/engine/chat/provider/ChatGPTProvider.scala
+++ b/externals/kyuubi-chat-engine/src/main/scala/org/apache/kyuubi/engine/chat/provider/ChatGPTProvider.scala
@@ -21,9 +21,10 @@ import java.util
import java.util.concurrent.TimeUnit
import com.google.common.cache.{CacheBuilder, CacheLoader, LoadingCache}
-import org.apache.http.HttpStatus
+import org.apache.http.{HttpHost, HttpStatus}
+import org.apache.http.client.config.RequestConfig
import org.apache.http.client.methods.HttpPost
-import org.apache.http.entity.StringEntity
+import org.apache.http.entity.{ContentType, StringEntity}
import org.apache.http.impl.client.{CloseableHttpClient, HttpClientBuilder}
import org.apache.http.util.EntityUtils
@@ -32,9 +33,25 @@ import org.apache.kyuubi.engine.chat.provider.ChatProvider.mapper
class ChatGPTProvider(conf: KyuubiConf) extends ChatProvider {
- val token = conf.get(KyuubiConf.ENGINE_CHAT_GPT_API_KEY).get
+ private val gptApiKey = conf.get(KyuubiConf.ENGINE_CHAT_GPT_API_KEY).getOrElse {
+ throw new IllegalArgumentException(
+ s"'${KyuubiConf.ENGINE_CHAT_GPT_API_KEY.key}' must be configured, " +
+ s"which could be got at https://platform.openai.com/account/api-keys")
+ }
- val httpClient: CloseableHttpClient = HttpClientBuilder.create().build()
+ private val httpClient: CloseableHttpClient = HttpClientBuilder.create().build()
+
+ private val requestConfig = {
+ val connectTimeout = conf.get(KyuubiConf.ENGINE_CHAT_GPT_HTTP_CONNECT_TIMEOUT).asInstanceOf[Int]
+ val socketTimeout = conf.get(KyuubiConf.ENGINE_CHAT_GPT_HTTP_SOCKET_TIMEOUT).asInstanceOf[Int]
+ val builder: RequestConfig.Builder = RequestConfig.custom()
+ .setConnectTimeout(connectTimeout)
+ .setSocketTimeout(socketTimeout)
+ conf.get(KyuubiConf.ENGINE_CHAT_GPT_HTTP_PROXY).foreach { url =>
+ builder.setProxy(HttpHost.create(url))
+ }
+ builder.build()
+ }
private val chatHistory: LoadingCache[String, util.ArrayDeque[Message]] =
CacheBuilder.newBuilder()
@@ -53,8 +70,7 @@ class ChatGPTProvider(conf: KyuubiConf) extends ChatProvider {
messages.addLast(Message("user", q))
val request = new HttpPost("https://api.openai.com/v1/chat/completions")
- request.addHeader("Content-Type", "application/json")
- request.addHeader("Authorization", "Bearer " + token)
+ request.addHeader("Authorization", "Bearer " + gptApiKey)
val req = Map(
"messages" -> messages,
@@ -62,8 +78,9 @@ class ChatGPTProvider(conf: KyuubiConf) extends ChatProvider {
"max_tokens" -> 200,
"temperature" -> 0.5,
"top_p" -> 1)
-
- request.setEntity(new StringEntity(mapper.writeValueAsString(req)))
+ val entity = new StringEntity(mapper.writeValueAsString(req), ContentType.APPLICATION_JSON)
+ request.setEntity(entity)
+ request.setConfig(requestConfig)
val responseEntity = httpClient.execute(request)
val respJson = mapper.readTree(EntityUtils.toString(responseEntity.getEntity))
val statusCode = responseEntity.getStatusLine.getStatusCode
diff --git a/kyuubi-common/src/main/scala/org/apache/kyuubi/config/KyuubiConf.scala b/kyuubi-common/src/main/scala/org/apache/kyuubi/config/KyuubiConf.scala
index b39bee307..35626eea5 100644
--- a/kyuubi-common/src/main/scala/org/apache/kyuubi/config/KyuubiConf.scala
+++ b/kyuubi-common/src/main/scala/org/apache/kyuubi/config/KyuubiConf.scala
@@ -2667,6 +2667,31 @@ object KyuubiConf {
.stringConf
.createOptional
+ val ENGINE_CHAT_GPT_HTTP_PROXY: OptionalConfigEntry[String] =
+ buildConf("kyuubi.engine.chat.gpt.http.proxy")
+ .doc("HTTP proxy url for API calling in Chat GPT engine. e.g. http://127.0.0.1:1087")
+ .version("1.8.0")
+ .stringConf
+ .createOptional
+
+ val ENGINE_CHAT_GPT_HTTP_CONNECT_TIMEOUT: ConfigEntry[Long] =
+ buildConf("kyuubi.engine.chat.gpt.http.connect.timeout")
+ .doc("The timeout[ms] for establishing the connection with the Chat GPT server. " +
+ "A timeout value of zero is interpreted as an infinite timeout.")
+ .version("1.8.0")
+ .timeConf
+ .checkValue(_ >= 0, "must be 0 or positive number")
+ .createWithDefault(Duration.ofSeconds(120).toMillis)
+
+ val ENGINE_CHAT_GPT_HTTP_SOCKET_TIMEOUT: ConfigEntry[Long] =
+ buildConf("kyuubi.engine.chat.gpt.http.socket.timeout")
+ .doc("The timeout[ms] for waiting for data packets after Chat GPT server " +
+ "connection is established. A timeout value of zero is interpreted as an infinite timeout.")
+ .version("1.8.0")
+ .timeConf
+ .checkValue(_ >= 0, "must be 0 or positive number")
+ .createWithDefault(Duration.ofSeconds(120).toMillis)
+
val ENGINE_JDBC_MEMORY: ConfigEntry[String] =
buildConf("kyuubi.engine.jdbc.memory")
.doc("The heap memory for the JDBC query engine")