Merge remote-tracking branch 'origin/dev' into dev

This commit is contained in:
SwallowGG
2023-09-28 16:57:24 +08:00
50 changed files with 1866 additions and 341 deletions

View File

@ -21,8 +21,8 @@ import ai.chat2db.server.tools.common.exception.ParamBusinessException;
import ai.chat2db.server.tools.common.util.EasyEnumUtils;
import ai.chat2db.server.web.api.aspect.ConnectionInfoAspect;
import ai.chat2db.server.web.api.controller.ai.azure.client.AzureOpenAIClient;
import ai.chat2db.server.web.api.controller.ai.azure.models.AzureChatMessage;
import ai.chat2db.server.web.api.controller.ai.azure.models.AzureChatRole;
import ai.chat2db.server.web.api.controller.ai.azure.model.AzureChatMessage;
import ai.chat2db.server.web.api.controller.ai.azure.model.AzureChatRole;
import ai.chat2db.server.web.api.controller.ai.chat2db.client.Chat2dbAIClient;
import ai.chat2db.server.web.api.controller.ai.claude.client.ClaudeAIClient;
import ai.chat2db.server.web.api.controller.ai.claude.model.ClaudeChatCompletionsOptions;
@ -30,15 +30,19 @@ import ai.chat2db.server.web.api.controller.ai.claude.model.ClaudeChatMessage;
import ai.chat2db.server.web.api.controller.ai.config.LocalCache;
import ai.chat2db.server.web.api.controller.ai.converter.ChatConverter;
import ai.chat2db.server.web.api.controller.ai.enums.PromptType;
import ai.chat2db.server.web.api.controller.ai.listener.AzureOpenAIEventSourceListener;
import ai.chat2db.server.web.api.controller.ai.listener.ClaudeAIEventSourceListener;
import ai.chat2db.server.web.api.controller.ai.listener.OpenAIEventSourceListener;
import ai.chat2db.server.web.api.controller.ai.listener.RestAIEventSourceListener;
import ai.chat2db.server.web.api.controller.ai.azure.listener.AzureOpenAIEventSourceListener;
import ai.chat2db.server.web.api.controller.ai.claude.listener.ClaudeAIEventSourceListener;
import ai.chat2db.server.web.api.controller.ai.fastchat.client.FastChatAIClient;
import ai.chat2db.server.web.api.controller.ai.fastchat.listener.FastChatAIEventSourceListener;
import ai.chat2db.server.web.api.controller.ai.fastchat.model.FastChatMessage;
import ai.chat2db.server.web.api.controller.ai.fastchat.model.FastChatRole;
import ai.chat2db.server.web.api.controller.ai.openai.listener.OpenAIEventSourceListener;
import ai.chat2db.server.web.api.controller.ai.rest.listener.RestAIEventSourceListener;
import ai.chat2db.server.web.api.controller.ai.request.ChatQueryRequest;
import ai.chat2db.server.web.api.controller.ai.request.ChatRequest;
import ai.chat2db.server.web.api.controller.ai.rest.client.RestAIClient;
import ai.chat2db.server.web.api.util.ApplicationContextUtil;
import ai.chat2db.server.web.api.util.OpenAIClient;
import ai.chat2db.server.web.api.controller.ai.openai.client.OpenAIClient;
import ai.chat2db.spi.model.TableColumn;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
@ -218,6 +222,8 @@ public class ChatController {
return chatWithAzureAi(queryRequest, sseEmitter, uid);
case CLAUDEAI:
return chatWithClaudeAi(queryRequest, sseEmitter, uid);
case FASTCHATAI:
return chatWithFastChatAi(queryRequest, sseEmitter, uid);
}
return chatWithOpenAi(queryRequest, sseEmitter, uid);
}
@ -332,6 +338,36 @@ public class ChatController {
return sseEmitter;
}
/**
* chat with fast chat openai
*
* @param queryRequest
* @param sseEmitter
* @param uid
* @return
* @throws IOException
*/
private SseEmitter chatWithFastChatAi(ChatQueryRequest queryRequest, SseEmitter sseEmitter, String uid) throws IOException {
String prompt = buildPrompt(queryRequest);
List<FastChatMessage> messages = (List<FastChatMessage>)LocalCache.CACHE.get(uid);
if (CollectionUtils.isNotEmpty(messages)) {
if (messages.size() >= contextLength) {
messages = messages.subList(1, contextLength);
}
} else {
messages = Lists.newArrayList();
}
FastChatMessage currentMessage = new FastChatMessage(FastChatRole.USER).setContent(prompt);
messages.add(currentMessage);
buildSseEmitter(sseEmitter, uid);
FastChatAIEventSourceListener sourceListener = new FastChatAIEventSourceListener(sseEmitter);
FastChatAIClient.getInstance().streamCompletions(messages, sourceListener);
LocalCache.CACHE.put(uid, messages, LocalCache.TIMEOUT);
return sseEmitter;
}
/**
* chat with claude ai

View File

@ -6,8 +6,8 @@ import java.util.concurrent.TimeUnit;
import ai.chat2db.server.tools.common.exception.ParamBusinessException;
import ai.chat2db.server.web.api.controller.ai.azure.interceptor.AzureHeaderAuthorizationInterceptor;
import ai.chat2db.server.web.api.controller.ai.azure.models.AzureChatCompletionsOptions;
import ai.chat2db.server.web.api.controller.ai.azure.models.AzureChatMessage;
import ai.chat2db.server.web.api.controller.ai.azure.model.AzureChatCompletionsOptions;
import ai.chat2db.server.web.api.controller.ai.azure.model.AzureChatMessage;
import cn.hutool.http.ContentType;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Getter;

View File

@ -1,13 +1,12 @@
package ai.chat2db.server.web.api.controller.ai.listener;
package ai.chat2db.server.web.api.controller.ai.azure.listener;
import java.io.IOException;
import java.util.Objects;
import ai.chat2db.server.web.api.controller.ai.azure.models.AzureChatChoice;
import ai.chat2db.server.web.api.controller.ai.azure.models.AzureChatCompletions;
import ai.chat2db.server.web.api.controller.ai.azure.models.AzureChatMessage;
import ai.chat2db.server.web.api.controller.ai.azure.models.AzureCompletionsUsage;
import ai.chat2db.server.web.api.controller.ai.response.ChatCompletionResponse;
import ai.chat2db.server.web.api.controller.ai.azure.model.AzureChatChoice;
import ai.chat2db.server.web.api.controller.ai.azure.model.AzureChatCompletions;
import ai.chat2db.server.web.api.controller.ai.azure.model.AzureChatMessage;
import ai.chat2db.server.web.api.controller.ai.azure.model.AzureCompletionsUsage;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.unfbx.chatgpt.entity.chat.Message;

View File

@ -1,7 +1,7 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
// Code generated by Microsoft (R) AutoRest Code Generator.
package ai.chat2db.server.web.api.controller.ai.azure.models;
package ai.chat2db.server.web.api.controller.ai.azure.model;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;

View File

@ -1,10 +1,9 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
// Code generated by Microsoft (R) AutoRest Code Generator.
package ai.chat2db.server.web.api.controller.ai.azure.models;
package ai.chat2db.server.web.api.controller.ai.azure.model;
import java.util.List;
import java.util.Map;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;

View File

@ -1,4 +1,4 @@
package ai.chat2db.server.web.api.controller.ai.azure.models;
package ai.chat2db.server.web.api.controller.ai.azure.model;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;

View File

@ -1,7 +1,7 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
// Code generated by Microsoft (R) AutoRest Code Generator.
package ai.chat2db.server.web.api.controller.ai.azure.models;
package ai.chat2db.server.web.api.controller.ai.azure.model;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;

View File

@ -1,7 +1,7 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
// Code generated by Microsoft (R) AutoRest Code Generator.
package ai.chat2db.server.web.api.controller.ai.azure.models;
package ai.chat2db.server.web.api.controller.ai.azure.model;
import java.util.Collection;

View File

@ -1,7 +1,7 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
// Code generated by Microsoft (R) AutoRest Code Generator.
package ai.chat2db.server.web.api.controller.ai.azure.models;
package ai.chat2db.server.web.api.controller.ai.azure.model;
import java.util.List;
import java.util.Map;

View File

@ -1,7 +1,7 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
// Code generated by Microsoft (R) AutoRest Code Generator.
package ai.chat2db.server.web.api.controller.ai.azure.models;
package ai.chat2db.server.web.api.controller.ai.azure.model;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;

View File

@ -1,7 +1,7 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
package ai.chat2db.server.web.api.controller.ai.azure.models;
package ai.chat2db.server.web.api.controller.ai.azure.model;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;

View File

@ -1,4 +1,4 @@
package ai.chat2db.server.web.api.controller.ai.listener;
package ai.chat2db.server.web.api.controller.ai.claude.listener;
import ai.chat2db.server.web.api.controller.ai.claude.model.ClaudeCompletionResponse;
import com.fasterxml.jackson.databind.DeserializationFeature;

View File

@ -0,0 +1,75 @@
package ai.chat2db.server.web.api.controller.ai.fastchat.client;
import ai.chat2db.server.domain.api.model.Config;
import ai.chat2db.server.domain.api.service.ConfigService;
import ai.chat2db.server.web.api.util.ApplicationContextUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
/**
* @author moji
* @date 23/09/26
*/
@Slf4j
public class FastChatAIClient {
/**
* FASTCHAT OPENAI KEY
*/
public static final String FASTCHAT_API_KEY = "fastchat.chatgpt.apiKey";
/**
* FASTCHAT OPENAI HOST
*/
public static final String FASTCHAT_HOST = "fastchat.host";
/**
* FASTCHAT OPENAI model
*/
public static final String FASTCHAT_MODEL= "fastchat.model";
private static FastChatAIStreamClient FASTCHAT_AI_CLIENT;
public static FastChatAIStreamClient getInstance() {
if (FASTCHAT_AI_CLIENT != null) {
return FASTCHAT_AI_CLIENT;
} else {
return singleton();
}
}
private static FastChatAIStreamClient singleton() {
if (FASTCHAT_AI_CLIENT == null) {
synchronized (FastChatAIClient.class) {
if (FASTCHAT_AI_CLIENT == null) {
refresh();
}
}
}
return FASTCHAT_AI_CLIENT;
}
public static void refresh() {
String apiKey = "";
String apiHost = "";
String model = "";
ConfigService configService = ApplicationContextUtil.getBean(ConfigService.class);
Config apiHostConfig = configService.find(FASTCHAT_HOST).getData();
if (apiHostConfig != null && StringUtils.isNotBlank(apiHostConfig.getContent())) {
apiHost = apiHostConfig.getContent();
}
Config config = configService.find(FASTCHAT_API_KEY).getData();
if (config != null && StringUtils.isNotBlank(config.getContent())) {
apiKey = config.getContent();
}
Config deployConfig = configService.find(FASTCHAT_MODEL).getData();
if (deployConfig != null && StringUtils.isNotBlank(deployConfig.getContent())) {
model = deployConfig.getContent();
}
FASTCHAT_AI_CLIENT = FastChatAIStreamClient.builder().apiKey(apiKey).apiHost(apiHost).model(model)
.build();
}
}

