Compare commits

...

6 Commits
flux ... master

@ -1,112 +0,0 @@
package xyz.wbsite.achat;
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.RequestBody;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
import xyz.wbsite.achat.core.base.Message;
import xyz.wbsite.achat.core.base.Result;
import xyz.wbsite.achat.core.base.Session;
import xyz.wbsite.achat.core.message.UserMessage;
import xyz.wbsite.achat.core.prompt.MessagePrompt;
import xyz.wbsite.achat.core.service.SessionService;
import javax.annotation.Resource;
import java.util.List;
import java.util.UUID;
/**
* AI.
*
* @author wangbing
* @version 0.0.1
* @since 1.8
*/
@RestController
public class ChatController {
@Resource
private SessionService sessionService;
/**
*
*/
@GetMapping("/chat")
public String chat() {
return "AChat is running!";
}
/**
*
*
* @return SSE
*/
@PostMapping(value = "/chat/send", produces = "text/event-stream;charset=UTF-8")
public SseEmitter send(@RequestBody MessagePrompt message) {
return sessionService.sendMessage(message);
}
/**
*
*
* @return
*/
@PostMapping("/chat/session")
public Result<Session> createSession() {
String sid = UUID.randomUUID().toString();
return sessionService.createSession(sid);
}
/**
*
*
* @return
*/
@ResponseBody
@GetMapping("/chat/session/list")
public Result<List<Session>> listSession() {
String sid = UUID.randomUUID().toString();
return sessionService.listSessions(sid);
}
/**
*
*
* @param sid ID
* @return
*/
@ResponseBody
@DeleteMapping("/chat/session/{sid}")
public Result deleteSession(@PathVariable("sid") String sid) {
return sessionService.deleteSession(sid);
}
/**
*
*
* @param sid ID
* @return
*/
@ResponseBody
@GetMapping("/chat/session/{sid}/history")
public Result<List<Message>> getSessionHistory(@PathVariable("sid") String sid) {
return sessionService.listMessage(sid);
}
/**
* AI
*
* @param sid ID
* @return
*/
@ResponseBody
@PostMapping("/chat/session/{sid}/stop")
public Result<Void> stopSession(@PathVariable("sid") String sid) {
return sessionService.stopSession(sid);
}
}

@ -0,0 +1,23 @@
package xyz.wbsite.achat;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
/**
*
*
* @author wangbing
* @version 0.0.1
* @since 1.8
*/
@RestController
public class HelloController {
/**
*
*/
@GetMapping("/")
public String chat() {
return "AChat is running!";
}
}

@ -0,0 +1,90 @@
package xyz.wbsite.achat;
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 javax.annotation.Resource;
/**
* AI.
*
* @author wangbing
* @version 0.0.1
* @since 1.8
*/
@RestController
@RequestMapping("/v1")
public class OpenAiController {
// @Resource
// private SessionService sessionService;
@Resource
private ChatService chatService;
@RequestMapping()
public String info() {
return "OpenAI API is support";
}
/**
*
* GET /v1/models
*/
@GetMapping("/models")
public ModelListResponse models() {
// 实现获取模型列表的逻辑
// 这里返回一个示例响应,实际应用中应从服务层获取数据
ModelListResponse response = new ModelListResponse();
response.setObject("list");
// response.setData(/* 实际模型列表 */);
return response;
}
/**
*
* GET /v1/models/{model}
*/
@GetMapping("/models/{model}")
public Object getModel(@PathVariable String model) {
// 实现获取模型详情的逻辑
// 这里返回一个示例响应,实际应用中应从服务层获取数据
return null; // 替换为实际的模型对象
}
@RequestMapping("/completions")
public CompletionResponse completions(@RequestBody CompletionRequest request) {
return chatService.prompt(request);
}
/**
*
* POST /v1/chat/completions
*/
@PostMapping("/chat/completions")
public Object createChatCompletion(@RequestBody ChatCompletionRequest request) {
if (Boolean.TRUE.equals(request.getStream())) {
// 流式响应处理
return chatService.streamChat(request);
} else {
// 非流式响应处理
return chatService.chat(request);
}
}
@RequestMapping("/embeddings")
public EmbeddingsResponse embeddings(@RequestBody EmbeddingsRequest request) {
return chatService.embeddings(request);
}
}

@ -0,0 +1,86 @@
package xyz.wbsite.achat;
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 javax.annotation.Resource;
import java.util.List;
/**
*
*
*
* @author wangbing
* @version 0.0.1
* @since 1.8
*/
@RestController
public class SessionController {
@Resource
private SessionService sessionService;
/**
*
*
* @param uid
* @return
*/
@PostMapping("/{uid}/session")
public Result<Session> createSession(@PathVariable("uid") String uid) {
return sessionService.createSession(uid);
}
/**
*
*
* @param uid
* @param sid ID
* @return
*/
@DeleteMapping("/{uid}/session/{sid}")
public Result<Void> deleteSession(@PathVariable("uid") String uid, @PathVariable("sid") String sid) {
return sessionService.deleteSession(uid, sid);
}
/**
*
*
* @param uid
* @param sid ID
* @return
*/
@GetMapping("/{uid}/session/{sid}")
public Result<Session> getSession(@PathVariable("uid") String uid, @PathVariable("sid") String sid) {
return sessionService.getSession(uid, sid);
}
/**
*
*
* @param uid
* @return
*/
@GetMapping("/{uid}/session/list")
public Result<List<Session>> listSession(@PathVariable("uid") String uid) {
return sessionService.listSessions(uid);
}
/**
*
*
* @param uid
* @param sid ID
* @return
*/
@DeleteMapping("/{uid}/session/{sid}/messages/{mid}")
public Result<Void> deleteMessage(@PathVariable("uid") String uid, @PathVariable("sid") String sid, @PathVariable("mid") String mid) {
return sessionService.deleteMessage(uid, sid, mid);
}
}

@ -0,0 +1,30 @@
package xyz.wbsite.achat.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;
/**
*
*
* @author wangbing
* @version 0.0.1
* @since 1.8
*/
@Configuration
public class ChatConfig implements WebMvcConfigurer {
@Bean
public ChatService chatService() {
return new ChatServiceSampleImpl();
}
@Bean
public SessionService sessionService() {
return new SessionServiceMemoryImpl();
}
}

@ -0,0 +1,66 @@
package xyz.wbsite.achat.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.ThreadPoolExecutor;
/**
* 线.
* 线
* 线
*
* @author wangbing
* @version 0.0.1
* @since 1.8
*/
@Configuration
public class PoolConfig {
// 获取CPU核心数
private final int cpuCount = Runtime.getRuntime().availableProcessors();
/**
* 线线
* IO线CPU
*/
private final int corePoolSize = Math.max(1, cpuCount);
/**
* 线线
* CPU+11线
*/
private final int maxPoolSize = Math.max(1, cpuCount + 1);
/**
*
* IO使线
*/
private final int queueCapacity = 100;
/**
*
* 线
*/
private final int keepAliveSeconds = 30;
/**
* 线
*/
@Bean
public ThreadPoolTaskExecutor threadPoolTaskExecutor() {
ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
threadPoolTaskExecutor.setCorePoolSize(corePoolSize);
threadPoolTaskExecutor.setMaxPoolSize(maxPoolSize);
threadPoolTaskExecutor.setQueueCapacity(queueCapacity);
threadPoolTaskExecutor.setKeepAliveSeconds(keepAliveSeconds);
threadPoolTaskExecutor.setThreadNamePrefix("ThreadPool-");
// rejection-policy当pool已经达到max size的时候如何处理新任务
// CALLER_RUNS不在新线程中公式任务而是由调用者所在的线程来执行
// 对拒绝task的处理策略
threadPoolTaskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
threadPoolTaskExecutor.initialize();
return threadPoolTaskExecutor;
}
}

