AiAutoConfiguration.java 7.7 KB

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