View File

@ -0,0 +1,187 @@
package ai.chat2db.server.web.api.controller.ai.fastchat.client;
import ai.chat2db.server.tools.common.exception.ParamBusinessException;
import ai.chat2db.server.web.api.controller.ai.fastchat.interceptor.FastChatHeaderAuthorizationInterceptor;
import ai.chat2db.server.web.api.controller.ai.fastchat.model.FastChatCompletionsOptions;
import ai.chat2db.server.web.api.controller.ai.fastchat.model.FastChatMessage;
import cn.hutool.http.ContentType;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.sse.EventSource;
import okhttp3.sse.EventSourceListener;
import okhttp3.sse.EventSources;
import org.apache.commons.collections4.CollectionUtils;
import org.jetbrains.annotations.NotNull;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
/**
* Fast Chat Aligned Client
*
* @author moji
*/
@Slf4j
public class FastChatAIStreamClient {
/**
* apikey
*/
@Getter
@NotNull
private String apiKey;
/**
* apiHost
*/
@Getter
@NotNull
private String apiHost;
/**
* model
*/
@Getter
private String model;
/**
* okHttpClient
*/
@Getter
private OkHttpClient okHttpClient;
/**
* @param builder
*/
private FastChatAIStreamClient(Builder builder) {
this.apiKey = builder.apiKey;
this.apiHost = builder.apiHost;
this.model = builder.model;
if (Objects.isNull(builder.okHttpClient)) {
builder.okHttpClient = this.okHttpClient();
}
okHttpClient = builder.okHttpClient;
}
/**
* okhttpclient
*/
private OkHttpClient okHttpClient() {
OkHttpClient okHttpClient = new OkHttpClient
.Builder()
.addInterceptor(new FastChatHeaderAuthorizationInterceptor(this.apiKey))
.connectTimeout(10, TimeUnit.SECONDS)
.writeTimeout(50, TimeUnit.SECONDS)
.readTimeout(50, TimeUnit.SECONDS)
.build();
return okHttpClient;
}
/**
* 构造
*
* @return
*/
public static FastChatAIStreamClient.Builder builder() {
return new FastChatAIStreamClient.Builder();
}
/**
* builder
*/
public static final class Builder {
private String apiKey;
private String apiHost;
private String model;
/**
* OkhttpClient
*/
private OkHttpClient okHttpClient;
public Builder() {
}
public FastChatAIStreamClient.Builder apiKey(String apiKeyValue) {
this.apiKey = apiKeyValue;
return this;
}
/**
* @param apiHostValue
* @return
*/
public FastChatAIStreamClient.Builder apiHost(String apiHostValue) {
this.apiHost = apiHostValue;
return this;
}
/**
* @param modelValue
* @return
*/
public FastChatAIStreamClient.Builder model(String modelValue) {
this.model = modelValue;
return this;
}
public FastChatAIStreamClient.Builder okHttpClient(OkHttpClient val) {
this.okHttpClient = val;
return this;
}
public FastChatAIStreamClient build() {
return new FastChatAIStreamClient(this);
}
}
/**
* 问答接口 stream 形式
*
* @param chatMessages
* @param eventSourceListener
*/
public void streamCompletions(List<FastChatMessage> chatMessages, EventSourceListener eventSourceListener) {
if (CollectionUtils.isEmpty(chatMessages)) {
log.error("param errorFast Chat Prompt cannot be empty");
throw new ParamBusinessException("prompt");
}
if (Objects.isNull(eventSourceListener)) {
log.error("param errorFastChatEventSourceListener cannot be empty");
throw new ParamBusinessException();
}
log.info("Fast Chat AI, prompt:{}", chatMessages.get(chatMessages.size() - 1).getContent());
try {
FastChatCompletionsOptions chatCompletionsOptions = new FastChatCompletionsOptions(chatMessages);
chatCompletionsOptions.setStream(true);
chatCompletionsOptions.setModel(this.model);
EventSource.Factory factory = EventSources.createFactory(this.okHttpClient);
ObjectMapper mapper = new ObjectMapper();
String requestBody = mapper.writeValueAsString(chatCompletionsOptions);
Request request = new Request.Builder()
.url(apiHost)
.post(RequestBody.create(MediaType.parse(ContentType.JSON.getValue()), requestBody))
.build();
//创建事件
EventSource eventSource = factory.newEventSource(request, eventSourceListener);
log.info("finish invoking fast chat ai");
} catch (Exception e) {
log.error("fast chat ai error", e);
eventSourceListener.onFailure(null, e, null);
throw new ParamBusinessException();
}
}
}

