AiAutoConfiguration.java 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. package jnpf.config;
  2. import com.unfbx.chatgpt.OpenAiClient;
  3. import com.unfbx.chatgpt.function.KeyRandomStrategy;
  4. import com.unfbx.chatgpt.function.KeyStrategyFunction;
  5. import com.unfbx.chatgpt.interceptor.DefaultOpenAiAuthInterceptor;
  6. import com.unfbx.chatgpt.interceptor.OpenAiAuthInterceptor;
  7. import jnpf.constants.AiConstants;
  8. import jnpf.service.OpenAiService;
  9. import jnpf.service.impl.DefaultOpenAiServiceImpl;
  10. import jnpf.service.impl.DisabledOpenAiServiceImpl;
  11. import jnpf.util.AiLimitUtil;
  12. import jnpf.util.StringUtil;
  13. import okhttp3.Authenticator;
  14. import okhttp3.OkHttpClient;
  15. import org.springframework.beans.factory.annotation.Qualifier;
  16. import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
  17. import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
  18. import org.springframework.boot.context.properties.ConfigurationProperties;
  19. import org.springframework.context.annotation.Bean;
  20. import org.springframework.context.annotation.Configuration;
  21. import java.net.InetSocketAddress;
  22. import java.net.PasswordAuthentication;
  23. import java.net.Proxy;
  24. import java.util.concurrent.TimeUnit;
  25. /**
  26. * AI客户端 自动配置
  27. *
  28. * @author JNPF开发平台组
  29. * @copyright 引迈信息技术有限公司
  30. * @date 2024/10/9 14:03
  31. */
  32. @Configuration(proxyBeanMethods = false)
  33. public class AiAutoConfiguration {
  34. @Bean
  35. @ConditionalOnMissingBean
  36. @ConditionalOnProperty(prefix = AiConstants.CONFIGURATION_PREFIX, name = "enabled", havingValue = "false", matchIfMissing = true)
  37. public OpenAiService getDisabledOpenAiService() {
  38. return new DisabledOpenAiServiceImpl();
  39. }
  40. @Configuration(proxyBeanMethods = false)
  41. @ConditionalOnProperty(prefix = AiConstants.CONFIGURATION_PREFIX, name = "enabled", havingValue = "true")
  42. public static class AiEnabledConfiguration{
  43. @Bean
  44. @ConfigurationProperties(prefix = AiConstants.CONFIGURATION_PREFIX)
  45. public AiProperties getAiProperties() {
  46. return new AiProperties();
  47. }
  48. @Bean
  49. public OpenAiService getDefaultOpenAiService(OpenAiClient openAiClient, AiProperties aiProperties) {
  50. return new DefaultOpenAiServiceImpl(openAiClient, aiProperties);
  51. }
  52. @Bean
  53. public AiLimitUtil getAiLimitUtil(AiProperties aiProperties) {
  54. return new AiLimitUtil(aiProperties);
  55. }
  56. @Bean
  57. @ConditionalOnMissingBean
  58. public OpenAiClient getOpenAiClient(@Qualifier(AiConstants.DEFAULT_HTTP_CLIENT_BEAN_NAME) OkHttpClient okHttpClient
  59. , KeyStrategyFunction keyStrategyFunction, OpenAiAuthInterceptor authInterceptor, AiProperties aiProperties) {
  60. String apiHost = aiProperties.getApiHost();
  61. // 需要以 / 结尾
  62. if(!apiHost.isEmpty() && !apiHost.endsWith("/")){
  63. apiHost +="/";
  64. }
  65. // 构造openAiClient
  66. return OpenAiClient.builder()
  67. .apiHost(apiHost)
  68. .apiKey(aiProperties.getApiKey())
  69. .keyStrategy(keyStrategyFunction)
  70. .authInterceptor(authInterceptor)
  71. .okHttpClient(okHttpClient)
  72. .build();
  73. }
  74. /*@Bean
  75. @ConditionalOnMissingBean
  76. public OpenAiStreamClient getOpenAiStreamClient(@Qualifier(AiConstants.DEFAULT_HTTP_CLIENT_BEAN_NAME) OkHttpClient okHttpClient
  77. , KeyStrategyFunction keyStrategyFunction, OpenAiAuthInterceptor authInterceptor, AiProperties aiProperties) {
  78. String apiHost = aiProperties.getApiHost();
  79. // 需要以 / 结尾
  80. if(!apiHost.isEmpty() && !apiHost.endsWith("/")){
  81. apiHost +="/";
  82. }
  83. // 构造openAiClient
  84. return OpenAiStreamClient.builder()
  85. .apiHost(apiHost)
  86. .apiKey(aiProperties.getApiKey())
  87. .keyStrategy(keyStrategyFunction)
  88. .authInterceptor(authInterceptor)
  89. .okHttpClient(okHttpClient)
  90. .build();
  91. }*/
  92. /**
  93. * 多Key选择策略
  94. */
  95. @Bean
  96. @ConditionalOnMissingBean
  97. public KeyStrategyFunction getDefaultOpenAiKeyStrategyFunction() {
  98. return new KeyRandomStrategy();
  99. }
  100. /**
  101. * 认证拦截器
  102. * @see com.unfbx.chatgpt.interceptor.DynamicKeyOpenAiAuthInterceptor 动态移除无效Key
  103. */
  104. @Bean
  105. @ConditionalOnMissingBean
  106. public OpenAiAuthInterceptor getDefaultOpenAiAuthInterceptor() {
  107. return new DefaultOpenAiAuthInterceptor();
  108. }
  109. /**
  110. * 默认okhttpclient
  111. */
  112. @Bean(name = AiConstants.DEFAULT_HTTP_CLIENT_BEAN_NAME)
  113. @ConditionalOnMissingBean(name = AiConstants.DEFAULT_HTTP_CLIENT_BEAN_NAME)
  114. public OkHttpClient getDefaultOpenAiOkHttpClient(AiProperties aiProperties) {
  115. OkHttpClient.Builder builder = new OkHttpClient
  116. .Builder();
  117. if(aiProperties.getProxy() != null
  118. && StringUtil.isNotEmpty(aiProperties.getProxy().getHost()) && aiProperties.getProxy().getPort() != null){
  119. // 设置代理
  120. builder.proxy(new Proxy(aiProperties.getProxy().getType(), new InetSocketAddress(aiProperties.getProxy().getHost(), aiProperties.getProxy().getPort())));
  121. // 设置代理认证
  122. if(StringUtil.isNotEmpty(aiProperties.getProxy().getUsername()) && StringUtil.isNotEmpty(aiProperties.getProxy().getPassword())){
  123. builder.proxyAuthenticator(Authenticator.JAVA_NET_AUTHENTICATOR);
  124. java.net.Authenticator.setDefault(new java.net.Authenticator() {
  125. @Override
  126. protected PasswordAuthentication getPasswordAuthentication() {
  127. // 返回代理的用户名和密码
  128. return new PasswordAuthentication(aiProperties.getProxy().getUsername(), aiProperties.getProxy().getPassword().toCharArray());
  129. }
  130. });
  131. }
  132. }
  133. /*try {
  134. // 创建一个信任所有证书的 TrustManager
  135. final TrustManager[] trustAllCerts = new TrustManager[]{
  136. new X509TrustManager() {
  137. @Override
  138. public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
  139. }
  140. @Override
  141. public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
  142. }
  143. @Override
  144. public X509Certificate[] getAcceptedIssuers() {
  145. return new X509Certificate[]{};
  146. }
  147. }
  148. };
  149. // 安装所有信任管理器
  150. final SSLContext sslContext = SSLContext.getInstance("SSL");
  151. sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
  152. // 创建 OkHttpClient 并配置 SSL socket factory 和 hostname verifier
  153. final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
  154. // 信任所有证书
  155. builder.sslSocketFactory(sslSocketFactory, (X509TrustManager) trustAllCerts[0]);
  156. builder.hostnameVerifier((hostname, session) -> true);
  157. } catch (Exception e) {
  158. throw new RuntimeException(e);
  159. }*/
  160. return builder
  161. .callTimeout(aiProperties.getTimeout(), TimeUnit.SECONDS)
  162. .connectTimeout(aiProperties.getTimeout(), TimeUnit.SECONDS)
  163. .writeTimeout(aiProperties.getTimeout(), TimeUnit.SECONDS)
  164. .readTimeout(aiProperties.getTimeout(), TimeUnit.SECONDS)
  165. .build();
  166. }
  167. }
  168. }