mirror of
https://github.com/coaidev/coai.git
synced 2025-05-19 21:10:18 +09:00
update mask feature
This commit is contained in:
parent
0b7d4c4108
commit
3773c43f76
@ -62,6 +62,7 @@
|
||||
|
||||
## 🔨 模型 | Models
|
||||
- [x] OpenAI ChatGPT (GPT-3.5, GPT-4, Instruct, DALL-E 2, DALL-E 3, Text-Davincci, ...)
|
||||
- [x] Azure OpenAI
|
||||
- [x] Anthropic Claude (claude-2, claude-instant)
|
||||
- [x] Slack Claude (deprecated)
|
||||
- [x] Sparkdesk (v1.5, v2, v3)
|
||||
@ -76,8 +77,6 @@
|
||||
- [x] Tencent Hunyuan
|
||||
- [x] 360 GPT
|
||||
- [ ] RWKV
|
||||
- [ ] Azure OpenAI
|
||||
- [ ] Baidu Qianfan
|
||||
|
||||
## 📚 预览 | Screenshots
|
||||

|
||||
|
@ -48,18 +48,15 @@ func NewChatInstanceFromConfig(v string) *ChatInstance {
|
||||
|
||||
func NewChatInstanceFromModel(props *InstanceProps) *ChatInstance {
|
||||
switch props.Model {
|
||||
case globals.GPT4, globals.GPT40314, globals.GPT40613, globals.GPT3Turbo1106, globals.GPT41106Preview,
|
||||
case globals.GPT4, globals.GPT40314, globals.GPT40613, globals.GPT3Turbo1106,
|
||||
globals.GPT432k, globals.GPT432k0613, globals.GPT432k0314:
|
||||
return NewChatInstanceFromConfig("gpt4")
|
||||
|
||||
case globals.GPT4Vision, globals.GPT4Dalle, globals.Dalle3, globals.GPT4All:
|
||||
case globals.GPT41106Preview, globals.GPT4Vision, globals.GPT4Dalle, globals.Dalle3, globals.GPT4All:
|
||||
return NewChatInstanceFromConfig("reverse")
|
||||
|
||||
case globals.GPT3Turbo, globals.GPT3TurboInstruct, globals.GPT3Turbo0613, globals.GPT3Turbo0301,
|
||||
globals.GPT3Turbo16k, globals.GPT3Turbo16k0301, globals.GPT3Turbo16k0613:
|
||||
if props.Plan {
|
||||
return NewChatInstanceFromConfig("subscribe")
|
||||
}
|
||||
return NewChatInstanceFromConfig("gpt3")
|
||||
|
||||
case globals.Dalle2:
|
||||
|
@ -5,6 +5,7 @@
|
||||
@layer base {
|
||||
:root {
|
||||
--background: 71 65% 97%;
|
||||
--background-hover: 56 43% 97%;
|
||||
--background-container: 71 65% 97%;
|
||||
--foreground: 222.2 84% 4.9%;
|
||||
|
||||
@ -58,6 +59,7 @@
|
||||
|
||||
.dark {
|
||||
--background: 0 0% 0%;
|
||||
--background-hover: 0 0% 7.8%;
|
||||
--background-container: 0 0% 7.8%;
|
||||
--foreground: 210 40% 98%;
|
||||
|
||||
|
@ -678,7 +678,7 @@
|
||||
.chat-box {
|
||||
position: relative;
|
||||
flex-grow: 1;
|
||||
margin: 0 4px;
|
||||
margin-right: 4px;
|
||||
}
|
||||
|
||||
.input-box {
|
||||
|
72
app/src/assets/pages/mask.less
Normal file
72
app/src/assets/pages/mask.less
Normal file
@ -0,0 +1,72 @@
|
||||
.mask-dialog {
|
||||
height: max-content;
|
||||
max-height: 50vh;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
scrollbar-width: thin;
|
||||
padding: 1rem 0.5rem 0.5rem;
|
||||
}
|
||||
|
||||
.mask-wrapper {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.mask-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
user-select: none;
|
||||
border: 1px solid hsl(var(--border));
|
||||
border-radius: var(--radius);
|
||||
overflow: hidden;
|
||||
margin-top: 1rem;
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
width: 0.25rem;
|
||||
}
|
||||
}
|
||||
|
||||
.mask-item {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
flex-shrink: 0;
|
||||
cursor: pointer;
|
||||
border-bottom: 1px solid hsl(var(--border));
|
||||
padding: 1rem 0;
|
||||
transition: 0.2s ease-in-out;
|
||||
|
||||
.mask-avatar {
|
||||
width: 2.25rem;
|
||||
height: 2.25rem;
|
||||
padding: 0.5rem;
|
||||
margin-right: 0.75rem;
|
||||
margin-left: 1rem;
|
||||
border-radius: var(--radius);
|
||||
border: 1px solid hsl(var(--border));
|
||||
transition: 0.2s ease-in-out;
|
||||
}
|
||||
|
||||
.mask-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.mask-name {
|
||||
color: hsl(var(--text));
|
||||
margin-right: 0.5rem;
|
||||
}
|
||||
|
||||
.mask-info {
|
||||
font-size: 12px;
|
||||
color: hsl(var(--text-secondary));
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: hsl(var(--background-hover));
|
||||
|
||||
.mask-avatar {
|
||||
border-color: hsl(var(--border-active));
|
||||
}
|
||||
}
|
||||
}
|
@ -29,7 +29,8 @@ function ChatInterface({ setTarget, setWorking }: ChatInterfaceProps) {
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
const working = messages.length > 0 && !messages[messages.length - 1].end;
|
||||
const end = messages[messages.length - 1].end;
|
||||
const working = messages.length > 0 && !(end === undefined ? true : end);
|
||||
setWorking?.(working);
|
||||
}, [messages]);
|
||||
|
||||
|
@ -108,10 +108,12 @@ function ChatWrapper() {
|
||||
});
|
||||
}
|
||||
|
||||
window.addEventListener("load", () => {
|
||||
const el = document.getElementById("input");
|
||||
if (el) el.focus();
|
||||
});
|
||||
useEffect(() => {
|
||||
window.addEventListener("load", () => {
|
||||
const el = document.getElementById("input");
|
||||
if (el) el.focus();
|
||||
});
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (!init) return;
|
||||
|
@ -8,7 +8,7 @@ import {
|
||||
} from "@/utils/env.ts";
|
||||
import { getMemory } from "@/utils/memory.ts";
|
||||
|
||||
export const version = "3.6.26";
|
||||
export const version = "3.6.27";
|
||||
export const dev: boolean = getDev();
|
||||
export const deploy: boolean = true;
|
||||
export let rest_api: string = getRestApi(deploy);
|
||||
|
@ -5,6 +5,7 @@ import { connectionEvent } from "@/events/connection.ts";
|
||||
import { AppDispatch } from "@/store";
|
||||
import { setMessages } from "@/store/chat.ts";
|
||||
import { modelEvent } from "@/events/model.ts";
|
||||
import {Mask} from "@/masks/types.ts";
|
||||
|
||||
type ConversationCallback = (idx: number, message: Message[]) => boolean;
|
||||
|
||||
@ -16,6 +17,7 @@ export class Conversation {
|
||||
public model: string;
|
||||
public data: Message[];
|
||||
public end: boolean;
|
||||
public mask: Mask | null;
|
||||
|
||||
public constructor(id: number, callback?: ConversationCallback) {
|
||||
if (callback) this.setCallback(callback);
|
||||
@ -24,6 +26,7 @@ export class Conversation {
|
||||
this.id = id;
|
||||
this.model = "";
|
||||
this.end = true;
|
||||
this.mask = null;
|
||||
this.connection = new Connection(this.id);
|
||||
|
||||
if (id === -1 && this.idx === -1) {
|
||||
@ -33,7 +36,7 @@ export class Conversation {
|
||||
);
|
||||
|
||||
this.load(data);
|
||||
this.sendEvent("share", refer);
|
||||
this.sendShareEvent(refer);
|
||||
});
|
||||
}
|
||||
|
||||
@ -47,7 +50,7 @@ export class Conversation {
|
||||
case "stop":
|
||||
this.end = true;
|
||||
this.data[this.data.length - 1].end = true;
|
||||
this.sendEvent("stop");
|
||||
this.sendStopEvent();
|
||||
this.triggerCallback();
|
||||
break;
|
||||
|
||||
@ -55,7 +58,7 @@ export class Conversation {
|
||||
this.end = false;
|
||||
delete this.data[this.data.length - 1];
|
||||
this.connection?.setCallback(this.useMessage());
|
||||
this.sendEvent("restart");
|
||||
this.sendRestartEvent();
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -75,6 +78,33 @@ export class Conversation {
|
||||
});
|
||||
}
|
||||
|
||||
public sendStopEvent() {
|
||||
this.sendEvent("stop");
|
||||
}
|
||||
|
||||
public sendRestartEvent() {
|
||||
this.sendEvent("restart");
|
||||
}
|
||||
|
||||
public sendMaskEvent(mask: Mask) {
|
||||
this.sendEvent("mask", JSON.stringify(mask.context));
|
||||
}
|
||||
|
||||
public sendShareEvent(refer: string) {
|
||||
this.sendEvent("share", refer);
|
||||
}
|
||||
|
||||
public preflightMask(mask: Mask) {
|
||||
this.mask = mask;
|
||||
}
|
||||
|
||||
public presentMask() {
|
||||
if (this.mask) {
|
||||
this.sendMaskEvent(this.mask);
|
||||
this.mask = null;
|
||||
}
|
||||
}
|
||||
|
||||
public setId(id: number): void {
|
||||
this.id = id;
|
||||
}
|
||||
@ -122,6 +152,10 @@ export class Conversation {
|
||||
return this.model;
|
||||
}
|
||||
|
||||
public isEmpty(): boolean {
|
||||
return this.getLength() === 0;
|
||||
}
|
||||
|
||||
public toggle(dispatch: AppDispatch): void {
|
||||
dispatch(setMessages(this.copyMessages()));
|
||||
modelEvent.emit(this.getModel());
|
||||
@ -198,6 +232,7 @@ export class Conversation {
|
||||
public sendMessage(t: any, props: ChatProps): boolean {
|
||||
if (!this.end) return false;
|
||||
|
||||
this.presentMask();
|
||||
this.addMessage({
|
||||
content: props.message,
|
||||
role: "user",
|
||||
@ -211,6 +246,7 @@ export class Conversation {
|
||||
public sendMessageWithRaise(t: any, id: number, props: ChatProps): boolean {
|
||||
if (!this.end) return false;
|
||||
|
||||
this.presentMask();
|
||||
this.addMessage({
|
||||
content: props.message,
|
||||
role: "user",
|
||||
|
@ -11,6 +11,8 @@ import { useShared } from "@/utils/hook.ts";
|
||||
import { ChatProps } from "@/conversation/connection.ts";
|
||||
import { AppDispatch } from "@/store";
|
||||
import { sharingEvent } from "@/events/sharing.ts";
|
||||
import {maskEvent} from "@/events/mask.ts";
|
||||
import {Mask} from "@/masks/types.ts";
|
||||
|
||||
export class Manager {
|
||||
conversations: Record<number, Conversation>;
|
||||
@ -22,15 +24,15 @@ export class Manager {
|
||||
this.conversations[-1] = this.createConversation(-1);
|
||||
this.current = -1;
|
||||
|
||||
const _this = this;
|
||||
sharingEvent.addEventListener(async (data) => {
|
||||
console.debug(`[manager] accept sharing event (refer: ${data.refer})`);
|
||||
await _this.newPage();
|
||||
});
|
||||
|
||||
const interval = setInterval(() => {
|
||||
if (this.dispatch) {
|
||||
this.toggle(this.dispatch, -1);
|
||||
clearInterval(interval);
|
||||
}
|
||||
}, 100);
|
||||
maskEvent.addEventListener(async (mask) => {
|
||||
console.debug(`[manager] accept mask event (name: ${mask.name})`);
|
||||
await _this.newMaskPage(mask);
|
||||
});
|
||||
}
|
||||
|
||||
@ -38,6 +40,30 @@ export class Manager {
|
||||
this.dispatch = dispatch;
|
||||
}
|
||||
|
||||
public async newPage(): Promise<void> {
|
||||
const interval = setInterval(() => {
|
||||
if (this.dispatch) {
|
||||
this.toggle(this.dispatch, -1);
|
||||
clearInterval(interval);
|
||||
}
|
||||
}, 100);
|
||||
}
|
||||
|
||||
public async newMaskPage(mask: Mask): Promise<void> {
|
||||
const interval = setInterval(() => {
|
||||
if (this.dispatch) {
|
||||
this.toggle(this.dispatch, -1);
|
||||
|
||||
const instance = this.get(-1);
|
||||
if (!instance) return;
|
||||
|
||||
instance.load(mask.context);
|
||||
instance.preflightMask(mask);
|
||||
clearInterval(interval);
|
||||
}
|
||||
}, 100);
|
||||
}
|
||||
|
||||
public callback(idx: number, message: Message[]): boolean {
|
||||
console.debug(
|
||||
`[manager] conversation receive message (id: ${idx}, length: ${message.length})`,
|
||||
@ -75,6 +101,11 @@ export class Manager {
|
||||
instance.setModel(res.model);
|
||||
}
|
||||
|
||||
public async load(id: number, data: Message[]): Promise<void> {
|
||||
if (!this.conversations[id]) await this.add(id);
|
||||
this.conversations[id].load(data);
|
||||
}
|
||||
|
||||
public async toggle(dispatch: AppDispatch, id: number): Promise<void> {
|
||||
if (!this.conversations[id]) await this.add(id);
|
||||
|
||||
|
@ -1,3 +1,4 @@
|
||||
import "@/assets/pages/mask.less";
|
||||
import {
|
||||
Dialog,
|
||||
DialogContent,
|
||||
@ -7,8 +8,71 @@ import {
|
||||
} from "@/components/ui/dialog.tsx";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import { selectMask, setMask } from "@/store/chat.ts";
|
||||
import {closeMask, selectMask, setMask} from "@/store/chat.ts";
|
||||
import {MASKS} from "@/masks/prompts.ts";
|
||||
import {Mask} from "@/masks/types.ts";
|
||||
import {Input} from "@/components/ui/input.tsx";
|
||||
import {useMemo, useState} from "react";
|
||||
import {splitList} from "@/utils/base.ts";
|
||||
import {maskEvent} from "@/events/mask.ts";
|
||||
|
||||
function getEmojiSource(emoji: string): string {
|
||||
return `https://cdn.staticfile.org/emoji-datasource-apple/14.0.0/img/apple/64/${emoji}.png`;
|
||||
}
|
||||
|
||||
function MaskItem({ mask }: { mask: Mask }) {
|
||||
const { t } = useTranslation();
|
||||
const dispatch = useDispatch();
|
||||
|
||||
return (
|
||||
<div className={`mask-item`} onClick={(e) => {
|
||||
e.preventDefault();
|
||||
|
||||
maskEvent.emit(mask);
|
||||
dispatch(closeMask());
|
||||
}}>
|
||||
<img src={getEmojiSource(mask.avatar)} alt={``} className={`mask-avatar`} />
|
||||
<div className={`mask-content`}>
|
||||
<div className={`mask-name`}>{mask.name}</div>
|
||||
<div className={`mask-info`}>
|
||||
{t('mask.context', { length: mask.context.length })}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
function MaskSelector() {
|
||||
const { t } = useTranslation();
|
||||
const [search, setSearch] = useState("");
|
||||
const arr = useMemo(() => {
|
||||
if (search.trim().length === 0) return MASKS;
|
||||
|
||||
const raw = splitList(search.toLowerCase(), [" ", ",", ";", "-"]);
|
||||
return MASKS.filter((mask) => {
|
||||
return raw.every((keyword) => (
|
||||
mask.name.toLowerCase().includes(keyword.toLowerCase())
|
||||
));
|
||||
});
|
||||
}, [search]);
|
||||
|
||||
return (
|
||||
<div className={`mask-wrapper`}>
|
||||
<Input value={search} onChange={(e) => setSearch(e.target.value)} placeholder={t("mask.search")} />
|
||||
<div className={`mask-list`}>
|
||||
{
|
||||
arr.length > 0 ? arr.map((mask, index) => (
|
||||
<MaskItem key={index} mask={mask} />
|
||||
)) : (
|
||||
<p className={`my-8 text-center`}>
|
||||
{t('conversation.empty')}
|
||||
</p>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
function MaskDialog() {
|
||||
const { t } = useTranslation();
|
||||
const dispatch = useDispatch();
|
||||
@ -21,7 +85,7 @@ function MaskDialog() {
|
||||
<DialogTitle>{t("mask.title")}</DialogTitle>
|
||||
<DialogDescription asChild>
|
||||
<div className={`mask-dialog`}>
|
||||
<div className={`mask-wrapper`}></div>
|
||||
<MaskSelector />
|
||||
</div>
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
|
7
app/src/events/mask.ts
Normal file
7
app/src/events/mask.ts
Normal file
@ -0,0 +1,7 @@
|
||||
import {Mask} from "@/masks/types.ts";
|
||||
import {EventCommitter} from "@/events/struct.ts";
|
||||
|
||||
export const maskEvent = new EventCommitter<Mask>({
|
||||
name: "mask",
|
||||
destroyedAfterTrigger: true,
|
||||
});
|
@ -321,6 +321,8 @@ const resources = {
|
||||
},
|
||||
mask: {
|
||||
title: "预设设置",
|
||||
search: "搜索预设名称",
|
||||
context: "包含 {{length}} 条上下文",
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -654,6 +656,11 @@ const resources = {
|
||||
"generate-result": "Generate Result",
|
||||
error: "Request Failed",
|
||||
},
|
||||
mask: {
|
||||
title: "Mask Settings",
|
||||
search: "Search Mask Name",
|
||||
context: "Contains {{length}} context",
|
||||
},
|
||||
},
|
||||
},
|
||||
ru: {
|
||||
@ -989,6 +996,11 @@ const resources = {
|
||||
"generate-result": "Результат",
|
||||
error: "Ошибка запроса",
|
||||
},
|
||||
mask: {
|
||||
title: "Настройки маски",
|
||||
search: "Поиск по имени маски",
|
||||
context: "Содержит {{length}} контекст",
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
@ -97,6 +97,46 @@ export const EN_MASKS: Mask[] = [
|
||||
];
|
||||
|
||||
export const CN_MASKS: Mask[] = [
|
||||
{ // created by @ProgramZmh
|
||||
avatar: "1f9d0",
|
||||
name: "数学家",
|
||||
context: [
|
||||
{
|
||||
role: "system",
|
||||
content:
|
||||
"数学家擅长数学领域的各种知识。数学家的回答应该是严谨的数学语言,包括数学公式和推理过程。" +
|
||||
"公式使用 $$ f $$ 包裹,推理过程使用 > 开头。" +
|
||||
"推理过程中步骤之间使用空行分隔,以1. 2. 3. ...开头。"
|
||||
},
|
||||
{
|
||||
role: "user",
|
||||
content:
|
||||
"我想让你担任数学家。你需要用严谨的数学语言回答。你的回答应该包括数学公式和推理过程。",
|
||||
},
|
||||
],
|
||||
lang: "cn",
|
||||
builtin: true,
|
||||
},
|
||||
{ // created by @ProgramZmh
|
||||
avatar: "1f468-200d-1f393",
|
||||
name: "经济学家",
|
||||
context: [
|
||||
{
|
||||
role: "system",
|
||||
content:
|
||||
"经济学家精通各种经济学知识和理论。" +
|
||||
"经济学家的回答应当以严谨的语言和深入的经济分析为主,包括宏观经济和微观经济的理论、财政政策、货币政策等等。" +
|
||||
"他们必须能够合理使用经济模型和数据分析,解释和预测经济现象及其影响。"
|
||||
},
|
||||
{
|
||||
role: "user",
|
||||
content:
|
||||
"我想让你担任经济学家。你需要用严谨的语言和深入的经济分析回答。你的回答应该包括宏观经济和微观经济的理论、财政政策、货币政策等等。",
|
||||
},
|
||||
],
|
||||
lang: "cn",
|
||||
builtin: true,
|
||||
},
|
||||
{
|
||||
avatar: "1f5bc-fe0f",
|
||||
name: "以文搜图",
|
||||
@ -317,7 +357,7 @@ export const CN_MASKS: Mask[] = [
|
||||
},
|
||||
{
|
||||
avatar: "1f513",
|
||||
name: "越狱模式 [Jailbreak]",
|
||||
name: "开发者模式",
|
||||
context: [
|
||||
{
|
||||
role: "user",
|
||||
|
@ -15,6 +15,7 @@ const (
|
||||
StopType = "stop"
|
||||
RestartType = "restart"
|
||||
ShareType = "share"
|
||||
MaskType = "mask"
|
||||
)
|
||||
|
||||
type Stack chan *conversation.FormMessage
|
||||
|
@ -9,6 +9,8 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
const defaultConversationName = "new chat"
|
||||
|
||||
type Conversation struct {
|
||||
Auth bool `json:"auth"`
|
||||
UserID int64 `json:"user_id"`
|
||||
@ -34,7 +36,7 @@ func NewAnonymousConversation() *Conversation {
|
||||
Auth: false,
|
||||
UserID: -1,
|
||||
Id: -1,
|
||||
Name: "anonymous",
|
||||
Name: defaultConversationName,
|
||||
Message: []globals.Message{},
|
||||
Model: globals.GPT3Turbo,
|
||||
IgnoreContext: false,
|
||||
@ -46,7 +48,7 @@ func NewConversation(db *sql.DB, id int64) *Conversation {
|
||||
Auth: true,
|
||||
UserID: id,
|
||||
Id: GetConversationLengthByUserID(db, id) + 1,
|
||||
Name: "new chat",
|
||||
Name: defaultConversationName,
|
||||
Message: []globals.Message{},
|
||||
Model: globals.GPT3Turbo,
|
||||
}
|
||||
@ -111,7 +113,7 @@ func (c *Conversation) GetName() string {
|
||||
}
|
||||
|
||||
func (c *Conversation) SetName(db *sql.DB, name string) {
|
||||
c.Name = name
|
||||
c.Name = utils.Extract(name, 50, "...")
|
||||
c.SaveConversation(db)
|
||||
}
|
||||
|
||||
@ -239,12 +241,12 @@ func (c *Conversation) AddMessageFromForm(form *FormMessage) error {
|
||||
}
|
||||
|
||||
func (c *Conversation) HandleMessage(db *sql.DB, form *FormMessage) bool {
|
||||
head := len(c.Message) == 0
|
||||
head := len(c.Message) == 0 || c.Name == defaultConversationName
|
||||
if err := c.AddMessageFromForm(form); err != nil {
|
||||
return false
|
||||
}
|
||||
if head {
|
||||
c.SetName(db, utils.Extract(form.Message, 50, "..."))
|
||||
c.SetName(db, form.Message)
|
||||
}
|
||||
c.SaveConversation(db)
|
||||
return true
|
||||
|
13
manager/conversation/mask.go
Normal file
13
manager/conversation/mask.go
Normal file
@ -0,0 +1,13 @@
|
||||
package conversation
|
||||
|
||||
import (
|
||||
"chat/globals"
|
||||
"chat/utils"
|
||||
)
|
||||
|
||||
func (c *Conversation) LoadMask(data string) {
|
||||
message := utils.UnmarshalForm[[]globals.Message](data)
|
||||
if message != nil && len(*message) > 0 {
|
||||
c.InsertMessages(*message, 0)
|
||||
}
|
||||
}
|
@ -73,10 +73,17 @@ func ChatAPI(c *gin.Context) {
|
||||
instance.LoadSharing(db, form.Message)
|
||||
case RestartType:
|
||||
if message := instance.RemoveLatestMessage(); message.Role != globals.Assistant {
|
||||
conn.Send(globals.ChatSegmentResponse{
|
||||
Message: "Hello, How can I assist you?",
|
||||
End: true,
|
||||
})
|
||||
return fmt.Errorf("message type error")
|
||||
}
|
||||
|
||||
response := ChatHandler(buf, user, instance)
|
||||
instance.SaveResponse(db, response)
|
||||
case MaskType:
|
||||
instance.LoadMask(form.Message)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
Loading…
Reference in New Issue
Block a user