View File

@ -0,0 +1,37 @@
package ai.chat2db.server.web.api.controller.ai.fastchat.interceptor;
import cn.hutool.http.ContentType;
import cn.hutool.http.Header;
import lombok.Getter;
import okhttp3.Interceptor;
import okhttp3.Request;
import okhttp3.Response;
import java.io.IOException;
/**
* header apikey
*
* @author grt
* @since 2023-03-23
*/
@Getter
public class FastChatHeaderAuthorizationInterceptor implements Interceptor {
private String apiKey;
public FastChatHeaderAuthorizationInterceptor(String apiKey) {
this.apiKey = apiKey;
}
@Override
public Response intercept(Chain chain) throws IOException {
Request original = chain.request();
Request request = original.newBuilder()
.header("apiKey", apiKey) // replace to your corresponding field and value
.header(Header.CONTENT_TYPE.getValue(), ContentType.JSON.getValue())
.method(original.method(), original.body())
.build();
return chain.proceed(request);
}
}

View File

@ -0,0 +1,148 @@
package ai.chat2db.server.web.api.controller.ai.fastchat.listener;
import ai.chat2db.server.web.api.controller.ai.fastchat.model.FastChatChoice;
import ai.chat2db.server.web.api.controller.ai.fastchat.model.FastChatCompletions;
import ai.chat2db.server.web.api.controller.ai.fastchat.model.FastChatCompletionsUsage;
import ai.chat2db.server.web.api.controller.ai.fastchat.model.FastChatMessage;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.unfbx.chatgpt.entity.chat.Message;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import okhttp3.Response;
import okhttp3.ResponseBody;
import okhttp3.sse.EventSource;
import okhttp3.sse.EventSourceListener;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
import java.io.IOException;
import java.util.Objects;
/**
* 描述OpenAIEventSourceListener
*
* @author https:www.unfbx.com
* @date 2023-02-22
*/
@Slf4j
public class FastChatAIEventSourceListener extends EventSourceListener {
private SseEmitter sseEmitter;
private ObjectMapper mapper = new ObjectMapper().disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
public FastChatAIEventSourceListener(SseEmitter sseEmitter) {
this.sseEmitter = sseEmitter;
}
/**
* {@inheritDoc}
*/
@Override
public void onOpen(EventSource eventSource, Response response) {
log.info("Fast Chat Sse connecting...");
}
/**
* {@inheritDoc}
*/
@SneakyThrows
@Override
public void onEvent(EventSource eventSource, String id, String type, String data) {
log.info("Fast Chat AI response data{}", data);
if (data.equals("[DONE]")) {
log.info("Fast Chat AI closed");
sseEmitter.send(SseEmitter.event()
.id("[DONE]")
.data("[DONE]")
.reconnectTime(3000));
sseEmitter.complete();
return;
}
FastChatCompletions chatCompletions = mapper.readValue(data, FastChatCompletions.class);
String text = "";
log.info("Model={} is created at {}.", chatCompletions.getId(),
chatCompletions.getCreated());
for (FastChatChoice choice : chatCompletions.getChoices()) {
FastChatMessage message = choice.getMessage();
if (message != null) {
log.info("Index: {}, Chat Role: {}", choice.getIndex(), message.getRole());
if (message.getContent() != null) {
text = message.getContent();
}
}
}
FastChatCompletionsUsage usage = chatCompletions.getUsage();
if (usage != null) {
log.info(
"Usage: number of prompt token is {}, number of completion token is {}, and number of total "
+ "tokens in request and response is {}.%n", usage.getPromptTokens(),
usage.getCompletionTokens(), usage.getTotalTokens());
}
Message message = new Message();
message.setContent(text);
sseEmitter.send(SseEmitter.event()
.id(null)
.data(message)
.reconnectTime(3000));
}
@Override
public void onClosed(EventSource eventSource) {
try {
sseEmitter.send(SseEmitter.event()
.id("[DONE]")
.data("[DONE]"));
} catch (IOException e) {
throw new RuntimeException(e);
}
sseEmitter.complete();
log.info("FastChatAI close sse connection...");
}
@Override
public void onFailure(EventSource eventSource, Throwable t, Response response) {
try {
if (Objects.isNull(response)) {
String message = t.getMessage();
Message sseMessage = new Message();
sseMessage.setContent(message);
sseEmitter.send(SseEmitter.event()
.id("[ERROR]")
.data(sseMessage));
sseEmitter.send(SseEmitter.event()
.id("[DONE]")
.data("[DONE]"));
sseEmitter.complete();
return;
}
ResponseBody body = response.body();
String bodyString = Objects.nonNull(t) ? t.getMessage() : "";
if (Objects.nonNull(body)) {
bodyString = body.string();
if (StringUtils.isBlank(bodyString) && Objects.nonNull(t)) {
bodyString = t.getMessage();
}
log.error("Fast Chat AI sse response{}", bodyString);
} else {
log.error("Fast Chat AI sse response{}error{}", response, t);
}
eventSource.cancel();
Message message = new Message();
message.setContent("Fast Chat AI error" + bodyString);
sseEmitter.send(SseEmitter.event()
.id("[ERROR]")
.data(message));
sseEmitter.send(SseEmitter.event()
.id("[DONE]")
.data("[DONE]"));
sseEmitter.complete();
} catch (Exception exception) {
log.error("Fast Chat AI send data error:", exception);
}
}
}

