上传备份

master
王兵 1 month ago
parent 388f37de6c
commit ff46e6e846

@ -48,6 +48,12 @@
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.0.M2</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>

@ -1,4 +1,4 @@
package xyz.wbsite.achat.core.chat;
package xyz.wbsite.achat.chat;
import java.util.ArrayList;

@ -1,4 +1,6 @@
package xyz.wbsite.achat.core.chat;
package xyz.wbsite.achat.chat;
import xyz.wbsite.achat.chat.tool.Tool;
import java.util.List;
@ -22,6 +24,9 @@ public class ChatCompletionRequest {
private Double frequency_penalty;
private Object logit_bias;
private String user;
// 工具调用相关字段
private List<Tool> tools;
private String tool_choice;
public String getModel() {
return model;
@ -118,4 +123,20 @@ public class ChatCompletionRequest {
public void setUser(String user) {
this.user = user;
}
public List<Tool> getTools() {
return tools;
}
public void setTools(List<Tool> tools) {
this.tools = tools;
}
public String getTool_choice() {
return tool_choice;
}
public void setTool_choice(String tool_choice) {
this.tool_choice = tool_choice;
}
}

@ -1,4 +1,4 @@
package xyz.wbsite.achat.core.chat;
package xyz.wbsite.achat.chat;
import java.util.ArrayList;
import java.util.List;

@ -1,8 +1,8 @@
package xyz.wbsite.achat.core.chat;
package xyz.wbsite.achat.chat;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
import xyz.wbsite.achat.core.embed.EmbeddingsRequest;
import xyz.wbsite.achat.core.embed.EmbeddingsResponse;
import xyz.wbsite.achat.embed.EmbeddingsRequest;
import xyz.wbsite.achat.embed.EmbeddingsResponse;
public interface ChatService {

@ -1,9 +1,9 @@
package xyz.wbsite.achat.core.chat;
package xyz.wbsite.achat.chat;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
import xyz.wbsite.achat.core.embed.EmbeddingsRequest;
import xyz.wbsite.achat.core.embed.EmbeddingsResponse;
import xyz.wbsite.achat.embed.EmbeddingsRequest;
import xyz.wbsite.achat.embed.EmbeddingsResponse;
import javax.annotation.Resource;
import java.util.Collections;

@ -1,4 +1,4 @@
package xyz.wbsite.achat.core.chat;
package xyz.wbsite.achat.chat;
/**
*

@ -1,4 +1,4 @@
package xyz.wbsite.achat.core.chat;
package xyz.wbsite.achat.chat;
import java.util.ArrayList;
import java.util.List;

@ -1,4 +1,9 @@
package xyz.wbsite.achat.core.chat;
package xyz.wbsite.achat.chat;
import xyz.wbsite.achat.chat.tool.ToolCall;
import java.util.ArrayList;
import java.util.List;
/**
*
@ -11,6 +16,8 @@ public class Message {
private Role role;
private String content;
private String name;
private List<ToolCall> tool_calls;
private String tool_call_id;
public Message() {
}
@ -19,6 +26,8 @@ public class Message {
this.role = builder.role;
this.content = builder.content;
this.name = builder.name;
this.tool_calls = builder.tool_calls;
this.tool_call_id = builder.tool_call_id;
}
public Role getRole() {
@ -45,7 +54,22 @@ public class Message {
this.name = name;
}
// 静态builder方法返回Builder实例
public List<ToolCall> getTool_calls() {
return tool_calls;
}
public void setTool_calls(List<ToolCall> function_call) {
this.tool_calls = function_call;
}
public String getTool_call_id() {
return tool_call_id;
}
public void setTool_call_id(String tool_call_id) {
this.tool_call_id = tool_call_id;
}
public static Builder builder() {
return new Builder();
}
@ -54,6 +78,8 @@ public class Message {
private Role role;
private String content;
private String name;
private List<ToolCall> tool_calls = new ArrayList<>();
private String tool_call_id;
public Builder role(Role role) {
this.role = role;
@ -70,7 +96,21 @@ public class Message {
return this;
}
// 构建Message对象
public Builder tool_calls(List<ToolCall> tool_calls) {
this.tool_calls = tool_calls;
return this;
}
public Builder tool_call_id(String tool_call_id) {
this.tool_call_id = tool_call_id;
return this;
}
public Builder withFunctionCall(java.util.function.Consumer<List<ToolCall>> choicesConsumer) {
choicesConsumer.accept(this.tool_calls);
return this;
}
public Message build() {
return new Message(this);
}

@ -1,4 +1,4 @@
package xyz.wbsite.achat.core.chat;
package xyz.wbsite.achat.chat;
import com.fasterxml.jackson.annotation.JsonValue;
@ -23,13 +23,11 @@ public enum Role {
this.value = value;
}
// 序列化时返回小写字符串
@JsonValue
public String getValue() {
return value;
}
// 反序列化时根据字符串匹配枚举
public static Role fromValue(String value) {
for (Role role : Role.values()) {
if (role.value.equalsIgnoreCase(value)) {
@ -38,4 +36,9 @@ public enum Role {
}
throw new IllegalArgumentException("Invalid Role value: " + value);
}
@Override
public String toString() {
return this.value;
}
}

@ -1,4 +1,4 @@
package xyz.wbsite.achat.core.chat;
package xyz.wbsite.achat.chat;
/**
*

@ -1,4 +1,4 @@
package xyz.wbsite.achat.core.chat;
package xyz.wbsite.achat.chat;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

@ -1,4 +1,4 @@
package xyz.wbsite.achat.core.chat;
package xyz.wbsite.achat.chat;
/**
* 使

@ -0,0 +1,37 @@
package xyz.wbsite.achat.chat.tool;
/**
*
*
* @author wangbing
* @version 0.0.1
* @since 1.8
*/
public class Arg {
/**
*
*/
private String type;
/**
*
*/
private String description;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}

@ -0,0 +1,77 @@
package xyz.wbsite.achat.chat.tool;
/**
* - OpenAIAPI
*
* @author wangbing
* @version 0.0.1
* @since 1.8
*/
public class Function {
private String name;
private String description;
private Parameters parameters;
public Function() {
}
private Function(Builder builder) {
this.name = builder.name;
this.description = builder.description;
this.parameters = builder.parameters;
}
public static Builder builder() {
return new Builder();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Parameters getParameters() {
return parameters;
}
public void setParameters(Parameters parameters) {
this.parameters = parameters;
}
public static class Builder {
private String name;
private String description;
private Parameters parameters;
public Builder name(String name) {
this.name = name;
return this;
}
public Builder description(String description) {
this.description = description;
return this;
}
public Builder parameters(Parameters parameters) {
this.parameters = parameters;
return this;
}
public Function build() {
return new Function(this);
}
}
}

@ -0,0 +1,70 @@
package xyz.wbsite.achat.chat.tool;
/**
*
*
* @author wangbing
* @version 0.0.1
* @since 1.8
*/
public class FunctionCall {
/**
*
*/
private String name;
/**
*
* <p>
* {\"arg0\":\"泰州\"}
*/
private String arguments;
public FunctionCall() {
}
private FunctionCall(Builder builder) {
this.name = builder.name;
this.arguments = builder.arguments;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getArguments() {
return arguments;
}
public void setArguments(String arguments) {
this.arguments = arguments;
}
public static Builder builder() {
return new Builder();
}
public static class Builder {
private String name;
private String arguments;
public Builder name(String name) {
this.name = name;
return this;
}
public Builder arguments(String arguments) {
this.arguments = arguments;
return this;
}
public FunctionCall build() {
return new FunctionCall(this);
}
}
}

@ -0,0 +1,51 @@
package xyz.wbsite.achat.chat.tool;
import java.util.List;
/**
*
*
* @author wangbing
* @version 0.0.1
* @since 1.8
*/
/**
*
*
* @author wangbing
* @version 0.0.1
* @since 1.8
*/
public class Parameters {
private String type;
private List<String> required;
private Properties properties;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public List<String> getRequired() {
return required;
}
public void setRequired(List<String> required) {
this.required = required;
}
public Properties getProperties() {
return properties;
}
public void setProperties(Properties properties) {
this.properties = properties;
}
}

@ -0,0 +1,15 @@
package xyz.wbsite.achat.chat.tool;
import java.util.TreeMap;
/**
*
*
* @author wangbing
* @version 0.0.1
* @since 1.8
*/
public class Properties extends TreeMap<String,Arg> {
}

@ -0,0 +1,60 @@
package xyz.wbsite.achat.chat.tool;
/**
* - OpenAIAPI
*
* @author wangbing
* @version 0.0.1
* @since 1.8
*/
public class Tool {
private String type;
private Function function;
public Tool() {
}
private Tool(Builder builder) {
this.type = builder.type;
this.function = builder.function;
}
public static Builder builder() {
return new Builder();
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public Function getFunction() {
return function;
}
public void setFunction(Function function) {
this.function = function;
}
public static class Builder {
private String type;
private Function function;
public Builder type(String type) {
this.type = type;
return this;
}
public Builder function(Function function) {
this.function = function;
return this;
}
public Tool build() {
return new Tool(this);
}
}
}

@ -0,0 +1,83 @@
package xyz.wbsite.achat.chat.tool;
import cn.hutool.core.util.RandomUtil;
/**
* - OpenAIAPI
*
* @author wangbing
* @version 0.0.1
* @since 1.8
*/
public class ToolCall {
private final String id = "call_" + RandomUtil.randomNumbers(8);
private int index;
private String type;
private FunctionCall function;
public int getIndex() {
return index;
}
public void setIndex(int index) {
this.index = index;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public FunctionCall getFunction() {
return function;
}
public void setFunction(FunctionCall function) {
this.function = function;
}
private ToolCall(String id, int index, String type, FunctionCall function) {
this.index = index;
this.type = type;
this.function = function;
}
public static Builder builder() {
return new Builder();
}
public static class Builder {
private String id;
private int index;
private String type;
private FunctionCall function;
// 链式设置id可选不设置则使用默认值
public Builder id(String id) {
this.id = id;
return this;
}
public Builder index(int index) {
this.index = index;
return this;
}
public Builder type(String type) {
this.type = type;
return this;
}
public Builder function(FunctionCall function) {
this.function = function;
return this;
}
public ToolCall build() {
return new ToolCall(id, index, type, function);
}
}
}

@ -1,35 +0,0 @@
package xyz.wbsite.achat.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* Web(,).
*
* @author wangbing
* @version 0.0.1
* @since 1.8
*/
@Configuration
public class WebConfig implements WebMvcConfigurer {
/**
*
*
* @param registry
*/
@Override
public void addCorsMappings(CorsRegistry registry) {
// 注意,如果授权认认证未通过会直接返回,此跨域配置则不会生效,前端仍然会提示跨域
registry.addMapping("/**")
//允许的域,不要写*否则cookie就无法使用了
.allowedOriginPatterns("http://localhost:5173")
.allowedHeaders("*")
//是否发送Cookie
.allowCredentials(true)
.allowedMethods("GET", "POST", "DELETE", "PUT")
.exposedHeaders("*")
.maxAge(3600);
}
}

@ -1,4 +1,4 @@
package xyz.wbsite.achat.core.embed;
package xyz.wbsite.achat.embed;
import java.util.ArrayList;
import java.util.List;

@ -1,6 +1,6 @@
package xyz.wbsite.achat.core.embed;
package xyz.wbsite.achat.embed;
import xyz.wbsite.achat.core.chat.Usage;
import xyz.wbsite.achat.chat.Usage;
import java.util.ArrayList;
import java.util.List;

@ -1,4 +1,4 @@
package xyz.wbsite.achat.core.model;
package xyz.wbsite.achat.model;
import java.util.List;

@ -1,4 +1,4 @@
package xyz.wbsite.achat.core.model;
package xyz.wbsite.achat.model;
import java.util.List;

@ -1,9 +1,9 @@
package xyz.wbsite.achat.core.session;
package xyz.wbsite.achat.session;
/**
*
*/
public class Message extends xyz.wbsite.achat.core.chat.Message {
public class Message extends xyz.wbsite.achat.chat.Message {
private String id;
private String uid;
private String sid;

@ -1,4 +1,4 @@
package xyz.wbsite.achat.core.session;
package xyz.wbsite.achat.session;
/**
*

@ -1,4 +1,4 @@
package xyz.wbsite.achat.core.session;
package xyz.wbsite.achat.session;
import java.util.List;

@ -1,6 +1,4 @@
package xyz.wbsite.achat.core.session;
import xyz.wbsite.achat.core.chat.Message;
package xyz.wbsite.achat.session;
import java.util.List;

@ -1,4 +1,4 @@
package xyz.wbsite.achat.core.session;
package xyz.wbsite.achat.session;
import java.util.ArrayList;
import java.util.List;

@ -1,12 +1,12 @@
package xyz.wbsite.achat.config;
package xyz.wbsite.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import xyz.wbsite.achat.core.chat.ChatService;
import xyz.wbsite.achat.core.chat.ChatServiceSampleImpl;
import xyz.wbsite.achat.core.session.SessionService;
import xyz.wbsite.achat.core.session.SessionServiceMemoryImpl;
import xyz.wbsite.achat.chat.ChatService;
import xyz.wbsite.achat.chat.ChatServiceSampleImpl;
import xyz.wbsite.achat.session.SessionService;
import xyz.wbsite.achat.session.SessionServiceMemoryImpl;
/**
*

@ -1,4 +1,4 @@
package xyz.wbsite.achat.config;
package xyz.wbsite.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@ -0,0 +1,82 @@
package xyz.wbsite.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.InterceptorRegistration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
/**
* Web(,).
*
* @author wangbing
* @version 0.0.1
* @since 1.8
*/
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Value("${cfg.api.key}")
private String key;
/**
*
*
* @param registry
*/
@Override
public void addCorsMappings(CorsRegistry registry) {
// 注意,如果授权认认证未通过会直接返回,此跨域配置则不会生效,前端仍然会提示跨域
registry.addMapping("/**")
//允许的域,不要写*否则cookie就无法使用了
.allowedOriginPatterns("http://localhost:5173")
.allowedHeaders("*")
//是否发送Cookie
.allowCredentials(true)
.allowedMethods("GET", "POST", "DELETE", "PUT")
.exposedHeaders("*")
.maxAge(3600);
}
/**
*
*
* @param registry
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 自定义拦截器
InterceptorRegistration interceptorRegistration = registry.addInterceptor(new HandlerInterceptor() {
//处理器运行之前执行
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String authorization = request.getHeader("authorization");
if (authorization == null || !authorization.equals("Bearer " + key)){
response.setHeader("Content-Type", MediaType.APPLICATION_JSON.toString());
try {
PrintWriter writer = response.getWriter();
writer.print("{\"error\":\"Incorrect API key\",\"code\":401}");
writer.flush();
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
return true;
}
});
interceptorRegistration.addPathPatterns("/**");
}
}

@ -1,4 +1,4 @@
package xyz.wbsite.achat;
package xyz.wbsite.openai;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@ -1,18 +1,19 @@
package xyz.wbsite.achat;
package xyz.wbsite.openai;
import cn.hutool.json.JSONUtil;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import xyz.wbsite.achat.core.chat.ChatCompletionRequest;
import xyz.wbsite.achat.core.chat.CompletionRequest;
import xyz.wbsite.achat.core.chat.CompletionResponse;
import xyz.wbsite.achat.core.embed.EmbeddingsRequest;
import xyz.wbsite.achat.core.embed.EmbeddingsResponse;
import xyz.wbsite.achat.core.model.ModelListResponse;
import xyz.wbsite.achat.core.chat.ChatService;
import xyz.wbsite.achat.chat.ChatCompletionRequest;
import xyz.wbsite.achat.chat.ChatService;
import xyz.wbsite.achat.chat.CompletionRequest;
import xyz.wbsite.achat.chat.CompletionResponse;
import xyz.wbsite.achat.embed.EmbeddingsRequest;
import xyz.wbsite.achat.embed.EmbeddingsResponse;
import xyz.wbsite.achat.model.ModelListResponse;
import javax.annotation.Resource;
@ -72,7 +73,12 @@ public class OpenAiController {
* POST /v1/chat/completions
*/
@PostMapping("/chat/completions")
public Object createChatCompletion(@RequestBody ChatCompletionRequest request) {
public Object createChatCompletion(@RequestBody String ss) {
System.out.println("原始请求");
System.out.println(ss);
ChatCompletionRequest request = JSONUtil.toBean(ss, ChatCompletionRequest.class);
System.out.println("转换后请求");
System.out.println(JSONUtil.toJsonStr(request));
if (Boolean.TRUE.equals(request.getStream())) {
// 流式响应处理
return chatService.streamChat(request);

@ -1,13 +1,13 @@
package xyz.wbsite.achat;
package xyz.wbsite.openai;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import xyz.wbsite.achat.core.session.Result;
import xyz.wbsite.achat.core.session.Session;
import xyz.wbsite.achat.core.session.SessionService;
import xyz.wbsite.achat.session.Result;
import xyz.wbsite.achat.session.Session;
import xyz.wbsite.achat.session.SessionService;
import javax.annotation.Resource;
import java.util.List;

@ -1,2 +1,3 @@
server.port=8080
spring.application.name=achat
cfg.api.key=qazwsxedc741852963

Loading…
Cancel
Save

Powered by TurnKey Linux.