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 <[email protected]>
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 <[email protected]>
    Co-authored-by: Cheng Pan <[email protected]>
    Signed-off-by: Cheng Pan <[email protected]>
---
 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                       | &lt;undefined&gt; 
        | The extra classpath for the Chat engine, for configuring the location 
of the SDK and etc.                                                             
                                                                                
                                                                                
                                                                                
              [...]
 | kyuubi.engine.chat.gpt.apiKey                            | &lt;undefined&gt; 
        | 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                        | &lt;undefined&gt; 
        | 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                          | &lt;undefined&gt; 
        | 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")

Reply via email to