View File

@ -0,0 +1,97 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
// Code generated by Microsoft (R) AutoRest Code Generator.
package ai.chat2db.server.web.api.controller.ai.fastchat.model;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
/**
* The representation of a single prompt completion as part of an overall completions request. Generally, `n` choices
* are generated per provided prompt with a default value of 1. Token limits and other settings may limit the number of
* choices generated.
*/
@Data
public final class FastChatChoice {
/*
* The generated text for a given completions prompt.
*/
@JsonProperty(value = "text")
private String text;
/*
* The ordered index associated with this completions choice.
*/
@JsonProperty(value = "index")
private int index;
/*
* The log probabilities model for tokens associated with this completions choice.
*/
@JsonProperty(value = "message")
private FastChatMessage message;
/*
* Reason for finishing
*/
@JsonProperty(value = "finish_reason")
private FastChatCompletionsFinishReason finishReason;
/**
* Creates an instance of Choice class.
*
* @param text the text value to set.
* @param index the index value to set.
* @param message the message value to set
* @param finishReason the finishReason value to set.
*/
@JsonCreator
private FastChatChoice(
@JsonProperty(value = "text") String text,
@JsonProperty(value = "index") int index,
@JsonProperty(value = "message") FastChatMessage message,
@JsonProperty(value = "finish_reason") FastChatCompletionsFinishReason finishReason) {
this.text = text;
this.index = index;
this.message = message;
this.finishReason = finishReason;
}
/**
* Get the text property: The generated text for a given completions prompt.
*
* @return the text value.
*/
public String getText() {
return this.text;
}
/**
* Get the index property: The ordered index associated with this completions choice.
*
* @return the index value.
*/
public int getIndex() {
return this.index;
}
/**
* Get the logprobs property: The log probabilities model for tokens associated with this completions choice.
*
* @return the logprobs value.
*/
public FastChatMessage getMessage() {
return this.message;
}
/**
* Get the finishReason property: Reason for finishing.
*
* @return the finishReason value.
*/
public FastChatCompletionsFinishReason getFinishReason() {
return this.finishReason;
}
}

View File

@ -0,0 +1,110 @@
package ai.chat2db.server.web.api.controller.ai.fastchat.model;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import java.util.List;
@Data
public class FastChatCompletions {
/*
* A unique identifier associated with this chat completions response.
*/
private String id;
/*
* The first timestamp associated with generation activity for this completions response,
* represented as seconds since the beginning of the Unix epoch of 00:00 on 1 Jan 1970.
*/
private int created;
/**
* model
*/
private String model;
/**
* object
*/
private String object;
/*
* The collection of completions choices associated with this completions response.
* Generally, `n` choices are generated per provided prompt with a default value of 1.
* Token limits and other settings may limit the number of choices generated.
*/
@JsonProperty(value = "choices")
private List<FastChatChoice> choices;
/*
* Usage information for tokens processed and generated as part of this completions operation.
*/
private FastChatCompletionsUsage usage;
/**
* Creates an instance of ChatCompletions class.
*
* @param id the id value to set.
* @param created the created value to set.
* @param choices the choices value to set.
* @param usage the usage value to set.
*/
@JsonCreator
private FastChatCompletions(
@JsonProperty(value = "id") String id,
@JsonProperty(value = "created") int created,
@JsonProperty(value = "model") String model,
@JsonProperty(value = "object") String object,
@JsonProperty(value = "choices") List<FastChatChoice> choices,
@JsonProperty(value = "usage") FastChatCompletionsUsage usage) {
this.id = id;
this.created = created;
this.model = model;
this.object = object;
this.choices = choices;
this.usage = usage;
}
/**
* Get the id property: A unique identifier associated with this chat completions response.
*
* @return the id value.
*/
public String getId() {
return this.id;
}
/**
* Get the created property: The first timestamp associated with generation activity for this completions response,
* represented as seconds since the beginning of the Unix epoch of 00:00 on 1 Jan 1970.
*
* @return the created value.
*/
public int getCreated() {
return this.created;
}
/**
* Get the choices property: The collection of completions choices associated with this completions response.
* Generally, `n` choices are generated per provided prompt with a default value of 1. Token limits and other
* settings may limit the number of choices generated.
*
* @return the choices value.
*/
public List<FastChatChoice> getChoices() {
return this.choices;
}
/**
* Get the usage property: Usage information for tokens processed and generated as part of this completions
* operation.
*
* @return the usage value.
*/
public FastChatCompletionsUsage getUsage() {
return this.usage;
}
}