@ -12,7 +12,7 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
* @since 1.8
*/
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
public class WebConfig implements WebMvcConfigurer {
/**
*
@ -22,7 +22,7 @@ public class WebMvcConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
// 注意,如果授权认认证未通过会直接返回,此跨域配置则不会生效,前端仍然会提示跨域
registry.addMapping("/chat/**")
registry.addMapping("/**")
//允许的域,不要写*否则cookie就无法使用了
.allowedOriginPatterns("http://localhost:5173")
.allowedHeaders("*")

@ -1,30 +0,0 @@
package xyz.wbsite.achat.core.base;
/**
*
*
* @author wangbing
* @version 0.0.1
* @since 1.8
*/
public class Attachment {
private String filename;
private String fid;
public String getFilename() {
return filename;
}
public void setFilename(String filename) {
this.filename = filename;
}
public String getFid() {
return fid;
}
public void setFid(String fid) {
this.fid = fid;
}
}

@ -1,59 +0,0 @@
package xyz.wbsite.achat.core.base;
import java.util.Date;
/**
*
*
* @author wangbing
* @version 0.0.1
* @since 1.8
*/
public class Event {
private String sid;
private Date time;
private String text;
private String type;
public Event(String sid) {
this.sid = sid;
this.time = new Date();
}
public String getSid() {
return sid;
}
public void setSid(String sid) {
this.sid = sid;
}
public Date getTime() {
return time;
}
public void setTime(Date time) {
this.time = time;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}

@ -1,52 +0,0 @@
package xyz.wbsite.achat.core.base;
import xyz.wbsite.achat.enums.Role;
/**
*
*
* @author wangbing
* @version 0.0.1
* @since 1.8
*/
public class Message {
/**
*
*/
private Role role;
/**
* ID
*/
private String sid;
/**
*
*/
private String content;
public Role getRole() {
return role;
}
public void setRole(Role role) {
this.role = role;
}
public String getSid() {
return sid;
}
public void setSid(String sid) {
this.sid = sid;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}

@ -1,17 +0,0 @@
package xyz.wbsite.achat.core.base;
public class Prompt {
/**
*
*/
private String prompt;
public String getPrompt() {
return prompt;
}
public void setPrompt(String prompt) {
this.prompt = prompt;
}
}

@ -0,0 +1,187 @@
package xyz.wbsite.achat.core.chat;
import java.util.ArrayList;
import java.util.List;
/**
* OpenAI - OpenAIAPI
*
* @author wangbing
* @version 0.0.1
* @since 1.8
*/
public class ChatCompletionChunk {
private String id;
private String object;
private long created;
private String model;
private List<Choice> choices;
private ChatCompletionChunk(Builder builder) {
this.id = builder.id;
this.object = builder.object;
this.created = builder.created;
this.model = builder.model;
this.choices = builder.choices;
}
public static Builder builder() {
return new Builder();
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getObject() {
return object;
}
public void setObject(String object) {
this.object = object;
}
public long getCreated() {
return created;
}
public void setCreated(long created) {
this.created = created;
}
public String getModel() {
return model;
}
public void setModel(String model) {
this.model = model;
}
public List<Choice> getChoices() {
return choices;
}
public void setChoices(List<Choice> choices) {
this.choices = choices;
}
public static class Builder {
private String id;
private String object;
private long created;
private String model;
private List<Choice> choices = new ArrayList<>();
public Builder id(String id) {
this.id = id;
return this;
}
public Builder object(String object) {
this.object = object;
return this;
}
public Builder created(long created) {
this.created = created;
return this;
}
public Builder model(String model) {
this.model = model;
return this;
}
public Builder choices(List<Choice> choices) {
this.choices = choices;
return this;
}
// 使用lambda表达式构建choices列表优化代码可读性
public Builder withChoices(java.util.function.Consumer<List<Choice>> choicesConsumer) {
choicesConsumer.accept(this.choices);
return this;
}
// 构建ChatCompletionChunk对象
public ChatCompletionChunk build() {
return new ChatCompletionChunk(this);
}
}
public static class Choice {
private int index = 0;
private Message delta;
private String finish_reason;
public Integer getIndex() {
return index;
}
public void setIndex(Integer index) {
this.index = index;
}
public Message getDelta() {
return delta;
}
public void setDelta(Message delta) {
this.delta = delta;
}
public String getFinish_reason() {
return finish_reason;
}
public void setFinish_reason(String finish_reason) {
this.finish_reason = finish_reason;
}
}
public static ChoiceBuilder choiceBuilder() {
return new ChoiceBuilder();
}
public static class ChoiceBuilder {
private Integer index;
private Role role;
private String content;
private String name;
private String finish_reason;
public ChoiceBuilder index(Integer index) {
this.index = index;
return this;
}
public ChoiceBuilder role(Role role) {
this.role = role;
return this;
}
public ChoiceBuilder content(String content) {
this.content = content;
return this;
}
public ChoiceBuilder name(String name) {
this.name = name;
return this;
}
public ChoiceBuilder finish_reason(String finish_reason) {
this.finish_reason = finish_reason;
return this;
}
public Choice build() {
Choice choice = new Choice();
choice.setIndex(index);
choice.setDelta(Message.builder().role(role).content(content).name(name).build());
choice.setFinish_reason(finish_reason);
return choice;
}
}
}

@ -0,0 +1,121 @@
package xyz.wbsite.achat.core.chat;
import java.util.List;
/**
* OpenAI - OpenAIAPI
*
* @author wangbing
* @version 0.0.1
* @since 1.8
*/
public class ChatCompletionRequest {
private String model;
private List<Message> messages;
private Double temperature;
private Double top_p;
private Integer n;
private Boolean stream;
private List<String> stop;
private Integer max_tokens;
private Double presence_penalty;
private Double frequency_penalty;
private Object logit_bias;
private String user;
public String getModel() {
return model;
}
public void setModel(String model) {
this.model = model;
}
public List<Message> getMessages() {
return messages;
}
public void setMessages(List<Message> messages) {
this.messages = messages;
}
public Double getTemperature() {
return temperature;
}
public void setTemperature(Double temperature) {
this.temperature = temperature;
}
public Double getTop_p() {
return top_p;
}
public void setTop_p(Double top_p) {
this.top_p = top_p;
}
public Integer getN() {
return n;
}
public void setN(Integer n) {
this.n = n;
}
public Boolean getStream() {
return stream;
}
public void setStream(Boolean stream) {
this.stream = stream;
}
public List<String> getStop() {
return stop;
}
public void setStop(List<String> stop) {
this.stop = stop;
}
public Integer getMax_tokens() {
return max_tokens;
}
public void setMax_tokens(Integer max_tokens) {
this.max_tokens = max_tokens;
}
public Double getPresence_penalty() {
return presence_penalty;
}
public void setPresence_penalty(Double presence_penalty) {
this.presence_penalty = presence_penalty;
}
public Double getFrequency_penalty() {
return frequency_penalty;
}
public void setFrequency_penalty(Double frequency_penalty) {
this.frequency_penalty = frequency_penalty;
}
public Object getLogit_bias() {
return logit_bias;
}
public void setLogit_bias(Object logit_bias) {
this.logit_bias = logit_bias;
}
public String getUser() {
return user;
}
public void setUser(String user) {
this.user = user;
}
}

@ -0,0 +1,214 @@
package xyz.wbsite.achat.core.chat;
import java.util.ArrayList;
import java.util.List;
/**
* OpenAI - OpenAIAPI
*
* @author wangbing
* @version 0.0.1
* @since 1.8
*/
public class ChatCompletionResponse {
private String id;
private String object;
private long created;
private String model;
private List<Choice> choices;
private Usage usage;
// 无参构造函数
public ChatCompletionResponse() {
}
// 私有构造函数用于Builder模式
private ChatCompletionResponse(Builder builder) {
this.id = builder.id;
this.object = builder.object;
this.created = builder.created;
this.model = builder.model;
this.choices = builder.choices;
this.usage = builder.usage;
}
// 静态builder方法返回Builder实例
public static Builder builder() {
return new Builder();
}
// Getters and Setters
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getObject() {
return object;
}
public void setObject(String object) {
this.object = object;
}
public long getCreated() {
return created;
}
public void setCreated(long created) {
this.created = created;
}
public String getModel() {
return model;
}
public void setModel(String model) {
this.model = model;
}
public List<Choice> getChoices() {
return choices;
}
public void setChoices(List<Choice> choices) {
this.choices = choices;
}
public Usage getUsage() {
return usage;
}
public void setUsage(Usage usage) {
this.usage = usage;
}
// Builder内部类
public static class Builder {
private String id;
private String object;
private long created;
private String model;
private List<Choice> choices = new ArrayList<>();
private Usage usage;
public Builder id(String id) {
this.id = id;
return this;
}
public Builder object(String object) {
this.object = object;
return this;
}
public Builder created(long created) {
this.created = created;
return this;
}
public Builder model(String model) {
this.model = model;
return this;
}
// 设置整个choices列表
public Builder choices(List<Choice> choices) {
this.choices = choices;
return this;
}
// 使用lambda表达式构建choices列表优化代码可读性
public Builder withChoices(java.util.function.Consumer<List<Choice>> choicesConsumer) {
choicesConsumer.accept(this.choices);
return this;
}
public Builder usage(Usage usage) {
this.usage = usage;
return this;
}
public ChatCompletionResponse build() {
return new ChatCompletionResponse(this);
}
}
public static class Choice {
private int index = 0;
private Message message;
private String finish_reason;
public Integer getIndex() {
return index;
}
public void setIndex(Integer index) {
this.index = index;
}
public Message getMessage() {
return message;
}
public void setMessage(Message message) {
this.message = message;
}
public String getFinish_reason() {
return finish_reason;
}
public void setFinish_reason(String finish_reason) {
this.finish_reason = finish_reason;
}
}
public static ChoiceBuilder choiceBuilder() {
return new ChoiceBuilder();
}
public static class ChoiceBuilder {
private Integer index;
private Role role;
private String content;
private String name;
private String finish_reason;
public ChoiceBuilder index(Integer index) {
this.index = index;
return this;
}
public ChoiceBuilder role(Role role) {
this.role = role;
return this;
}
public ChoiceBuilder content(String content) {
this.content = content;
return this;
}
public ChoiceBuilder name(String name) {
this.name = name;
return this;
}
public ChoiceBuilder finish_reason(String finish_reason) {
this.finish_reason = finish_reason;
return this;
}
public Choice build() {
Choice choice = new Choice();
choice.setIndex(index);
choice.setMessage(Message.builder().role(role).content(content).name(name).build());
choice.setFinish_reason(finish_reason);
return choice;
}
}
}

@ -0,0 +1,16 @@
package xyz.wbsite.achat.core.chat;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
import xyz.wbsite.achat.core.embed.EmbeddingsRequest;
import xyz.wbsite.achat.core.embed.EmbeddingsResponse;
public interface ChatService {
CompletionResponse prompt(CompletionRequest request);
ChatCompletionResponse chat(ChatCompletionRequest request);
SseEmitter streamChat(ChatCompletionRequest request);
EmbeddingsResponse embeddings(EmbeddingsRequest request);
}

@ -0,0 +1,138 @@
package xyz.wbsite.achat.core.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 javax.annotation.Resource;
import java.util.Collections;
/**
* AI
* ChatServicepromptchatstreamChat
*
* @author wangbing
* @version 0.0.1
* @since 1.8
*/
public class ChatServiceSampleImpl implements ChatService {
@Resource
private ThreadPoolTaskExecutor taskExecutor;
/**
*
*/
private final String DEFAULT_PROMPT = "您好我还没有接入AI请接入后再试";
@Override
public CompletionResponse prompt(CompletionRequest request) {
return CompletionResponse.builder()
.id("chatcmpl-" + System.currentTimeMillis())
.object("chat.completion")
.created(System.currentTimeMillis() / 1000)
.model(request.getModel())
.withChoices(choices -> {
choices.add(CompletionResponse.choiceBuilder()
.index(0)
.role(Role.ASSISTANT)
.content(DEFAULT_PROMPT)
.finish_reason("stop").build());
})
.usage(Usage.builder()
.prompt_tokens(10)
.completion_tokens(10)
.total_tokens(10)
.build())
.build();
}
@Override
public ChatCompletionResponse chat(ChatCompletionRequest request) {
return ChatCompletionResponse.builder()
.id("chatcmpl-" + System.currentTimeMillis())
.object("chat.completion")
.created(System.currentTimeMillis() / 1000)
.model(request.getModel())
.withChoices(choices -> {
choices.add(ChatCompletionResponse.choiceBuilder()
.index(0)
.role(Role.ASSISTANT)
.content(DEFAULT_PROMPT)
.finish_reason("stop")
.build());
})
.usage(Usage.builder()
.prompt_tokens(10)
.completion_tokens(10)
.total_tokens(10)
.build())
.build();
}
@Override
public SseEmitter streamChat(ChatCompletionRequest request) {
// 验证请求参数
if (request.getModel() == null) {
throw new IllegalArgumentException("模型不能为空");
}
if (request.getMessages() == null || request.getMessages().isEmpty()) {
throw new IllegalArgumentException("消息不能为空");
}
StreamEmitter streamEmitter = new StreamEmitter(request);
taskExecutor.execute(() -> {
String chatId = "chatcmpl-" + System.currentTimeMillis();
streamEmitter.onStart(chatId);
char[] charArray = DEFAULT_PROMPT.toCharArray();
for (char c : charArray) {
try {
Thread.sleep(30);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
streamEmitter.onPartial(String.valueOf(c));
}
streamEmitter.onComplete();
});
return streamEmitter;
}
@Override
public EmbeddingsResponse embeddings(EmbeddingsRequest request) {
// 验证请求参数
if (request == null) {
throw new IllegalArgumentException("请求参数不能为空");
}
if (request.getModel() == null || request.getModel().isEmpty()) {
throw new IllegalArgumentException("模型不能为空");
}
if (request.getInput() == null || request.getInput().isEmpty()) {
throw new IllegalArgumentException("输入文本不能为空");
}
// 模拟生成嵌入向量响应
return EmbeddingsResponse.builder()
.id("embedding-" + System.currentTimeMillis())
.object("list")
.created(System.currentTimeMillis() / 1000)
.model(request.getModel())
.withData(data -> {
for (int i = 0; i < request.getInput().size(); i++) {
data.add(EmbeddingsResponse.dataBuilder()
.index(i)
.embedding(Collections.emptyList())
.object("embedding")
.build());
}
})
.usage(Usage.builder()
.prompt_tokens(10)
.completion_tokens(10)
.total_tokens(10)
.build())
.build();
}
}

@ -0,0 +1,67 @@
package xyz.wbsite.achat.core.chat;
/**
*
*
* @author wangbing
* @version 0.0.1
* @since 1.8
*/
public class CompletionRequest {
private String model;
private String prompt;
private boolean stream;
private Double temperature;
private Integer max_tokens;
private Double top_p;
private Integer n;
public String getModel() {
return model;
}
public void setModel(String model) {
this.model = model;
}
public String getPrompt() {
return prompt;
}
public void setPrompt(String prompt) {
this.prompt = prompt;
}
public Integer getMax_tokens() {
return max_tokens;
}
public void setMax_tokens(Integer max_tokens) {
this.max_tokens = max_tokens;
}
public Double getTemperature() {
return temperature;
}
public void setTemperature(Double temperature) {
this.temperature = temperature;
}
public Double getTop_p() {
return top_p;
}
public void setTop_p(Double top_p) {
this.top_p = top_p;
}
public Integer getN() {
return n;
}
public void setN(Integer n) {
this.n = n;
}
}

@ -0,0 +1,204 @@
package xyz.wbsite.achat.core.chat;
import java.util.ArrayList;
import java.util.List;
/**
* OpenAI - OpenAIAPI
*
* @author wangbing
* @version 0.0.1
* @since 1.8
*/
public class CompletionResponse {
private String id;
private String object;
private long created;
private String model;
private List<Choice> choices;
private Usage usage;
private CompletionResponse(Builder builder) {
this.id = builder.id;
this.object = builder.object;
this.created = builder.created;
this.model = builder.model;
this.choices = builder.choices;
this.usage = builder.usage;
}
public static Builder builder() {
return new Builder();
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getObject() {
return object;
}
public void setObject(String object) {
this.object = object;
}
public long getCreated() {
return created;
}
public void setCreated(long created) {
this.created = created;
}
public String getModel() {
return model;
}
public void setModel(String model) {
this.model = model;
}
public List<Choice> getChoices() {
return choices;
}
public void setChoices(List<Choice> choices) {
this.choices = choices;
}
public Usage getUsage() {
return usage;
}
public void setUsage(Usage usage) {
this.usage = usage;
}
public static class Builder {
private String id;
private String object;
private long created;
private String model;
private List<Choice> choices = new ArrayList<>();
private Usage usage;
public Builder id(String id) {
this.id = id;
return this;
}
public Builder object(String object) {
this.object = object;
return this;
}
public Builder created(long created) {
this.created = created;
return this;
}
public Builder model(String model) {
this.model = model;
return this;
}
public Builder choices(List<Choice> choices) {
this.choices = choices;
return this;
}
public Builder withChoices(java.util.function.Consumer<List<Choice>> choicesConsumer) {
choicesConsumer.accept(this.choices);
return this;
}
public Builder usage(Usage usage) {
this.usage = usage;
return this;
}
public CompletionResponse build() {
return new CompletionResponse(this);
}
}
public static class Choice {
private int index = 0;
private Message message;
private String finish_reason;
public Integer getIndex() {
return index;
}
public void setIndex(Integer index) {
this.index = index;
}
public Message getMessage() {
return message;
}
public void setMessage(Message message) {
this.message = message;
}
public String getFinish_reason() {
return finish_reason;
}
public void setFinish_reason(String finish_reason) {
this.finish_reason = finish_reason;
}
}
public static ChoiceBuilder choiceBuilder() {
return new ChoiceBuilder();
}
public static class ChoiceBuilder {
private Integer index;
private Role role;
private String content;
private String name;
private String finish_reason;
public ChoiceBuilder index(Integer index) {
this.index = index;
return this;
}
public ChoiceBuilder role(Role role) {
this.role = role;
return this;
}
public ChoiceBuilder content(String content) {
this.content = content;
return this;
}
public ChoiceBuilder name(String name) {
this.name = name;
return this;
}
public ChoiceBuilder finish_reason(String finish_reason) {
this.finish_reason = finish_reason;
return this;
}
public Choice build() {
Choice choice = new Choice();
choice.setIndex(index);
choice.setMessage(Message.builder().role(role).content(content).name(name).build());
choice.setFinish_reason(finish_reason);
return choice;
}
}
}

@ -0,0 +1,78 @@
package xyz.wbsite.achat.core.chat;
/**
*
*
* @author wangbing
* @version 0.0.1
* @since 1.8
*/
public class Message {
private Role role;
private String content;
private String name;
public Message() {
}
private Message(Builder builder) {
this.role = builder.role;
this.content = builder.content;
this.name = builder.name;
}
public Role getRole() {
return role;
}
public void setRole(Role role) {
this.role = role;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
// 静态builder方法返回Builder实例
public static Builder builder() {
return new Builder();
}
public static class Builder {
private Role role;
private String content;
private String name;
public Builder role(Role role) {
this.role = role;
return this;
}
public Builder content(String content) {
this.content = content;
return this;
}
public Builder name(String name) {
this.name = name;
return this;
}
// 构建Message对象
public Message build() {
return new Message(this);
}
}
}

@ -1,4 +1,4 @@
package xyz.wbsite.achat.enums;
package xyz.wbsite.achat.core.chat;
import com.fasterxml.jackson.annotation.JsonValue;

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

@ -0,0 +1,185 @@
package xyz.wbsite.achat.core.chat;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
/**
*
*
* @author wangbing
* @version 0.0.1
* @since 1.8
*/
public class StreamEmitter extends SseEmitter {
/**
*
*/
private static final Long DEFAULT_TIMEOUT = 5 * 60 * 1000L;
/**
*
*/
private ChatCompletionRequest request;
/**
*
*/
private Status status;
/**
* ID
*/
private String chatId;
/**
*
*/
private boolean complete;
public StreamEmitter(ChatCompletionRequest request) {
super(DEFAULT_TIMEOUT);
this.request = request;
}
// /**
// * 错误处理
// */
// private void onError(Throwable e) {
//// this.sendMessage(createPartialMessage("</think></think>" + e.getMessage()));
// this.answer.append("</think></think>" + e.getMessage());
// this.onCompleteResponse(null);
// }
//
// /**
// * 部分响应处理
// */
// public void onPartialResponse(String msg) {
// if (complete) {
// return;
// }
//// this.sendMessage(createPartialMessage(msg));
// this.answer.append(msg);
// }
/**
*
*/
public void onCompleteResponse(Object chatResponse) {
if (this.complete) {
return;
}
// 推送结束
// this.sendMessage(createCompleteMessage());
// 关闭链接
this.complete();
}
/**
* send
*/
@Override
public void send(SseEventBuilder builder) {
try {
super.send(builder);
} catch (Exception e) {
complete = true;
}
}
/**
*
*/
private void pushChunk(ChatCompletionChunk chunk) {
try {
this.send(chunk);
} catch (Exception e) {
complete = true;
}
}
/**
*
*
* @param chatId id
*/
public void onStart(String chatId) {
if (!StringUtils.hasText(chatId)) {
throw new IllegalArgumentException("chatId is empty!");
}
if (this.status != null) {
throw new IllegalArgumentException("chunk has been started!");
}
ChatCompletionChunk chunk = ChatCompletionChunk.builder()
.id(chatId)
.object("chat.completion.chunk")
.created(System.currentTimeMillis() / 1000)
.model(request.getModel())
.withChoices(choices -> {
choices.add(ChatCompletionChunk.choiceBuilder().index(0)
.role(Role.ASSISTANT)
.build());
})
.build();
this.pushChunk(chunk);
this.status = Status.PENDING;
this.chatId = chatId;
}
/**
*
*
* @param text
*/
public void onPartial(String text) {
ChatCompletionChunk chunk = ChatCompletionChunk.builder()
.id(chatId)
.object("chat.completion.chunk")
.created(System.currentTimeMillis() / 1000)
.model(request.getModel())
.withChoices(choices -> {
choices.add(ChatCompletionChunk.choiceBuilder().index(0)
.role(Role.ASSISTANT)
.content(text)
.build());
})
.build();
this.pushChunk(chunk);
}
/**
* OpenAI APIfinish_reason
*/
public void onComplete() {
ChatCompletionChunk chunk = ChatCompletionChunk.builder()
.id(chatId)
.object("chat.completion.chunk")
.created(System.currentTimeMillis() / 1000)
.model(request.getModel())
.withChoices(choices -> {
choices.add(ChatCompletionChunk.choiceBuilder().index(0)
.role(Role.ASSISTANT)
// 符合OpenAI规范最后一个片段需要设置finish_reason
.finish_reason("stop")
.build());
})
.build();
this.pushChunk(chunk);
this.complete();
this.status = Status.SUCCESS;
}
/**
*
*/
public boolean isComplete() {
return complete;
}
/**
*
*/
public void setComplete(boolean complete) {
this.complete = complete;
}
}

@ -0,0 +1,88 @@
package xyz.wbsite.achat.core.chat;
/**
* 使
*
* @author wangbing
* @version 0.0.1
* @since 1.8
*/
public class Usage {
/**
* tokens
*/
private int prompt_tokens;
/**
* tokens
*/
private int completion_tokens;
/**
* tokens
*/
private int total_tokens;
public Usage() {
}
private Usage(Builder builder) {
this.prompt_tokens = builder.prompt_tokens;
this.completion_tokens = builder.completion_tokens;
this.total_tokens = builder.total_tokens;
}
public static Builder builder() {
return new Builder();
}
public int getPrompt_tokens() {
return prompt_tokens;
}
public void setPrompt_tokens(int prompt_tokens) {
this.prompt_tokens = prompt_tokens;
}
public int getCompletion_tokens() {
return completion_tokens;
}
public void setCompletion_tokens(int completion_tokens) {
this.completion_tokens = completion_tokens;
}
public int getTotal_tokens() {
return total_tokens;
}
public void setTotal_tokens(int total_tokens) {
this.total_tokens = total_tokens;
}
public static class Builder {
private int prompt_tokens;
private int completion_tokens;
private int total_tokens;
public Builder prompt_tokens(int prompt_tokens) {
this.prompt_tokens = prompt_tokens;
return this;
}
public Builder completion_tokens(int completion_tokens) {
this.completion_tokens = completion_tokens;
return this;
}
public Builder total_tokens(int total_tokens) {
this.total_tokens = total_tokens;
return this;
}
public Usage build() {
return new Usage(this);
}
}
}

@ -0,0 +1,84 @@
package xyz.wbsite.achat.core.embed;
import java.util.ArrayList;
import java.util.List;
/**
* - OpenAIAPI
*
* @author wangbing
* @version 0.0.1
* @since 1.8
*/
public class EmbeddingsRequest {
private String model;
private List<String> input;
private String user;
public EmbeddingsRequest() {
}
private EmbeddingsRequest(Builder builder) {
this.model = builder.model;
this.input = builder.input;
this.user = builder.user;
}
public static Builder builder() {
return new Builder();
}
public String getModel() {
return model;
}
public void setModel(String model) {
this.model = model;
}
public List<String> getInput() {
return input;
}
public void setInput(List<String> input) {
this.input = input;
}
public String getUser() {
return user;
}
public void setUser(String user) {
this.user = user;
}
public static class Builder {
private String model;
private List<String> input = new ArrayList<>();
private String user;
public Builder model(String model) {
this.model = model;
return this;
}
public Builder input(List<String> input) {
this.input = input;
return this;
}
public Builder addInput(String text) {
this.input.add(text);
return this;
}
public Builder user(String user) {
this.user = user;
return this;
}
public EmbeddingsRequest build() {
return new EmbeddingsRequest(this);
}
}
}

@ -0,0 +1,266 @@
package xyz.wbsite.achat.core.embed;
import xyz.wbsite.achat.core.chat.Usage;
import java.util.ArrayList;
import java.util.List;
/**
* - OpenAIAPI
*
*
* @author wangbing
* @version 0.0.1
* @since 1.8
*/
public class EmbeddingsResponse {
private String id;
private String object;
private long created;
private String model;
private List<Data> data = new ArrayList<>();
private Usage usage;
/**
*
*/
public EmbeddingsResponse() {
}
/**
* Builder
*/
private EmbeddingsResponse(Builder builder) {
this.id = builder.id;
this.object = builder.object;
this.created = builder.created;
this.model = builder.model;
this.data = builder.data;
this.usage = builder.usage;
}
/**
* builderBuilder
*/
public static Builder builder() {
return new Builder();
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getObject() {
return object;
}
public void setObject(String object) {
this.object = object;
}
public long getCreated() {
return created;
}
public void setCreated(long created) {
this.created = created;
}
public String getModel() {
return model;
}
public void setModel(String model) {
this.model = model;
}
/**
*
*/
public List<Data> getData() {
return data;
}
public void setData(List<Data> data) {
this.data = data;
}
public Usage getUsage() {
return usage;
}
public void setUsage(Usage usage) {
this.usage = usage;
}
/**
* BuilderEmbeddingsResponse
*/
public static class Builder {
private String id;
private String object;
private long created;
private String model;
private List<Data> data = new ArrayList<>();
private Usage usage;
public Builder id(String id) {
this.id = id;
return this;
}
public Builder object(String object) {
this.object = object;
return this;
}
public Builder created(long created) {
this.created = created;
return this;
}
public Builder model(String model) {
this.model = model;
return this;
}
public Builder data(List<Data> data) {
this.data = data;
return this;
}
public Builder addData(Data data) {
this.data.add(data);
return this;
}
/**
* data访lambdadata
*/
public Builder withData(java.util.function.Consumer<List<Data>> dataConsumer) {
dataConsumer.accept(this.data);
return this;
}
public Builder usage(Usage usage) {
this.usage = usage;
return this;
}
/**
* EmbeddingsResponse
*/
public EmbeddingsResponse build() {
return new EmbeddingsResponse(this);
}
}
/**
* -
*/
public static class Data {
private int index;
private List<Double> embedding;
private String object;
/**
*
*/
public Data() {
}
/**
* Builder
*/
private Data(Builder builder) {
this.index = builder.index;
this.embedding = builder.embedding;
this.object = builder.object;
}
/**
* builderBuilder
*/
public static Builder builder() {
return new Builder();
}
public int getIndex() {
return index;
}
public void setIndex(int index) {
this.index = index;
}
/**
*
*/
public List<Double> getEmbedding() {
return embedding;
}
public void setEmbedding(List<Double> embedding) {
this.embedding = embedding;
}
public String getObject() {
return object;
}
public void setObject(String object) {
this.object = object;
}
/**
* DataBuilder
*/
public static class Builder {
private int index;
private List<Double> embedding;
private String object = "embedding";
public Builder index(int index) {
this.index = index;
return this;
}
public Builder embedding(List<Double> embedding) {
this.embedding = embedding;
return this;
}
public Builder addEmbeddingValue(double value) {
if (this.embedding == null) {
this.embedding = new ArrayList<>();
}
this.embedding.add(value);
return this;
}
public Builder object(String object) {
this.object = object;
return this;
}
/**
* Data
*/
public Data build() {
return new Data(this);
}
}
}
/**
* DataBuilder
*/
public static Data.Builder dataBuilder() {
return Data.builder();
}
}

@ -1,22 +0,0 @@
package xyz.wbsite.achat.core.event;
import xyz.wbsite.achat.core.base.Event;
/**
*
*
* @author wangbing
* @version 0.0.1
* @since 1.8
*/
public class CompleteEvent extends Event {
public CompleteEvent(String sid) {
super(sid);
setType("complete");
}
public static CompleteEvent of(String sid) {
return new CompleteEvent(sid);
}
}

@ -1,29 +0,0 @@
package xyz.wbsite.achat.core.event;
import xyz.wbsite.achat.core.base.Event;
/**
*
* <p>
* AI
*
* @author wangbing
* @version 0.0.1
* @since 1.8
*/
public class PartialEvent extends Event {
public PartialEvent(String sid) {
super(sid);
setType("partial");
}
public PartialEvent(String sid, String partial) {
super(sid);
setType("partial");
setText(partial);
}
public static PartialEvent of(String sid, String partial) {
return new PartialEvent(sid, partial);
}
}

@ -1,15 +0,0 @@
package xyz.wbsite.achat.core.message;
import xyz.wbsite.achat.core.base.Message;
/**
*
*
* @author wangbing
* @version 0.0.1
* @since 1.8
*/
public class AiMessage extends Message {
}

@ -1,176 +0,0 @@
package xyz.wbsite.achat.core.message;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
import xyz.wbsite.achat.core.base.Event;
import xyz.wbsite.achat.core.event.CompleteEvent;
import xyz.wbsite.achat.core.event.PartialEvent;
import xyz.wbsite.achat.core.prompt.MessagePrompt;
import xyz.wbsite.achat.core.service.MessageGenerator;
import java.io.IOException;
/**
* SSE
* SSE
*
* @author wangbing
* @version 0.0.1
* @since 1.8
*/
public class MessageSseEmitter extends SseEmitter {
/**
*
*/
private MessagePrompt messagePrompt;
/**
*
*/
private boolean complete;
/**
* AI
*/
private final StringBuilder answer = new StringBuilder();
/**
*
*/
private MessageGenerator messageGenerator;
/**
*
*
* @param message
*/
public MessageSseEmitter(MessagePrompt message, MessageGenerator processor) {
super(0L);
this.messagePrompt = message;
this.messageGenerator = processor;
// TaskUtil.taskAsync(task);
}
/**
*
*/
// public Runnable task = () -> {
// try {
// // 检查会话是否存在
// if (!messageProcessor.checkSessionExists(message.getChatId(), uid)) {
// this.sendMessage(createPartialMessage("当前会话不存在,请刷新后再试!"));
// return;
// }
//
// // 更新新会话的标题(如果为空)
// messageProcessor.updateSessionTitleIfEmpty(message.getChatId(), message.getText(), uid);
//
// // 保存本次用户消息
// messageProcessor.saveUserMessage(message.getChatId(), message.getText(), uid);
//
// // 根据是否有附件选择不同的处理方式
// TokenStream tokenStream;
// if (this.hasAttachment()) {
// String attachment = messageProcessor.parseAttachment(message.getAttachments(), uid);
// tokenStream = messageProcessor.createAssistantStreamWithAttachment(
// message.getChatId(), message.getText(), attachment, uid);
// } else {
// tokenStream = messageProcessor.createAssistantStream(
// message.getChatId(), message.getText(), uid);
// }
//
// // 设置流回调
// tokenStream
// .onPartialResponse(this::onPartialResponse)
// .onCompleteResponse(this::onCompleteResponse)
// .onError(this::onError)
// .start();
// } catch (Exception e) {
// onError(e);
// }
// };
/**
*
*/
private void onError(Throwable e) {
this.sendMessage(createPartialMessage("</think></think>" + e.getMessage()));
this.answer.append("</think></think>" + e.getMessage());
this.onCompleteResponse(null);
}
/**
*
*/
public void onPartialResponse(String msg) {
if (complete) {
return;
}
this.sendMessage(createPartialMessage(msg));
this.answer.append(msg);
}
/**
*
*/
public void onCompleteResponse(Object chatResponse) {
if (this.complete) {
return;
}
// 推送结束
this.sendMessage(createCompleteMessage());
// 关闭链接
this.complete();
}
/**
*
*/
private Event createPartialMessage(String partial) {
return new PartialEvent(messagePrompt.getSid(), partial);
}
/**
*
*/
private Event createCompleteMessage() {
return new CompleteEvent(messagePrompt.getSid());
}
/**
* send
*/
@Override
public void send(SseEventBuilder builder) throws IOException {
try {
super.send(builder);
} catch (Exception e) {
complete = true;
}
}
/**
*
*/
private void sendMessage(Event message) {
try {
this.send(message);
} catch (Exception e) {
complete = true;
}
}
/**
*
*/
public boolean isComplete() {
return complete;
}
/**
*
*/
public void setComplete(boolean complete) {
this.complete = complete;
}
}

@ -1,42 +0,0 @@
package xyz.wbsite.achat.core.message;
import xyz.wbsite.achat.core.base.Attachment;
import xyz.wbsite.achat.core.base.Message;
import java.util.List;
/**
*
*
* @author wangbing
* @version 0.0.1
* @since 1.8
*/
public class UserMessage extends Message {
/**
* ID
*/
private String uid;
/**
*
*/
private List<Attachment> attachments;
public String getUid() {
return uid;
}
public void setUid(String uid) {
this.uid = uid;
}
public List<Attachment> getAttachments() {
return attachments;
}
public void setAttachments(List<Attachment> attachments) {
this.attachments = attachments;
}
}

@ -0,0 +1,80 @@
package xyz.wbsite.achat.core.model;
import java.util.List;
/**
* OpenAI - OpenAIAPI
*
* @author wangbing
* @version 0.0.1
* @since 1.8
*/
public class Model {
private String id;
private String object;
private long created;
private String owned_by;
private List<Permission> permission;
private String root;
private String parent;
// Getters and Setters
public String getId() { return id; }
public void setId(String id) { this.id = id; }
public String getObject() { return object; }
public void setObject(String object) { this.object = object; }
public long getCreated() { return created; }
public void setCreated(long created) { this.created = created; }
public String getOwned_by() { return owned_by; }
public void setOwned_by(String owned_by) { this.owned_by = owned_by; }
public List<Permission> getPermission() { return permission; }
public void setPermission(List<Permission> permission) { this.permission = permission; }
public String getRoot() { return root; }
public void setRoot(String root) { this.root = root; }
public String getParent() { return parent; }
public void setParent(String parent) { this.parent = parent; }
/**
*
*/
public static class Permission {
private String id;
private String object;
private long created;
private boolean allow_create_engine;
private boolean allow_sampling;
private boolean allow_logprobs;
private boolean allow_search_indices;
private boolean allow_view;
private boolean allow_fine_tuning;
private String organization;
private String group;
private boolean is_blocking;
// Getters and Setters
public String getId() { return id; }
public void setId(String id) { this.id = id; }
public String getObject() { return object; }
public void setObject(String object) { this.object = object; }
public long getCreated() { return created; }
public void setCreated(long created) { this.created = created; }
public boolean isAllow_create_engine() { return allow_create_engine; }
public void setAllow_create_engine(boolean allow_create_engine) { this.allow_create_engine = allow_create_engine; }
public boolean isAllow_sampling() { return allow_sampling; }
public void setAllow_sampling(boolean allow_sampling) { this.allow_sampling = allow_sampling; }
public boolean isAllow_logprobs() { return allow_logprobs; }
public void setAllow_logprobs(boolean allow_logprobs) { this.allow_logprobs = allow_logprobs; }
public boolean isAllow_search_indices() { return allow_search_indices; }
public void setAllow_search_indices(boolean allow_search_indices) { this.allow_search_indices = allow_search_indices; }
public boolean isAllow_view() { return allow_view; }
public void setAllow_view(boolean allow_view) { this.allow_view = allow_view; }
public boolean isAllow_fine_tuning() { return allow_fine_tuning; }
public void setAllow_fine_tuning(boolean allow_fine_tuning) { this.allow_fine_tuning = allow_fine_tuning; }
public String getOrganization() { return organization; }
public void setOrganization(String organization) { this.organization = organization; }
public String getGroup() { return group; }
public void setGroup(String group) { this.group = group; }
public boolean isIs_blocking() { return is_blocking; }
public void setIs_blocking(boolean is_blocking) { this.is_blocking = is_blocking; }
}
}

@ -0,0 +1,21 @@
package xyz.wbsite.achat.core.model;
import java.util.List;
/**
* OpenAI - OpenAIAPI
*
* @author wangbing
* @version 0.0.1
* @since 1.8
*/
public class ModelListResponse {
private String object;
private List<Model> data;
// Getters and Setters
public String getObject() { return object; }
public void setObject(String object) { this.object = object; }
public List<Model> getData() { return data; }
public void setData(List<Model> data) { this.data = data; }
}

@ -1,106 +0,0 @@
package xyz.wbsite.achat.core.prompt;
import xyz.wbsite.achat.core.base.Message;
import xyz.wbsite.achat.core.base.Prompt;
import xyz.wbsite.achat.core.message.UserMessage;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class MessagePrompt extends Prompt {
/**
*
*/
private String model;
/**
*
*/
private List<Message> messages;
/**
*
*/
private Boolean stream;
/**
* token
*/
private Integer maxTokens;
/**
*
*/
private Double temperature;
/**
*
*/
private Map<String, Object> extraParams;
public String getModel() {
return model;
}
public void setModel(String model) {
this.model = model;
}
public List<Message> getMessages() {
return messages;
}
public void setMessages(List<Message> messages) {
this.messages = messages;
}
public Boolean getStream() {
return stream;
}
public void setStream(Boolean stream) {
this.stream = stream;
}
public Integer getMaxTokens() {
return maxTokens;
}
public void setMaxTokens(Integer maxTokens) {
this.maxTokens = maxTokens;
}
public Double getTemperature() {
return temperature;
}
public void setTemperature(Double temperature) {
this.temperature = temperature;
}
public Map<String, Object> getExtraParams() {
return extraParams;
}
public void setExtraParams(Map<String, Object> extraParams) {
this.extraParams = extraParams;
}
public UserMessage getLastUserMessage() {
List<Message> messageList = messages.stream().filter(message -> message instanceof UserMessage).collect(Collectors.toList());
UserMessage userMessage = (UserMessage)messageList.get(messageList.size() - 1);
return userMessage;
}
public String getUid() {
return getLastUserMessage().getUid();
}
public String getSid(){
return getLastUserMessage().getSid();
}
}

@ -1,18 +0,0 @@
package xyz.wbsite.achat.core.service;
import xyz.wbsite.achat.core.message.MessageSseEmitter;
import xyz.wbsite.achat.core.base.Message;
/**
*
* <p>
*
*
* @author wangbing
* @version 0.0.1
* @since 1.8
*/
public interface MessageGenerator {
void on(MessageSseEmitter emitter, Message message);
}

@ -1,85 +0,0 @@
package xyz.wbsite.achat.core.service;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
import xyz.wbsite.achat.core.base.Message;
import xyz.wbsite.achat.core.base.Result;
import xyz.wbsite.achat.core.base.Session;
import xyz.wbsite.achat.core.message.UserMessage;
import xyz.wbsite.achat.core.prompt.MessagePrompt;
import java.util.List;
/**
*
*
*
* @author wangbing
* @version 0.0.1
* @since 1.8
*/
public interface SessionService {
/**
*
*
* @param uid
* @return
*/
Result<Session> createSession(String uid);
/**
*
*
* @param sid ID
* @return
*/
Result<Void> deleteSession(String sid);
/**
*
*
* @param uid
* @return
*/
Result<List<Session>> listSessions(String uid);
/**
*
*
* @param sid ID
* @return
*/
Result<Session> getSession(String sid);
/**
*
*
* @param sid ID
* @return
*/
Result<Void> stopSession(String sid);
/**
*
*
* @param message
* @return SSE
*/
SseEmitter sendMessage(MessagePrompt message);
/**
*
*
* @param sid ID
* @return
*/
Result<List<Message>> listMessage(String sid);
/**
*
*
* @param sid ID
* @return
*/
Result<Void> deleteMessage(String sid);
}

@ -1,122 +0,0 @@
package xyz.wbsite.achat.core.service.impl;
import org.springframework.stereotype.Service;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
import xyz.wbsite.achat.core.message.MessageSseEmitter;
import xyz.wbsite.achat.core.base.Message;
import xyz.wbsite.achat.core.base.Result;
import xyz.wbsite.achat.core.base.Session;
import xyz.wbsite.achat.core.message.UserMessage;
import xyz.wbsite.achat.core.prompt.MessagePrompt;
import xyz.wbsite.achat.core.service.SessionService;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.stream.Collectors;
/**
*
*
*
* @author wangbing
* @version 0.0.1
* @since 1.8
*/
@Service
public class SessionServiceMemoryImpl implements SessionService {
private final Map<String, Session> sessionStore = new HashMap<>();
private final List<Message> messageStore = new ArrayList<>();
/**
*
*/
@Override
public Result<Session> createSession(String uid) {
Session session = new Session();
session.setId(String.valueOf(UUID.randomUUID().toString()));
session.setUid(uid);
session.setTitle("新对话");
sessionStore.put(session.getId(), session);
return Result.success(session);
}
/**
*
*/
@Override
public Result<Void> deleteSession(String sid) {
sessionStore.remove(sid);
return Result.success();
}
/**
*
*/
@Override
public Result<List<Session>> listSessions(String uid) {
List<Session> collect = sessionStore.values()
.stream()
.filter(item -> item.getUid().equals(uid))
.collect(Collectors.toList());
return Result.success(collect);
}
/**
*
*/
@Override
public Result<Session> getSession(String sid) {
Session session = sessionStore.get(sid);
if (session == null) {
return Result.error("会话不存在");
}
return Result.success(session);
}
/**
*
*/
@Override
public SseEmitter sendMessage(MessagePrompt message) {
// 创建VChatSseEmitter来处理流式响应
return new MessageSseEmitter(message, (emitter, message1) -> {
// 这边模拟LLM复述一遍用户问题
String text = message1.getContent();
for (char c : text.toCharArray()) {
if (emitter.isComplete()) {
return;
}
emitter.onPartialResponse(String.valueOf(c));
try {
Thread.sleep(100);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
emitter.onCompleteResponse(null);
});
}
@Override
public Result<Void> stopSession(String sid) {
// todo
return Result.success();
}
@Override
public Result<List<Message>> listMessage(String sid) {
List<Message> messages = messageStore.stream().filter(item -> item.getSid().equals(sid)).collect(Collectors.toList());
return Result.success(messages);
}
@Override
public Result<Void> deleteMessage(String sid) {
messageStore.forEach(item -> messageStore.remove(item));
return null;
}
}

@ -0,0 +1,34 @@
package xyz.wbsite.achat.core.session;
/**
*
*/
public class Message extends xyz.wbsite.achat.core.chat.Message {
private String id;
private String uid;
private String sid;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getUid() {
return uid;
}
public void setUid(String uid) {
this.uid = uid;
}
public String getSid() {
return sid;
}
public void setSid(String sid) {
this.sid = sid;
}
}

@ -1,7 +1,4 @@
package xyz.wbsite.achat.core.base;
import java.util.HashMap;
import java.util.Map;
package xyz.wbsite.achat.core.session;
/**
*
@ -33,16 +30,6 @@ public class Result<T> {
*/
private boolean success = true;
/**
*
*/
private Map<String, String> errors;
/**
* ID
*/
private String requestId;
/**
*
*/
@ -84,24 +71,6 @@ public class Result<T> {
return this;
}
public Map<String, String> getErrors() {
return errors;
}
public Result<T> setErrors(Map<String, String> errors) {
this.errors = errors;
return this;
}
public String getRequestId() {
return requestId;
}
public Result<T> setRequestId(String requestId) {
this.requestId = requestId;
return this;
}
public long getTimestamp() {
return timestamp;
}
@ -111,21 +80,6 @@ public class Result<T> {
return this;
}
/**
*
*
* @param field
* @param error
* @return
*/
public Result<T> addError(String field, String error) {
if (errors == null) {
errors = new HashMap<>();
}
errors.put(field, error);
return this;
}
/**
*
*

@ -1,6 +1,8 @@
package xyz.wbsite.achat.core.base;
package xyz.wbsite.achat.core.session;
import java.util.List;
/**
*
*
@ -28,6 +30,8 @@ public class Session {
private String lastTime;
private String lastMessage;
private List<Message> messages;
public String getId() {
return id;
}
@ -123,4 +127,12 @@ public class Session {
public void setLastMessage(String lastMessage) {
this.lastMessage = lastMessage;
}
public List<Message> getMessages() {
return messages;
}
public void setMessages(List<Message> messages) {
this.messages = messages;
}
}

@ -0,0 +1,56 @@
package xyz.wbsite.achat.core.session;
import xyz.wbsite.achat.core.chat.Message;
import java.util.List;
/**
*
*
*
* @author wangbing
* @version 0.0.1
* @since 1.8
*/
public interface SessionService {
/**
*
*
* @param uid
* @return
*/
Result<Session> createSession(String uid);
/**
*
*
* @param sid ID
* @return
*/
Result<Void> deleteSession(String uid, String sid);
/**
*
*
* @param uid
* @return
*/
Result<List<Session>> listSessions(String uid);
/**
*
*
* @param sid ID
* @return
*/
Result<Session> getSession(String uid,String sid);
/**
*
*
* @param sid ID
* @return
*/
Result<Void> deleteMessage(String uid, String sid, String mid);
}

@ -0,0 +1,173 @@
package xyz.wbsite.achat.core.session;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;
/**
*
*
*
* @author wangbing
* @version 0.0.1
* @since 1.8
*/
public class SessionServiceMemoryImpl implements SessionService {
/**
*
*/
private final List<Session> sessionStore = new ArrayList<>();
/**
*
*/
private final List<Message> messageStore = new ArrayList<>();
/**
*
*
* @param uid ID
* @return
*/
@Override
public Result<Session> createSession(String uid) {
// 检查参数合法性
if (uid == null || uid.isEmpty()) {
return Result.error("用户ID不能为空");
}
Session session = new Session();
session.setId(String.valueOf(UUID.randomUUID().toString()));
session.setUid(uid);
session.setTitle("新对话");
sessionStore.add(session);
return Result.success(session);
}
/**
*
*
* @param uid ID
* @param sid ID
* @return
*/
@Override
public Result<Void> deleteSession(String uid, String sid) {
// 检查参数合法性
if (uid == null || uid.isEmpty() || sid == null || sid.isEmpty()) {
return Result.error("用户ID或会话ID不能为空");
}
// 从sessionStore查找比对uid和sid然后删除
boolean sessionRemoved = sessionStore.removeIf(session ->
session.getId().equals(sid) && session.getUid().equals(uid)
);
// 从messageStore查找比对uid和sid然后删除
messageStore.removeIf(message ->
message.getUid().equals(uid) && message.getSid().equals(sid)
);
if (!sessionRemoved) {
return Result.error("会话不存在或无权限删除");
}
return Result.success();
}
/**
*
*
* @param uid ID
* @return
*/
/**
*
*
* @param uid ID
* @return
*/
@Override
public Result<List<Session>> listSessions(String uid) {
// 检查参数合法性
if (uid == null || uid.isEmpty()) {
return Result.error("用户ID不能为空");
}
// 从sessionStore查找比对uid返回所有会话
List<Session> userSessions = sessionStore.stream()
.filter(session -> session.getUid().equals(uid))
.collect(Collectors.toList());
return Result.success(userSessions);
}
/**
*
*
* @param uid ID
* @param sid ID
* @return
*/
@Override
public Result<Session> getSession(String uid, String sid) {
// 检查参数合法性
if (uid == null || uid.isEmpty() || sid == null || sid.isEmpty()) {
return Result.error("用户ID或会话ID不能为空");
}
// 从sessionStore查找比对uid和sid返回会话
Session session = sessionStore.stream()
.filter(s -> s.getId().equals(sid) && s.getUid().equals(uid))
.findFirst()
.orElse(null);
if (session == null) {
return Result.error("会话不存在或无权限查看");
}
// 创建会话副本
Session sessionCopy = new Session();
sessionCopy.setId(session.getId());
sessionCopy.setUid(session.getUid());
sessionCopy.setTitle(session.getTitle());
// 从messageStore检索出当前会话的聊天记录
List<Message> sessionMessages = messageStore.stream()
.filter(message -> message.getUid().equals(uid) && message.getSid().equals(sid))
.collect(Collectors.toList());
sessionCopy.setMessages(sessionMessages);
return Result.success(sessionCopy);
}
/**
*
*
* @param uid ID
* @param sid ID
* @param mid ID
* @return
*/
@Override
public Result<Void> deleteMessage(String uid, String sid, String mid) {
// 检查参数合法性
if (uid == null || uid.isEmpty() || sid == null || sid.isEmpty() || mid == null || mid.isEmpty()) {
return Result.error("用户ID、会话ID或消息ID不能为空");
}
// 从messageStore查找比对uid、sid和mid然后删除
boolean mr = messageStore.removeIf(message ->
message.getId().equals(mid) && message.getUid().equals(uid) && message.getSid().equals(sid)
);
if (!mr) {
return Result.error("消息不存在或无权限删除");
}
return Result.success();
}
}
Loading…
Cancel
Save

Powered by TurnKey Linux.