View File

@ -0,0 +1,51 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
// Code generated by Microsoft (R) AutoRest Code Generator.
package ai.chat2db.server.web.api.controller.ai.fastchat.model;
import com.fasterxml.jackson.annotation.JsonCreator;
import java.util.Collection;
/** Representation of the manner in which a completions response concluded. */
public final class FastChatCompletionsFinishReason extends FastChatExpandableStringEnum<FastChatCompletionsFinishReason> {
/** Completions ended normally and reached its end of token generation. */
public static final FastChatCompletionsFinishReason STOPPED = fromString("stopped");
/** Completions exhausted available token limits before generation could complete. */
public static final FastChatCompletionsFinishReason TOKEN_LIMIT_REACHED = fromString("tokenLimitReached");
/**
* Completions generated a response that was identified as potentially sensitive per content moderation policies.
*/
public static final FastChatCompletionsFinishReason CONTENT_FILTERED = fromString("contentFiltered");
/**
* Creates a new instance of CompletionsFinishReason value.
*
* @deprecated Use the {@link #fromString(String)} factory method.
*/
@Deprecated
public FastChatCompletionsFinishReason() {}
/**
* Creates or finds a CompletionsFinishReason from its string representation.
*
* @param name a name to look for.
* @return the corresponding CompletionsFinishReason.
*/
@JsonCreator
public static FastChatCompletionsFinishReason fromString(String name) {
return fromString(name, FastChatCompletionsFinishReason.class);
}
/**
* Gets known CompletionsFinishReason values.
*
* @return known CompletionsFinishReason values.
*/
public static Collection<FastChatCompletionsFinishReason> values() {
return values(FastChatCompletionsFinishReason.class);
}
}

View File

@ -0,0 +1,92 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
// Code generated by Microsoft (R) AutoRest Code Generator.
package ai.chat2db.server.web.api.controller.ai.fastchat.model;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import java.util.List;
/**
* The configuration information for a chat completions request. Completions support a wide variety of tasks and
* generate text that continues from or "completes" provided prompt data.
*/
@Data
public final class FastChatCompletionsOptions {
/*
* The collection of context messages associated with this chat completions request.
* Typical usage begins with a chat message for the System role that provides instructions for
* the behavior of the assistant, followed by alternating messages between the User and
* Assistant roles.
*/
private List<FastChatMessage> messages;
/*
* A value indicating whether chat completions should be streamed for this request.
*/
private Boolean stream;
//
/*
* The model name to provide as part of this completions request.
* Not applicable to Fast Chat AI, where deployment information should be included in the Fast Chat
* resource URI that's connected to.
*/
private String model;
/**
* Creates an instance of ChatCompletionsOptions class.
*
* @param messages the messages value to set.
*/
@JsonCreator
public FastChatCompletionsOptions(@JsonProperty(value = "messages") List<FastChatMessage> messages) {
this.messages = messages;
}
/**
* Get the stream property: A value indicating whether chat completions should be streamed for this request.
*
* @return the stream value.
*/
public Boolean isStream() {
return this.stream;
}
/**
* Set the stream property: A value indicating whether chat completions should be streamed for this request.
*
* @param stream the stream value to set.
* @return the ChatCompletionsOptions object itself.
*/
public FastChatCompletionsOptions setStream(Boolean stream) {
this.stream = stream;
return this;
}
/**
* Get the model property: The model name to provide as part of this completions request. Not applicable to Fast Chat AI,
* where deployment information should be included in the Fast Chat AI resource URI that's connected to.
*
* @return the model value.
*/
public String getModel() {
return this.model;
}
/**
* Set the model property: The model name to provide as part of this completions request. Not applicable to Fast Chat AI,
* where deployment information should be included in the Fast Chat AI resource URI that's connected to.
*
* @param model the model value to set.
* @return the ChatCompletionsOptions object itself.
*/
public FastChatCompletionsOptions setModel(String model) {
this.model = model;
return this;
}
}

View File

@ -0,0 +1,78 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
// Code generated by Microsoft (R) AutoRest Code Generator.
package ai.chat2db.server.web.api.controller.ai.fastchat.model;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
/**
* Representation of the token counts processed for a completions request. Counts consider all tokens across prompts,
* choices, choice alternates, best_of generations, and other consumers.
*/
@Data
public final class FastChatCompletionsUsage {
/*
* The number of tokens generated across all completions emissions.
*/
@JsonProperty(value = "completion_tokens")
private int completionTokens;
/*
* The number of tokens in the provided prompts for the completions request.
*/
@JsonProperty(value = "prompt_tokens")
private int promptTokens;
/*
* The total number of tokens processed for the completions request and response.
*/
@JsonProperty(value = "total_tokens")
private int totalTokens;
/**
* Creates an instance of CompletionsUsage class.
*
* @param completionTokens the completionTokens value to set.
* @param promptTokens the promptTokens value to set.
* @param totalTokens the totalTokens value to set.
*/
@JsonCreator
private FastChatCompletionsUsage(
@JsonProperty(value = "completion_tokens") int completionTokens,
@JsonProperty(value = "prompt_tokens") int promptTokens,
@JsonProperty(value = "total_tokens") int totalTokens) {
this.completionTokens = completionTokens;
this.promptTokens = promptTokens;
this.totalTokens = totalTokens;
}
/**
* Get the completionTokens property: The number of tokens generated across all completions emissions.
*
* @return the completionTokens value.
*/
public int getCompletionTokens() {
return this.completionTokens;
}
/**
* Get the promptTokens property: The number of tokens in the provided prompts for the completions request.
*
* @return the promptTokens value.
*/
public int getPromptTokens() {
return this.promptTokens;
}
/**
* Get the totalTokens property: The total number of tokens processed for the completions request and response.
*
* @return the totalTokens value.
*/
public int getTotalTokens() {
return this.totalTokens;
}
}

View File

@ -0,0 +1,147 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
package ai.chat2db.server.web.api.controller.ai.fastchat.model;
import ai.chat2db.server.web.api.controller.ai.azure.util.AzureReflectionUtils;
import com.fasterxml.jackson.annotation.JsonValue;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import static java.lang.invoke.MethodType.methodType;
/**
* Base implementation for expandable, single string enums.
*
* @param <T> a specific expandable enum type
*/
public abstract class FastChatExpandableStringEnum<T extends FastChatExpandableStringEnum<T>> {
private static final Map<Class<?>, MethodHandle> CONSTRUCTORS = new ConcurrentHashMap<>();
private static final Map<Class<?>, ConcurrentHashMap<String, ? extends FastChatExpandableStringEnum<?>>> VALUES
= new ConcurrentHashMap<>();
private static final Logger LOGGER = LoggerFactory.getLogger(FastChatExpandableStringEnum.class);
private String name;
private Class<T> clazz;
/**
* Creates a new instance of {@link FastChatExpandableStringEnum} without a {@link #toString()} value.
* <p>
* This constructor shouldn't be called as it will produce a {@link FastChatExpandableStringEnum} which doesn't
* have a String enum value.
*
* @deprecated Use the {@link #fromString(String, Class)} factory method.
*/
@Deprecated
public FastChatExpandableStringEnum() {
}
/**
* Creates an instance of the specific expandable string enum from a String.
*
* @param name The value to create the instance from.
* @param clazz The class of the expandable string enum.
* @param <T> the class of the expandable string enum.
* @return The expandable string enum instance.
*
* @throws RuntimeException wrapping implementation class constructor exception (if any is thrown).
*/
@SuppressWarnings({"unchecked", "deprecation"})
protected static <T extends FastChatExpandableStringEnum<T>> T fromString(String name, Class<T> clazz) {
if (name == null) {
return null;
}
ConcurrentHashMap<String, ?> clazzValues = VALUES.computeIfAbsent(clazz, key -> new ConcurrentHashMap<>());
T value = (T) clazzValues.get(name);
if (value != null) {
return value;
} else {
MethodHandle ctor = CONSTRUCTORS.computeIfAbsent(clazz, FastChatExpandableStringEnum::getDefaultConstructor);
if (ctor == null) {
// logged in ExpandableStringEnum::getDefaultConstructor
return null;
}
try {
value = (T) ctor.invoke();
} catch (Throwable e) {
LOGGER.warn("Failed to create {}, default constructor threw exception", clazz.getName(), e);
return null;
}
return value.nameAndAddValue(name, value, clazz);
}
}
private static <T> MethodHandle getDefaultConstructor(Class<T> clazz) {
try {
MethodHandles.Lookup lookup = AzureReflectionUtils.getLookupToUse(clazz);
return lookup.findConstructor(clazz, methodType(void.class));
} catch (NoSuchMethodException | IllegalAccessException e) {
LOGGER.info("Can't find or access default constructor for {}", clazz.getName(), e);
} catch (Exception e) {
LOGGER.info("Failed to get lookup for {}", clazz.getName(), e);
}
return null;
}
@SuppressWarnings("unchecked")
T nameAndAddValue(String name, T value, Class<T> clazz) {
this.name = name;
this.clazz = clazz;
((ConcurrentHashMap<String, T>) VALUES.get(clazz)).put(name, value);
return (T) this;
}
/**
* Gets a collection of all known values to an expandable string enum type.
*
* @param clazz the class of the expandable string enum.
* @param <T> the class of the expandable string enum.
* @return A collection of all known values for the given {@code clazz}.
*/
@SuppressWarnings("unchecked")
protected static <T extends FastChatExpandableStringEnum<T>> Collection<T> values(Class<T> clazz) {
return new ArrayList<T>((Collection<T>) VALUES.getOrDefault(clazz, new ConcurrentHashMap<>()).values());
}
@Override
@JsonValue
public String toString() {
return this.name;
}
@Override
public int hashCode() {
return Objects.hash(this.clazz, this.name);
}
@SuppressWarnings("unchecked")
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
} else if (clazz == null || !clazz.isAssignableFrom(obj.getClass())) {
return false;
} else if (obj == this) {
return true;
} else if (this.name == null) {
return ((FastChatExpandableStringEnum<T>) obj).name == null;
} else {
return this.name.equals(((FastChatExpandableStringEnum<T>) obj).name);
}
}
}

View File

@ -0,0 +1,61 @@
package ai.chat2db.server.web.api.controller.ai.fastchat.model;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
@Data
public class FastChatMessage {
/*
* The role associated with this message payload.
*/
@JsonProperty(value = "role")
private FastChatRole role;
/*
* The text associated with this message payload.
*/
@JsonProperty(value = "content")
private String content;
/**
* Creates an instance of ChatMessage class.
*
* @param role the role value to set.
*/
@JsonCreator
public FastChatMessage(@JsonProperty(value = "role") FastChatRole role) {
this.role = role;
}
/**
* Get the role property: The role associated with this message payload.
*
* @return the role value.
*/
public FastChatRole getRole() {
return this.role;
}
/**
* Get the content property: The text associated with this message payload.
*
* @return the content value.
*/
public String getContent() {
return this.content;
}
/**
* Set the content property: The text associated with this message payload.
*
* @param content the content value to set.
* @return the ChatMessage object itself.
*/
public FastChatMessage setContent(String content) {
this.content = content;
return this;
}
}

View File

@ -0,0 +1,46 @@
package ai.chat2db.server.web.api.controller.ai.fastchat.model;
import com.fasterxml.jackson.annotation.JsonCreator;
import java.util.Collection;
public class FastChatRole extends FastChatExpandableStringEnum<FastChatRole> {
/** The role that instructs or sets the behavior of the assistant. */
public static final FastChatRole SYSTEM = fromString("system");
/** The role that provides responses to system-instructed, user-prompted input. */
public static final FastChatRole ASSISTANT = fromString("assistant");
/** The role that provides input for chat completions. */
public static final FastChatRole USER = fromString("user");
/**
* Creates a new instance of ChatRole value.
*
* @deprecated Use the {@link #fromString(String)} factory method.
*/
@Deprecated
public FastChatRole() {}
/**
* Creates or finds a ChatRole from its string representation.
*
* @param name a name to look for.
* @return the corresponding ChatRole.
*/
@JsonCreator
public static FastChatRole fromString(String name) {
return fromString(name, FastChatRole.class);
}
/**
* Gets known ChatRole values.
*
* @return known ChatRole values.
*/
public static Collection<FastChatRole> values() {
return values(FastChatRole.class);
}
}

View File

@ -1,5 +1,5 @@
package ai.chat2db.server.web.api.util;
package ai.chat2db.server.web.api.controller.ai.openai.client;
import java.net.InetSocketAddress;
import java.net.Proxy;
@ -8,6 +8,7 @@ import java.util.Objects;
import ai.chat2db.server.domain.api.model.Config;
import ai.chat2db.server.domain.api.service.ConfigService;
import ai.chat2db.server.web.api.util.ApplicationContextUtil;
import com.google.common.collect.Lists;
import com.unfbx.chatgpt.OpenAiStreamClient;
import com.unfbx.chatgpt.constant.OpenAIConst;

View File

@ -14,10 +14,11 @@ import ai.chat2db.server.tools.base.wrapper.result.DataResult;
import ai.chat2db.server.web.api.aspect.ConnectionInfoAspect;
import ai.chat2db.server.web.api.controller.ai.azure.client.AzureOpenAIClient;
import ai.chat2db.server.web.api.controller.ai.chat2db.client.Chat2dbAIClient;
import ai.chat2db.server.web.api.controller.ai.fastchat.client.FastChatAIClient;
import ai.chat2db.server.web.api.controller.ai.rest.client.RestAIClient;
import ai.chat2db.server.web.api.controller.config.request.AIConfigCreateRequest;
import ai.chat2db.server.web.api.controller.config.request.SystemConfigRequest;
import ai.chat2db.server.web.api.util.OpenAIClient;
import ai.chat2db.server.web.api.controller.ai.openai.client.OpenAIClient;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
@ -83,6 +84,9 @@ public class ConfigController {
case AZUREAI:
saveAzureAIConfig(request);
break;
case FASTCHATAI:
saveFastChatAIConfig(request);
break;
}
return ActionResult.isSuccess();
}
@ -159,6 +163,24 @@ public class ConfigController {
AzureOpenAIClient.refresh();
}
/**
* save common fast chat ai config
*
* @param request
*/
private void saveFastChatAIConfig(AIConfigCreateRequest request) {
SystemConfigParam apikeyParam = SystemConfigParam.builder().code(FastChatAIClient.FASTCHAT_API_KEY)
.content(request.getApiKey()).build();
configService.createOrUpdate(apikeyParam);
SystemConfigParam apiHostParam = SystemConfigParam.builder().code(FastChatAIClient.FASTCHAT_HOST)
.content(request.getApiHost()).build();
configService.createOrUpdate(apiHostParam);
SystemConfigParam modelParam = SystemConfigParam.builder().code(FastChatAIClient.FASTCHAT_MODEL)
.content(request.getModel()).build();
configService.createOrUpdate(modelParam);
FastChatAIClient.refresh();
}
@GetMapping("/system_config/{code}")
public DataResult<Config> getSystemConfig(@PathVariable("code") String code) {
DataResult<Config> result = configService.find(code);
@ -221,6 +243,14 @@ public class ConfigController {
config.setStream(Objects.nonNull(restAiHttpMethod.getData()) ? Boolean.valueOf(
restAiHttpMethod.getData().getContent()) : Boolean.TRUE);
break;
case FASTCHATAI:
DataResult<Config> fastChatApiKey = configService.find(FastChatAIClient.FASTCHAT_API_KEY);
DataResult<Config> fastChatApiHost = configService.find(FastChatAIClient.FASTCHAT_HOST);
DataResult<Config> fastChatModel = configService.find(FastChatAIClient.FASTCHAT_MODEL);
config.setApiKey(Objects.nonNull(fastChatApiKey.getData()) ? fastChatApiKey.getData().getContent() : "");
config.setApiHost(Objects.nonNull(fastChatApiHost.getData()) ? fastChatApiHost.getData().getContent() : "");
config.setModel(Objects.nonNull(fastChatModel.getData()) ? fastChatModel.getData().getContent() : "");
break;
default:
break;
}
@ -228,153 +258,4 @@ public class ConfigController {
return DataResult.of(config);
}
///**
// * save ai config
// *
// * @param request
// * @return
// */
//@PostMapping("/system_config/chatgpt")
//public ActionResult addAiSystemConfig(@RequestBody AISystemConfigRequest request) {
// String sqlSource = StringUtils.isNotBlank(request.getAiSqlSource()) ? request.getAiSqlSource()
// : AiSqlSourceEnum.CHAT2DBAI.getCode();
// AiSqlSourceEnum aiSqlSourceEnum = AiSqlSourceEnum.getByName(sqlSource);
// if (Objects.isNull(aiSqlSourceEnum)) {
// aiSqlSourceEnum = AiSqlSourceEnum.CHAT2DBAI;
// sqlSource = AiSqlSourceEnum.CHAT2DBAI.getCode();
// }
// SystemConfigParam param = SystemConfigParam.builder().code(RestAIClient.AI_SQL_SOURCE).content(sqlSource)
// .build();
// configService.createOrUpdate(param);
//
// switch (Objects.requireNonNull(aiSqlSourceEnum)) {
// case OPENAI :
// saveOpenAIConfig(request);
// break;
// case CHAT2DBAI:
// saveChat2dbAIConfig(request);
// break;
// case RESTAI :
// saveRestAIConfig(request);
// break;
// case AZUREAI :
// saveAzureAIConfig(request);
// break;
// }
// return ActionResult.isSuccess();
//}
//
///**
// * 保存OPENAI相关配置
// *
// * @param request
// */
//private void saveOpenAIConfig(AISystemConfigRequest request) {
// SystemConfigParam param = SystemConfigParam.builder().code(OpenAIClient.OPENAI_KEY).content(
// request.getApiKey()).build();
// configService.createOrUpdate(param);
// SystemConfigParam hostParam = SystemConfigParam.builder().code(OpenAIClient.OPENAI_HOST).content(
// request.getApiHost()).build();
// configService.createOrUpdate(hostParam);
// SystemConfigParam httpProxyHostParam = SystemConfigParam.builder().code(OpenAIClient.PROXY_HOST).content(
// request.getHttpProxyHost()).build();
// configService.createOrUpdate(httpProxyHostParam);
// SystemConfigParam httpProxyPortParam = SystemConfigParam.builder().code(OpenAIClient.PROXY_PORT).content(
// request.getHttpProxyPort()).build();
// configService.createOrUpdate(httpProxyPortParam);
// OpenAIClient.refresh();
//}
//
///**
// * 保存RESTAI接口相关配置
// *
// * @param request
// */
//private void saveRestAIConfig(AISystemConfigRequest request) {
// SystemConfigParam restParam = SystemConfigParam.builder().code(RestAIClient.REST_AI_URL).content(
// request.getRestAiUrl())
// .build();
// configService.createOrUpdate(restParam);
// SystemConfigParam methodParam = SystemConfigParam.builder().code(RestAIClient.REST_AI_STREAM_OUT).content(
// request.getRestAiStream().toString()).build();
// configService.createOrUpdate(methodParam);
// RestAIClient.refresh();
//}
//
///**
// * 保存azure配置
// *
// * @param request
// */
//private void saveAzureAIConfig(AISystemConfigRequest request) {
// SystemConfigParam apikeyParam = SystemConfigParam.builder().code(AzureOpenAIClient.AZURE_CHATGPT_API_KEY)
// .content(
// request.getAzureApiKey()).build();
// configService.createOrUpdate(apikeyParam);
// SystemConfigParam endpointParam = SystemConfigParam.builder().code(AzureOpenAIClient
// .AZURE_CHATGPT_ENDPOINT).content(
// request.getAzureEndpoint()).build();
// configService.createOrUpdate(endpointParam);
// SystemConfigParam modelParam = SystemConfigParam.builder().code(AzureOpenAIClient
// .AZURE_CHATGPT_DEPLOYMENT_ID).content(
// request.getAzureDeploymentId()).build();
// configService.createOrUpdate(modelParam);
// AzureOpenAIClient.refresh();
//}
///**
// * 查询ChatGPT相关配置
// *
// * @return
// */
//@GetMapping("/system_config/chatgpt")
//public DataResult<ChatGptConfig> getChatGptSystemConfig() {
// DataResult<Config> apiKey = configService.find(OpenAIClient.OPENAI_KEY);
// DataResult<Config> apiHost = configService.find(OpenAIClient.OPENAI_HOST);
// DataResult<Config> httpProxyHost = configService.find(OpenAIClient.PROXY_HOST);
// DataResult<Config> httpProxyPort = configService.find(OpenAIClient.PROXY_PORT);
// DataResult<Config> aiSqlSource = configService.find(RestAIClient.AI_SQL_SOURCE);
// DataResult<Config> restAiUrl = configService.find(RestAIClient.REST_AI_URL);
// DataResult<Config> restAiHttpMethod = configService.find(RestAIClient.REST_AI_STREAM_OUT);
// DataResult<Config> azureApiKey = configService.find(AzureOpenAIClient.AZURE_CHATGPT_API_KEY);
// DataResult<Config> azureEndpoint = configService.find(AzureOpenAIClient.AZURE_CHATGPT_ENDPOINT);
// DataResult<Config> azureDeployId = configService.find(AzureOpenAIClient.AZURE_CHATGPT_DEPLOYMENT_ID);
// ChatGptConfig config = new ChatGptConfig();
//
// String sqlSource = Objects.nonNull(aiSqlSource.getData()) ? aiSqlSource.getData().getContent() :
// AiSqlSourceEnum.CHAT2DBAI.getCode();
// AiSqlSourceEnum aiSqlSourceEnum = AiSqlSourceEnum.getByName(sqlSource);
// if (Objects.isNull(aiSqlSourceEnum)) {
// aiSqlSourceEnum = AiSqlSourceEnum.CHAT2DBAI;
// sqlSource = AiSqlSourceEnum.CHAT2DBAI.getCode();
// }
// config.setAiSqlSource(sqlSource);
// switch (Objects.requireNonNull(aiSqlSourceEnum)) {
// case OPENAI :
// config.setApiKey(Objects.nonNull(apiKey.getData()) ? apiKey.getData().getContent() : null);
// config.setApiHost(Objects.nonNull(apiHost.getData()) ? apiHost.getData().getContent() : null);
// config.setChat2dbApiKey("");
// config.setChat2dbApiHost("");
// break;
// case CHAT2DBAI:
// config.setApiKey("");
// config.setApiHost("");
// config.setChat2dbApiKey(Objects.nonNull(apiKey.getData()) ? apiKey.getData().getContent() : null);
// config.setChat2dbApiHost(Objects.nonNull(apiHost.getData()) ? apiHost.getData().getContent() : null);
// break;
// }
// config.setRestAiUrl(Objects.nonNull(restAiUrl.getData()) ? restAiUrl.getData().getContent() : null);
// config.setRestAiStream(Objects.nonNull(restAiHttpMethod.getData()) ? Boolean.valueOf(
// restAiHttpMethod.getData().getContent()) : Boolean.TRUE);
// config.setHttpProxyHost(Objects.nonNull(httpProxyHost.getData()) ? httpProxyHost.getData().getContent() :
// null);
// config.setHttpProxyPort(Objects.nonNull(httpProxyPort.getData()) ? httpProxyPort.getData().getContent() :
// null);
// config.setAzureApiKey(Objects.nonNull(azureApiKey.getData()) ? azureApiKey.getData().getContent() : null);
// config.setAzureEndpoint(Objects.nonNull(azureEndpoint.getData()) ? azureEndpoint.getData().getContent() :
// null);
// config.setAzureDeploymentId(Objects.nonNull(azureDeployId.getData()) ? azureDeployId.getData().getContent()
// : null);
// return DataResult.of(config);
//}
}