Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
赵月辉
/
fastgpt-migrated
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Unverified
Commit
67e10d6f
authored
Jul 23, 2023
by
archer
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
perf: completion chatId
parent
b7d18e38
Show whitespace changes
Inline
Side-by-side
Showing
35 changed files
with
411 additions
and
349 deletions
+411
-349
client/src/api/chat.ts
+1
-1
client/src/api/fetch.ts
+1
-0
client/src/api/response/chat.d.ts
+0
-1
client/src/components/ChatBox/index.tsx
+4
-4
client/src/pages/api/admin/initChat.ts
+61
-0
client/src/pages/api/admin/initPromotion.ts
+0
-47
client/src/pages/api/chat/delChatRecordByContentId.ts
+1
-1
client/src/pages/api/chat/history/getHistory.ts
+2
-2
client/src/pages/api/chat/history/getHistoryQuote.ts
+2
-3
client/src/pages/api/chat/history/updateChatHistory.ts
+1
-1
client/src/pages/api/chat/history/updateHistoryQuote.ts
+1
-1
client/src/pages/api/chat/init.ts
+22
-33
client/src/pages/api/chat/removeHistory.ts
+2
-2
client/src/pages/api/chat/saveChat.ts
+0
-104
client/src/pages/api/chat/shareChat/create.ts
+2
-3
client/src/pages/api/chat/shareChat/init.ts
+5
-11
client/src/pages/api/chat/shareChat/list.ts
+0
-1
client/src/pages/api/openapi/v1/chat/completions.ts
+21
-18
client/src/pages/api/openapi/v1/chat/getHistory.ts
+2
-4
client/src/pages/api/system/getInitData.ts
+60
-0
client/src/pages/app/detail/components/BasicEdit/index.tsx
+2
-1
client/src/pages/app/detail/components/Edit/components/ChatTest.tsx
+5
-2
client/src/pages/chat/index.tsx
+53
-26
client/src/pages/chat/share.tsx
+36
-28
client/src/pages/number/index.tsx
+10
-4
client/src/service/models/chat.ts
+27
-15
client/src/service/models/shareChat.ts
+0
-4
client/src/service/moduleDispatch/chat/oneapi.ts
+3
-3
client/src/service/utils/chat/saveChat.ts
+65
-0
client/src/store/chat.ts
+2
-2
client/src/store/shareChat.ts
+12
-19
client/src/types/app.d.ts
+0
-1
client/src/types/chat.d.ts
+3
-5
client/src/types/index.d.ts
+1
-1
client/src/types/mongoSchema.d.ts
+4
-1
No files found.
client/src/api/chat.ts
View file @
67e10d6f
...
...
@@ -22,7 +22,7 @@ export const getChatHistory = (data: RequestPaging & { appId?: string }) =>
/**
* 删除一条历史记录
*/
export
const
delChatHistoryById
=
(
id
:
string
)
=>
GET
(
`/chat/removeHistory?id=
${
id
}
`
);
export
const
delChatHistoryById
=
(
chatId
:
string
)
=>
DELETE
(
`/chat/removeHistory`
,
{
chatId
}
);
/**
* get history quotes
...
...
client/src/api/fetch.ts
View file @
67e10d6f
...
...
@@ -78,6 +78,7 @@ export const streamFetch = ({
onMessage
(
answer
);
responseText
+=
answer
;
}
else
if
(
item
.
event
===
sseResponseEventEnum
.
appStreamResponse
)
{
console
.
log
(
data
);
}
else
if
(
item
.
event
===
sseResponseEventEnum
.
error
)
{
errMsg
=
getErrText
(
data
,
'流响应错误'
);
}
...
...
client/src/api/response/chat.d.ts
View file @
67e10d6f
...
...
@@ -20,7 +20,6 @@ export interface InitChatResponse {
export
interface
InitShareChatResponse
{
userAvatar
:
string
;
maxContext
:
number
;
app
:
{
variableModules
?:
VariableItemType
[];
welcomeText
?:
string
;
...
...
client/src/components/ChatBox/index.tsx
View file @
67e10d6f
...
...
@@ -19,7 +19,6 @@ import {
getErrText
}
from
'@/utils/tools'
;
import
{
Box
,
Card
,
Flex
,
Input
,
Textarea
,
Button
,
useTheme
}
from
'@chakra-ui/react'
;
import
{
useUserStore
}
from
'@/store/user'
;
import
{
feConfigs
}
from
'@/store/static'
;
import
{
Types
}
from
'mongoose'
;
import
{
EventNameEnum
}
from
'../Markdown/constant'
;
...
...
@@ -118,6 +117,7 @@ const ChatBox = (
showEmptyIntro
=
false
,
chatId
,
appAvatar
,
userAvatar
,
variableModules
,
welcomeText
,
onUpdateVariable
,
...
...
@@ -126,7 +126,8 @@ const ChatBox = (
}:
{
showEmptyIntro
?:
boolean
;
chatId
?:
string
;
appAvatar
:
string
;
appAvatar
?:
string
;
userAvatar
?:
string
;
variableModules
?:
VariableItemType
[];
welcomeText
?:
string
;
onUpdateVariable
?:
(
e
:
Record
<
string
,
any
>
)
=>
void
;
...
...
@@ -142,7 +143,6 @@ const ChatBox = (
const
router
=
useRouter
();
const
{
copyData
}
=
useCopyData
();
const
{
toast
}
=
useToast
();
const
{
userInfo
}
=
useUserStore
();
const
{
isPc
}
=
useGlobalStore
();
const
TextareaDom
=
useRef
<
HTMLTextAreaElement
>
(
null
);
const
controller
=
useRef
(
new
AbortController
());
...
...
@@ -585,7 +585,7 @@ const ChatBox = (
)
}
</
Flex
>
</
Box
>
<
ChatAvatar
src=
{
user
Info
?.
a
vatar
}
ml=
{
[
'6px'
,
2
]
}
/>
<
ChatAvatar
src=
{
user
A
vatar
}
ml=
{
[
'6px'
,
2
]
}
/>
</>
)
}
{
item
.
obj
===
'AI'
&&
(
...
...
client/src/pages/api/admin/initChat.ts
0 → 100644
View file @
67e10d6f
// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
import
type
{
NextApiRequest
,
NextApiResponse
}
from
'next'
;
import
{
jsonRes
}
from
'@/service/response'
;
import
{
authUser
}
from
'@/service/utils/auth'
;
import
{
connectToDatabase
,
TrainingData
,
User
,
promotionRecord
,
Chat
}
from
'@/service/mongo'
;
import
{
PRICE_SCALE
}
from
'@/constants/common'
;
export
default
async
function
handler
(
req
:
NextApiRequest
,
res
:
NextApiResponse
)
{
try
{
await
authUser
({
req
,
authRoot
:
true
});
await
connectToDatabase
();
const
{
limit
=
1000
}
=
req
.
body
as
{
limit
:
number
};
let
skip
=
0
;
const
total
=
await
Chat
.
countDocuments
({
chatId
:
{
$exists
:
false
}
});
let
promise
=
Promise
.
resolve
();
console
.
log
(
total
);
for
(
let
i
=
0
;
i
<
total
;
i
+=
limit
)
{
const
skipVal
=
skip
;
skip
+=
limit
;
promise
=
promise
.
then
(()
=>
init
(
limit
,
skipVal
))
.
then
(()
=>
{
console
.
log
(
skipVal
);
});
}
await
promise
;
jsonRes
(
res
,
{});
}
catch
(
error
)
{
jsonRes
(
res
,
{
code
:
500
,
error
});
}
}
async
function
init
(
limit
:
number
,
skip
:
number
)
{
// 遍历 app
const
chats
=
await
Chat
.
find
(
{
chatId
:
{
$exists
:
false
}
},
'_id'
)
.
limit
(
limit
)
.
skip
(
skip
);
await
Promise
.
all
(
chats
.
map
((
chat
)
=>
Chat
.
findByIdAndUpdate
(
chat
.
_id
,
{
chatId
:
String
(
chat
.
_id
),
source
:
'online'
})
)
);
}
client/src/pages/api/admin/initPromotion.ts
deleted
100644 → 0
View file @
b7d18e38
// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
import
type
{
NextApiRequest
,
NextApiResponse
}
from
'next'
;
import
{
jsonRes
}
from
'@/service/response'
;
import
{
authUser
}
from
'@/service/utils/auth'
;
import
{
connectToDatabase
,
TrainingData
,
User
,
promotionRecord
}
from
'@/service/mongo'
;
import
{
PRICE_SCALE
}
from
'@/constants/common'
;
export
default
async
function
handler
(
req
:
NextApiRequest
,
res
:
NextApiResponse
)
{
try
{
await
authUser
({
req
,
authRoot
:
true
});
await
connectToDatabase
();
// 计算剩余金额
const
countResidue
:
{
userId
:
string
;
totalAmount
:
number
}[]
=
await
promotionRecord
.
aggregate
(
[
{
$group
:
{
_id
:
'$userId'
,
// Group by userId
totalAmount
:
{
$sum
:
'$amount'
}
// Calculate the sum of amount field
}
},
{
$project
:
{
_id
:
false
,
// Exclude _id field
userId
:
'$_id'
,
// Include userId field
totalAmount
:
true
// Include totalAmount field
}
}
]
);
await
Promise
.
all
(
countResidue
.
map
((
item
)
=>
User
.
findByIdAndUpdate
(
item
.
userId
,
{
$inc
:
{
balance
:
item
.
totalAmount
*
PRICE_SCALE
}
})
)
);
jsonRes
(
res
,
{
data
:
countResidue
});
}
catch
(
error
)
{
jsonRes
(
res
,
{
code
:
500
,
error
});
}
}
client/src/pages/api/chat/delChatRecordByContentId.ts
View file @
67e10d6f
...
...
@@ -16,7 +16,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
// 凭证校验
const
{
userId
}
=
await
authUser
({
req
,
authToken
:
true
});
const
chatRecord
=
await
Chat
.
find
ById
(
chatId
);
const
chatRecord
=
await
Chat
.
find
One
({
chatId
}
);
if
(
!
chatRecord
)
{
throw
new
Error
(
'找不到对话'
);
...
...
client/src/pages/api/chat/history/getHistory.ts
View file @
67e10d6f
...
...
@@ -17,14 +17,14 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
userId
,
...(
appId
&&
{
appId
})
},
'
_i
d title top customTitle appId updateTime'
'
chatI
d title top customTitle appId updateTime'
)
.
sort
({
top
:
-
1
,
updateTime
:
-
1
})
.
limit
(
20
);
jsonRes
<
ChatHistoryItemType
[]
>
(
res
,
{
data
:
data
.
map
((
item
)
=>
({
_id
:
item
.
_i
d
,
chatId
:
item
.
chatI
d
,
updateTime
:
item
.
updateTime
,
appId
:
item
.
appId
,
customTitle
:
item
.
customTitle
,
...
...
client/src/pages/api/chat/history/getHistoryQuote.ts
View file @
67e10d6f
...
...
@@ -3,7 +3,6 @@ import { jsonRes } from '@/service/response';
import
{
connectToDatabase
,
Chat
}
from
'@/service/mongo'
;
import
{
authUser
}
from
'@/service/utils/auth'
;
import
{
Types
}
from
'mongoose'
;
import
{
rawSearchKey
}
from
'@/constants/chat'
;
export
default
async
function
handler
(
req
:
NextApiRequest
,
res
:
NextApiResponse
)
{
try
{
...
...
@@ -36,13 +35,13 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
},
{
$project
:
{
[
rawSearchKey
]:
`$content.
${
rawSearchKey
}
`
//
[rawSearchKey]: `$content.${rawSearchKey}`
}
}
]);
jsonRes
(
res
,
{
data
:
history
[
0
]?.[
rawSearchKey
]
||
[]
//
data: history[0]?.[rawSearchKey] || []
});
}
catch
(
err
)
{
jsonRes
(
res
,
{
...
...
client/src/pages/api/chat/history/updateChatHistory.ts
View file @
67e10d6f
...
...
@@ -20,7 +20,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
await
Chat
.
findOneAndUpdate
(
{
_id
:
chatId
,
chatId
,
userId
},
{
...
...
client/src/pages/api/chat/history/updateHistoryQuote.ts
View file @
67e10d6f
...
...
@@ -27,7 +27,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
await
Chat
.
updateOne
(
{
_id
:
new
Types
.
ObjectId
(
chatId
)
,
chatId
,
userId
:
new
Types
.
ObjectId
(
userId
),
'content._id'
:
new
Types
.
ObjectId
(
contentId
)
},
...
...
client/src/pages/api/chat/init.ts
View file @
67e10d6f
...
...
@@ -6,8 +6,7 @@ import { authUser } from '@/service/utils/auth';
import
{
ChatItemType
}
from
'@/types/chat'
;
import
{
authApp
}
from
'@/service/utils/auth'
;
import
mongoose
from
'mongoose'
;
import
type
{
AppSchema
,
ChatSchema
}
from
'@/types/mongoSchema'
;
import
{
quoteLenKey
,
rawSearchKey
}
from
'@/constants/chat'
;
import
type
{
ChatSchema
}
from
'@/types/mongoSchema'
;
import
{
getSpecialModule
}
from
'@/components/ChatBox'
;
/* 初始化我的聊天框,需要身份验证 */
...
...
@@ -20,52 +19,39 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
chatId
:
''
|
string
;
};
await
connectToDatabase
();
// 没有 appId 时,直接获取用户的第一个id
const
app
=
await
(
async
()
=>
{
if
(
!
appId
)
{
const
myModel
=
await
App
.
findOne
({
userId
});
if
(
!
myModel
)
{
const
{
_id
}
=
await
App
.
create
({
name
:
'应用1'
,
userId
return
jsonRes
(
res
,
{
code
:
501
,
message
:
"You don't have an app yet"
});
return
(
await
App
.
findById
(
_id
))
as
AppSchema
;
}
else
{
return
myModel
;
}
}
else
{
await
connectToDatabase
();
// 校验使用权限
const
authRes
=
await
authApp
({
const
app
=
(
await
authApp
({
appId
,
userId
,
authUser
:
false
,
authOwner
:
false
});
return
authRes
.
app
;
}
})();
appId
=
appId
||
app
.
_id
;
})
).
app
;
// 历史记录
const
{
chat
,
history
=
[]
}:
{
chat
?:
ChatSchema
;
history
?:
ChatItemType
[]
}
=
await
(
async
()
=>
{
if
(
chatId
)
{
// auth chatId
const
chat
=
await
Chat
.
findOne
({
_id
:
chatId
,
const
[
chat
,
history
]
=
await
Promise
.
all
([
Chat
.
findOne
({
chatId
,
userId
});
if
(
!
chat
)
{
throw
new
Error
(
'聊天框不存在'
);
}
// 获取 chat.content 数据
const
history
=
await
Chat
.
aggregate
([
}),
Chat
.
aggregate
([
{
$match
:
{
_id
:
new
mongoose
.
Types
.
ObjectId
(
chatId
)
,
chatId
,
userId
:
new
mongoose
.
Types
.
ObjectId
(
userId
)
}
},
...
...
@@ -81,11 +67,14 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
$project
:
{
_id
:
'$content._id'
,
obj
:
'$content.obj'
,
value
:
'$content.value'
,
[
quoteLenKey
]:
{
$size
:
{
$ifNull
:
[
`$content.
${
rawSearchKey
}
`
,
[]]
}
}
value
:
'$content.value'
}
}
])
]);
if
(
!
chat
)
{
throw
new
Error
(
'聊天框不存在'
);
}
return
{
history
,
chat
};
}
return
{};
...
...
client/src/pages/api/chat/removeHistory.ts
View file @
67e10d6f
...
...
@@ -6,13 +6,13 @@ import { authUser } from '@/service/utils/auth';
/* 获取历史记录 */
export
default
async
function
handler
(
req
:
NextApiRequest
,
res
:
NextApiResponse
)
{
try
{
const
{
i
d
}
=
req
.
query
;
const
{
chatI
d
}
=
req
.
query
;
const
{
userId
}
=
await
authUser
({
req
,
authToken
:
true
});
await
connectToDatabase
();
await
Chat
.
findOneAndRemove
({
_id
:
i
d
,
chatI
d
,
userId
});
...
...
client/src/pages/api/chat/saveChat.ts
deleted
100644 → 0
View file @
b7d18e38
import
type
{
NextApiRequest
,
NextApiResponse
}
from
'next'
;
import
{
jsonRes
}
from
'@/service/response'
;
import
{
ChatItemType
}
from
'@/types/chat'
;
import
{
connectToDatabase
,
Chat
,
App
}
from
'@/service/mongo'
;
import
{
authApp
}
from
'@/service/utils/auth'
;
import
{
authUser
}
from
'@/service/utils/auth'
;
import
{
Types
}
from
'mongoose'
;
type
Props
=
{
chatId
?:
string
;
appId
:
string
;
variables
?:
Record
<
string
,
any
>
;
prompts
:
[
ChatItemType
,
ChatItemType
];
};
/* 聊天内容存存储 */
export
default
async
function
handler
(
req
:
NextApiRequest
,
res
:
NextApiResponse
)
{
try
{
const
{
chatId
,
appId
,
prompts
}
=
req
.
body
as
Props
;
if
(
!
prompts
)
{
throw
new
Error
(
'缺少参数'
);
}
const
{
userId
}
=
await
authUser
({
req
,
authToken
:
true
});
const
response
=
await
saveChat
({
chatId
,
appId
,
prompts
,
userId
});
jsonRes
(
res
,
{
data
:
response
});
}
catch
(
err
)
{
jsonRes
(
res
,
{
code
:
500
,
error
:
err
});
}
}
export
async
function
saveChat
({
newChatId
,
chatId
,
appId
,
prompts
,
variables
,
userId
}:
Props
&
{
newChatId
?:
Types
.
ObjectId
;
userId
:
string
}):
Promise
<
{
newChatId
:
string
}
>
{
await
connectToDatabase
();
const
{
app
}
=
await
authApp
({
appId
,
userId
,
authOwner
:
false
});
if
(
String
(
app
.
userId
)
===
userId
)
{
await
App
.
findByIdAndUpdate
(
appId
,
{
updateTime
:
new
Date
()
});
}
const
[
response
]
=
await
Promise
.
all
([
...(
chatId
?
[
Chat
.
findByIdAndUpdate
(
chatId
,
{
$push
:
{
content
:
{
$each
:
prompts
}
},
variables
,
title
:
prompts
[
0
].
value
.
slice
(
0
,
20
),
updateTime
:
new
Date
()
}).
then
(()
=>
({
newChatId
:
''
}))
]
:
[
Chat
.
create
({
_id
:
newChatId
,
userId
,
appId
,
variables
,
content
:
prompts
,
title
:
prompts
[
0
].
value
.
slice
(
0
,
20
)
}).
then
((
res
)
=>
({
newChatId
:
String
(
res
.
_id
)
}))
]),
// update app
...(
String
(
app
.
userId
)
===
userId
?
[
App
.
findByIdAndUpdate
(
appId
,
{
updateTime
:
new
Date
()
})
]
:
[])
]);
return
{
// @ts-ignore
newChatId
:
response
?.
newChatId
||
''
};
}
client/src/pages/api/chat/shareChat/create.ts
View file @
67e10d6f
...
...
@@ -9,7 +9,7 @@ const nanoid = customAlphabet('abcdefghijklmnopqrstuvwxyz1234567890', 24);
/* create a shareChat */
export
default
async
function
handler
(
req
:
NextApiRequest
,
res
:
NextApiResponse
)
{
try
{
const
{
appId
,
name
,
maxContext
}
=
req
.
body
as
ShareChatEditType
&
{
const
{
appId
,
name
}
=
req
.
body
as
ShareChatEditType
&
{
appId
:
string
;
};
...
...
@@ -27,8 +27,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
shareId
,
userId
,
appId
,
name
,
maxContext
name
});
jsonRes
(
res
,
{
...
...
client/src/pages/api/chat/shareChat/init.ts
View file @
67e10d6f
...
...
@@ -3,10 +3,7 @@ import { jsonRes } from '@/service/response';
import
{
connectToDatabase
,
ShareChat
,
User
}
from
'@/service/mongo'
;
import
type
{
InitShareChatResponse
}
from
'@/api/response/chat'
;
import
{
authApp
}
from
'@/service/utils/auth'
;
import
{
hashPassword
}
from
'@/service/utils/tools'
;
import
{
HUMAN_ICON
}
from
'@/constants/chat'
;
import
{
FlowModuleTypeEnum
}
from
'@/constants/flow'
;
import
{
SystemInputEnum
}
from
'@/constants/app'
;
import
{
getSpecialModule
}
from
'@/components/ChatBox'
;
/* 初始化我的聊天框,需要身份验证 */
...
...
@@ -33,21 +30,18 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
}
// 校验使用权限
const
{
app
}
=
await
authApp
({
const
[{
app
},
user
]
=
await
Promise
.
all
([
authApp
({
appId
:
shareChat
.
appId
,
userId
:
String
(
shareChat
.
userId
),
authOwner
:
false
});
const
user
=
await
User
.
findById
(
shareChat
.
userId
,
'avatar'
);
}),
User
.
findById
(
shareChat
.
userId
,
'avatar'
)
]
);
jsonRes
<
InitShareChatResponse
>
(
res
,
{
data
:
{
userAvatar
:
user
?.
avatar
||
HUMAN_ICON
,
maxContext
:
app
.
modules
?.
find
((
item
)
=>
item
.
flowType
===
FlowModuleTypeEnum
.
historyNode
)
?.
inputs
?.
find
((
item
)
=>
item
.
key
===
'maxContext'
)?.
value
||
0
,
app
:
{
...
getSpecialModule
(
app
.
modules
),
name
:
app
.
name
,
...
...
client/src/pages/api/chat/shareChat/list.ts
View file @
67e10d6f
...
...
@@ -28,7 +28,6 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
shareId
:
item
.
shareId
,
name
:
item
.
name
,
total
:
item
.
total
,
maxContext
:
item
.
maxContext
,
lastTime
:
item
.
lastTime
}))
});
...
...
client/src/pages/api/openapi/v1/chat/completions.ts
View file @
67e10d6f
...
...
@@ -3,7 +3,7 @@ import { connectToDatabase } from '@/service/mongo';
import
{
authUser
,
authApp
,
authShareChat
}
from
'@/service/utils/auth'
;
import
{
sseErrRes
,
jsonRes
}
from
'@/service/response'
;
import
{
withNextCors
}
from
'@/service/utils/tools'
;
import
{
ChatRoleEnum
,
sseResponseEventEnum
}
from
'@/constants/chat'
;
import
{
ChatRoleEnum
,
ChatSourceEnum
,
sseResponseEventEnum
}
from
'@/constants/chat'
;
import
{
dispatchHistory
,
dispatchChatInput
,
...
...
@@ -15,12 +15,11 @@ import {
import
type
{
CreateChatCompletionRequest
}
from
'openai'
;
import
{
gptMessage2ChatType
}
from
'@/utils/adapt'
;
import
{
getChatHistory
}
from
'./getHistory'
;
import
{
saveChat
}
from
'@/
pages/api
/chat/saveChat'
;
import
{
saveChat
}
from
'@/
service/utils
/chat/saveChat'
;
import
{
sseResponse
}
from
'@/service/utils/tools'
;
import
{
type
ChatCompletionRequestMessage
}
from
'openai'
;
import
{
TaskResponseKeyEnum
}
from
'@/constants/chat'
;
import
{
FlowModuleTypeEnum
,
initModuleType
}
from
'@/constants/flow'
;
import
{
Types
}
from
'mongoose'
;
import
{
AppModuleItemType
,
RunningModuleItemType
}
from
'@/types/app'
;
import
{
pushTaskBill
}
from
'@/service/events/pushBill'
;
import
{
BillSourceEnum
}
from
'@/constants/user'
;
...
...
@@ -101,16 +100,10 @@ export default withNextCors(async function handler(req: NextApiRequest, res: Nex
}
// user question
const
prompt
=
prompts
.
pop
();
if
(
!
prompt
)
{
throw
new
Error
(
'Question is empty'
);
}
const
newChatId
=
chatId
===
''
?
new
Types
.
ObjectId
()
:
undefined
;
if
(
stream
&&
newChatId
)
{
res
.
setHeader
(
'newChatId'
,
String
(
newChatId
));
}
/* start process */
const
{
responseData
,
answerText
}
=
await
dispatchModules
({
res
,
...
...
@@ -122,29 +115,39 @@ export default withNextCors(async function handler(req: NextApiRequest, res: Nex
},
stream
});
console
.
log
(
responseData
,
'==='
,
answerText
);
//
console.log(responseData, '===', answerText);
if
(
!
answerText
)
{
throw
new
Error
(
'回复内容为空,可能模块编排出现问题'
);
}
//
if (!answerText) {
//
throw new Error('回复内容为空,可能模块编排出现问题');
//
}
// save chat
if
(
typeof
chatId
===
'string'
)
{
await
saveChat
({
chatId
,
newChatId
,
appId
,
userId
,
variables
,
prompts
:
[
isOwner
,
shareId
,
source
:
(()
=>
{
if
(
shareId
)
{
return
ChatSourceEnum
.
share
;
}
if
(
authType
===
'apikey'
)
{
return
ChatSourceEnum
.
api
;
}
return
ChatSourceEnum
.
online
;
})(),
content
:
[
prompt
,
{
_id
:
messages
[
messages
.
length
-
1
].
_id
,
obj
:
ChatRoleEnum
.
AI
,
value
:
answerText
,
...
responseData
responseData
}
],
userId
]
});
}
...
...
client/src/pages/api/openapi/v1/chat/getHistory.ts
View file @
67e10d6f
...
...
@@ -43,7 +43,7 @@ export async function getChatHistory({
}
const
history
=
await
Chat
.
aggregate
([
{
$match
:
{
_id
:
new
Types
.
ObjectId
(
chatId
)
,
userId
:
new
Types
.
ObjectId
(
userId
)
}
},
{
$match
:
{
chatId
,
userId
:
new
Types
.
ObjectId
(
userId
)
}
},
{
$project
:
{
content
:
{
...
...
@@ -54,10 +54,8 @@ export async function getChatHistory({
{
$unwind
:
'$content'
},
{
$project
:
{
_id
:
'$content._id'
,
obj
:
'$content.obj'
,
value
:
'$content.value'
,
quote
:
'$content.quote'
value
:
'$content.value'
}
}
]);
...
...
client/src/pages/api/system/getInitData.ts
View file @
67e10d6f
...
...
@@ -42,6 +42,66 @@ export async function getInitConfig() {
global
.
qaModels
=
res
.
QAModels
;
global
.
vectorModels
=
res
.
VectorModels
;
}
catch
(
error
)
{
setDefaultData
();
return
Promise
.
reject
(
'get init config error'
);
}
}
export
function
setDefaultData
()
{
global
.
systemEnv
=
{
vectorMaxProcess
:
15
,
qaMaxProcess
:
15
,
pgIvfflatProbe
:
20
,
sensitiveCheck
:
false
};
global
.
feConfigs
=
{
show_emptyChat
:
true
,
show_register
:
true
,
show_appStore
:
true
,
show_userDetail
:
true
,
show_git
:
true
,
systemTitle
:
'FastAI'
,
authorText
:
'Made by FastAI Team.'
};
global
.
chatModels
=
[
{
model
:
'gpt-3.5-turbo'
,
name
:
'FastAI-4k'
,
contextMaxToken
:
4000
,
systemMaxToken
:
2400
,
maxTemperature
:
1.2
,
price
:
1.5
},
{
model
:
'gpt-3.5-turbo-16k'
,
name
:
'FastAI-16k'
,
contextMaxToken
:
16000
,
systemMaxToken
:
8000
,
maxTemperature
:
1.2
,
price
:
3
},
{
model
:
'gpt-4'
,
name
:
'FastAI-Plus'
,
contextMaxToken
:
8000
,
systemMaxToken
:
4000
,
maxTemperature
:
1.2
,
price
:
45
}
];
global
.
qaModels
=
[
{
model
:
'gpt-3.5-turbo-16k'
,
name
:
'FastAI-16k'
,
maxToken
:
16000
,
price
:
3
}
];
global
.
vectorModels
=
[
{
model
:
'text-embedding-ada-002'
,
name
:
'Embedding-2'
,
price
:
0.2
}
];
}
client/src/pages/app/detail/components/BasicEdit/index.tsx
View file @
67e10d6f
...
...
@@ -441,7 +441,7 @@ const Settings = ({ appId }: { appId: string }) => {
};
const
ChatTest
=
({
appId
}:
{
appId
:
string
})
=>
{
const
{
appDetail
}
=
useUserStore
();
const
{
appDetail
,
userInfo
}
=
useUserStore
();
const
ChatBoxRef
=
useRef
<
ComponentRef
>
(
null
);
const
[
modules
,
setModules
]
=
useState
<
AppModuleItemType
[]
>
([]);
...
...
@@ -509,6 +509,7 @@ const ChatTest = ({ appId }: { appId: string }) => {
<
ChatBox
ref=
{
ChatBoxRef
}
appAvatar=
{
appDetail
.
avatar
}
userAvatar=
{
userInfo
?.
avatar
}
{
...
getSpecialModule
(
modules
)}
onStartChat=
{
startChat
}
onDelMessage=
{
()
=>
{}
}
...
...
client/src/pages/app/detail/components/Edit/components/ChatTest.tsx
View file @
67e10d6f
...
...
@@ -13,6 +13,7 @@ import MyIcon from '@/components/Icon';
import
{
FlowModuleTypeEnum
}
from
'@/constants/flow'
;
import
{
streamFetch
}
from
'@/api/fetch'
;
import
MyTooltip
from
'@/components/MyTooltip'
;
import
{
useUserStore
}
from
'@/store/user'
;
import
ChatBox
,
{
getSpecialModule
,
type
ComponentRef
,
...
...
@@ -36,6 +37,7 @@ const ChatTest = (
ref
:
ForwardedRef
<
ChatTestComponentRef
>
)
=>
{
const
ChatBoxRef
=
useRef
<
ComponentRef
>
(
null
);
const
{
userInfo
}
=
useUserStore
();
const
isOpen
=
useMemo
(()
=>
modules
&&
modules
.
length
>
0
,
[
modules
]);
const
startChat
=
useCallback
(
...
...
@@ -47,7 +49,7 @@ const ChatTest = (
const
history
=
messages
.
slice
(
-
historyMaxLen
-
2
,
-
2
);
// 流请求,获取数据
const
{
responseText
,
rawSearch
}
=
await
streamFetch
({
const
{
responseText
}
=
await
streamFetch
({
url
:
'/api/chat/chatTest'
,
data
:
{
history
,
...
...
@@ -61,7 +63,7 @@ const ChatTest = (
abortSignal
:
controller
});
return
{
responseText
,
rawSearch
};
return
{
responseText
};
},
[
app
.
_id
,
app
.
name
,
modules
]
);
...
...
@@ -113,6 +115,7 @@ const ChatTest = (
<
ChatBox
ref=
{
ChatBoxRef
}
appAvatar=
{
app
.
avatar
}
userAvatar=
{
userInfo
?.
avatar
}
{
...
getSpecialModule
(
modules
)}
onStartChat=
{
startChat
}
onDelMessage=
{
()
=>
{}
}
...
...
client/src/pages/chat/index.tsx
View file @
67e10d6f
...
...
@@ -15,19 +15,24 @@ import { useQuery } from '@tanstack/react-query';
import
{
streamFetch
}
from
'@/api/fetch'
;
import
{
useChatStore
}
from
'@/store/chat'
;
import
{
useLoading
}
from
'@/hooks/useLoading'
;
import
{
useToast
}
from
'@/hooks/useToast'
;
import
{
customAlphabet
}
from
'nanoid'
;
const
nanoid
=
customAlphabet
(
'abcdefghijklmnopqrstuvwxyz1234567890'
,
12
);
import
type
{
ChatHistoryItemType
}
from
'@/types/chat'
;
import
ChatBox
,
{
type
ComponentRef
,
type
StartChatFnProps
}
from
'@/components/ChatBox'
;
import
{
ChatHistoryItemType
}
from
'@/types/chat'
;
import
PageContainer
from
'@/components/PageContainer'
;
import
SideBar
from
'@/components/SideBar'
;
import
ChatHistorySlider
from
'./components/ChatHistorySlider'
;
import
SliderApps
from
'./components/SliderApps'
;
import
ChatHeader
from
'./components/ChatHeader'
;
import
{
getErrText
}
from
'@/utils/tools'
;
import
{
useUserStore
}
from
'@/store/user'
;
const
Chat
=
()
=>
{
const
Chat
=
(
{
appId
,
chatId
}:
{
appId
:
string
;
chatId
:
string
}
)
=>
{
const
router
=
useRouter
();
const
{
appId
=
''
,
chatId
=
''
}
=
router
.
query
as
{
appId
:
string
;
chatId
:
string
};
const
theme
=
useTheme
();
const
{
toast
}
=
useToast
();
const
ChatBoxRef
=
useRef
<
ComponentRef
>
(
null
);
const
forbidRefresh
=
useRef
(
false
);
...
...
@@ -44,6 +49,7 @@ const Chat = () => {
chatData
,
setChatData
}
=
useChatStore
();
const
{
myApps
,
userInfo
}
=
useUserStore
();
const
{
isPc
}
=
useGlobalStore
();
const
{
Loading
,
setIsLoading
}
=
useLoading
();
...
...
@@ -52,12 +58,14 @@ const Chat = () => {
const
startChat
=
useCallback
(
async
({
messages
,
controller
,
generatingMessage
,
variables
}:
StartChatFnProps
)
=>
{
const
prompts
=
messages
.
slice
(
-
2
);
const
{
responseText
,
newChatId
,
rawSearch
}
=
await
streamFetch
({
const
completionChatId
=
chatId
?
chatId
:
nanoid
();
const
{
responseText
}
=
await
streamFetch
({
data
:
{
messages
:
prompts
,
variables
,
appId
,
chatId
chatId
:
completionChatId
},
onMessage
:
generatingMessage
,
abortSignal
:
controller
...
...
@@ -66,10 +74,10 @@ const Chat = () => {
const
newTitle
=
prompts
[
0
].
content
?.
slice
(
0
,
20
)
||
'新对话'
;
// update history
if
(
newC
hatId
&&
!
controller
.
signal
.
aborted
)
{
if
(
completionChatId
!==
c
hatId
&&
!
controller
.
signal
.
aborted
)
{
forbidRefresh
.
current
=
true
;
const
newHistory
:
ChatHistoryItemType
=
{
_id
:
new
ChatId
,
chatId
:
completion
ChatId
,
updateTime
:
new
Date
(),
title
:
newTitle
,
appId
,
...
...
@@ -78,12 +86,12 @@ const Chat = () => {
updateHistory
(
newHistory
);
router
.
replace
({
query
:
{
chatId
:
new
ChatId
,
chatId
:
completion
ChatId
,
appId
}
});
}
else
{
const
currentChat
=
history
.
find
((
item
)
=>
item
.
_i
d
===
chatId
);
const
currentChat
=
history
.
find
((
item
)
=>
item
.
chatI
d
===
chatId
);
currentChat
&&
updateHistory
({
...
currentChat
,
...
...
@@ -98,7 +106,7 @@ const Chat = () => {
history
:
ChatBoxRef
.
current
?.
getChatHistory
()
||
state
.
history
}));
return
{
responseText
,
rawSearch
};
return
{
responseText
};
},
[
appId
,
chatId
,
history
,
router
,
setChatData
,
updateHistory
]
);
...
...
@@ -153,38 +161,43 @@ const Chat = () => {
ChatBoxRef
.
current
?.
scrollToBottom
(
'auto'
);
},
200
);
}
// empty appId request, return first app
if
(
res
.
appId
!==
appId
)
{
forbidRefresh
.
current
=
true
;
router
.
replace
({
query
:
{
appId
:
res
.
appId
}
});
}
}
catch
(
e
:
any
)
{
// reset all chat tore
setLastChatAppId
(
''
);
setLastChatId
(
''
);
toast
({
title
:
getErrText
(
e
,
'初始化聊天失败'
),
status
:
'error'
});
if
(
e
?.
code
===
501
)
{
router
.
replace
(
'/app/list'
);
}
else
{
router
.
replace
(
'/chat'
);
}
}
setIsLoading
(
false
);
return
null
;
},
[
setIsLoading
,
setChatData
,
router
,
setLastChatAppId
,
setLastChatId
]
[
setIsLoading
,
setChatData
,
router
,
setLastChatAppId
,
setLastChatId
,
toast
]
);
// 初始化聊天框
useQuery
([
'init'
,
appId
,
chatId
],
()
=>
{
// pc: redirect to latest model chat
if
(
!
appId
&&
lastChatAppId
)
{
router
.
replace
({
r
eturn
r
outer
.
replace
({
query
:
{
appId
:
lastChatAppId
,
chatId
:
lastChatId
}
});
return
null
;
}
if
(
!
appId
&&
myApps
[
0
])
{
return
router
.
replace
({
query
:
{
appId
:
myApps
[
0
].
_id
,
chatId
:
lastChatId
}
});
}
// store id
...
...
@@ -196,11 +209,15 @@ const Chat = () => {
return
null
;
}
if
(
appId
)
{
return
loadChatInfo
({
appId
,
chatId
,
loading
:
appId
!==
chatData
.
appId
});
}
return
null
;
});
useQuery
([
'loadHistory'
,
appId
],
()
=>
(
appId
?
loadHistory
({
appId
})
:
null
));
...
...
@@ -233,7 +250,7 @@ const Chat = () => {
appAvatar=
{
chatData
.
app
.
avatar
}
activeChatId=
{
chatId
}
history=
{
history
.
map
((
item
)
=>
({
id
:
item
.
_i
d
,
id
:
item
.
chatI
d
,
title
:
item
.
title
,
customTitle
:
item
.
customTitle
,
top
:
item
.
top
...
...
@@ -253,7 +270,7 @@ const Chat = () => {
onSetHistoryTop=
{
async
(
e
)
=>
{
try
{
await
putChatHistory
(
e
);
const
historyItem
=
history
.
find
((
item
)
=>
item
.
_i
d
===
e
.
chatId
);
const
historyItem
=
history
.
find
((
item
)
=>
item
.
chatI
d
===
e
.
chatId
);
if
(
!
historyItem
)
return
;
updateHistory
({
...
historyItem
,
...
...
@@ -267,7 +284,7 @@ const Chat = () => {
chatId
:
e
.
chatId
,
customTitle
:
e
.
title
});
const
historyItem
=
history
.
find
((
item
)
=>
item
.
_i
d
===
e
.
chatId
);
const
historyItem
=
history
.
find
((
item
)
=>
item
.
chatI
d
===
e
.
chatId
);
if
(
!
historyItem
)
return
;
updateHistory
({
...
historyItem
,
...
...
@@ -300,6 +317,7 @@ const Chat = () => {
showEmptyIntro
chatId=
{
chatId
}
appAvatar=
{
chatData
.
app
.
avatar
}
userAvatar=
{
userInfo
?.
avatar
}
variableModules=
{
chatData
.
app
.
variableModules
}
welcomeText=
{
chatData
.
app
.
welcomeText
}
onUpdateVariable=
{
(
e
)
=>
{}
}
...
...
@@ -315,4 +333,13 @@ const Chat = () => {
);
};
export
async
function
getServerSideProps
(
context
:
any
)
{
return
{
props
:
{
appId
:
context
?.
query
?.
appId
||
''
,
chatId
:
context
?.
query
?.
chatId
||
''
}
};
}
export
default
Chat
;
client/src/pages/chat/share.tsx
View file @
67e10d6f
import
React
,
{
useCallback
,
use
Effect
,
useRef
}
from
'react'
;
import
React
,
{
useCallback
,
use
Memo
,
useRef
}
from
'react'
;
import
{
useRouter
}
from
'next/router'
;
import
{
initShareChatInfo
}
from
'@/api/chat'
;
import
{
Box
,
Flex
,
useDisclosure
,
Drawer
,
DrawerOverlay
,
DrawerContent
}
from
'@chakra-ui/react'
;
...
...
@@ -10,14 +10,14 @@ import { useShareChatStore, defaultHistory } from '@/store/shareChat';
import
SideBar
from
'@/components/SideBar'
;
import
{
gptMessage2ChatType
}
from
'@/utils/adapt'
;
import
{
getErrText
}
from
'@/utils/tools'
;
import
dynamic
from
'next/dynamic'
;
import
{
ChatSiteItemType
}
from
'@/types/chat'
;
import
{
customAlphabet
}
from
'nanoid'
;
const
nanoid
=
customAlphabet
(
'abcdefghijklmnopqrstuvwxyz1234567890'
,
12
);
import
ChatBox
,
{
type
ComponentRef
,
type
StartChatFnProps
}
from
'@/components/ChatBox'
;
import
PageContainer
from
'@/components/PageContainer'
;
import
ChatHeader
from
'./components/ChatHeader'
;
const
ChatHistorySlider
=
dynamic
(()
=>
import
(
'./components/ChatHistorySlider'
),
{
ssr
:
false
});
import
ChatHistorySlider
from
'./components/ChatHistorySlider'
;
const
ShareChat
=
({
shareId
,
chatId
}:
{
shareId
:
string
;
chatId
:
string
})
=>
{
const
router
=
useRouter
();
...
...
@@ -36,44 +36,46 @@ const ShareChat = ({ shareId, chatId }: { shareId: string; chatId: string }) =>
delOneShareHistoryByChatId
,
delManyShareChatHistoryByShareId
}
=
useShareChatStore
();
const
history
=
useMemo
(
()
=>
shareChatHistory
.
filter
((
item
)
=>
item
.
shareId
===
shareId
),
[
shareChatHistory
,
shareId
]
);
const
startChat
=
useCallback
(
async
({
messages
,
controller
,
generatingMessage
,
variables
}:
StartChatFnProps
)
=>
{
const
prompts
=
messages
.
slice
(
-
shareChatData
.
maxContext
-
2
);
const
prompts
=
messages
.
slice
(
-
2
);
const
completionChatId
=
chatId
?
chatId
:
nanoid
();
const
{
responseText
}
=
await
streamFetch
({
data
:
{
history
,
messages
:
prompts
,
variables
,
shareId
shareId
,
chatId
:
completionChatId
},
onMessage
:
generatingMessage
,
abortSignal
:
controller
});
const
result
=
{
question
:
messages
[
messages
.
length
-
2
].
content
||
''
,
answer
:
responseText
};
prompts
[
prompts
.
length
-
1
].
content
=
responseText
;
/* save chat */
const
{
newChatId
}
=
saveChatResponse
({
chatId
,
prompts
:
gptMessage2ChatType
(
prompts
).
map
((
item
)
=>
({
const
result
:
ChatSiteItemType
[]
=
gptMessage2ChatType
(
prompts
).
map
((
item
)
=>
({
...
item
,
status
:
'finish'
})),
}));
result
[
1
].
value
=
responseText
;
/* save chat */
saveChatResponse
({
chatId
:
completionChatId
,
prompts
:
result
,
variables
,
shareId
});
if
(
newC
hatId
&&
!
controller
.
signal
.
aborted
)
{
if
(
completionChatId
!==
c
hatId
&&
!
controller
.
signal
.
aborted
)
{
router
.
replace
({
query
:
{
shareId
,
chatId
:
new
ChatId
chatId
:
completion
ChatId
}
});
}
...
...
@@ -81,14 +83,17 @@ const ShareChat = ({ shareId, chatId }: { shareId: string; chatId: string }) =>
window
.
top
?.
postMessage
(
{
type
:
'shareChatFinish'
,
data
:
result
data
:
{
question
:
result
[
0
]?.
value
,
answer
:
result
[
1
]?.
value
}
},
'*'
);
return
{
responseText
};
},
[
chatId
,
router
,
saveChatResponse
,
share
ChatData
.
maxContext
,
share
Id
]
[
chatId
,
router
,
saveChatResponse
,
shareId
]
);
const
loadAppInfo
=
useCallback
(
...
...
@@ -96,7 +101,7 @@ const ShareChat = ({ shareId, chatId }: { shareId: string; chatId: string }) =>
console
.
log
(
shareId
,
chatId
);
if
(
!
shareId
)
return
null
;
const
history
=
shareChatHistory
.
find
((
item
)
=>
item
.
_i
d
===
chatId
)
||
defaultHistory
;
const
history
=
shareChatHistory
.
find
((
item
)
=>
item
.
chatI
d
===
chatId
)
||
defaultHistory
;
ChatBoxRef
.
current
?.
resetHistory
(
history
.
chats
);
ChatBoxRef
.
current
?.
resetVariables
(
history
.
variables
);
...
...
@@ -157,11 +162,13 @@ const ShareChat = ({ shareId, chatId }: { shareId: string; chatId: string }) =>
appName=
{
shareChatData
.
app
.
name
}
appAvatar=
{
shareChatData
.
app
.
avatar
}
activeChatId=
{
chatId
}
history=
{
shareChatH
istory
.
map
((
item
)
=>
({
id
:
item
.
_i
d
,
history=
{
h
istory
.
map
((
item
)
=>
({
id
:
item
.
chatI
d
,
title
:
item
.
title
}))
}
onChangeChat=
{
(
chatId
)
=>
{
console
.
log
(
chatId
);
router
.
push
({
query
:
{
chatId
:
chatId
||
''
,
...
...
@@ -196,6 +203,7 @@ const ShareChat = ({ shareId, chatId }: { shareId: string; chatId: string }) =>
<
ChatBox
ref=
{
ChatBoxRef
}
appAvatar=
{
shareChatData
.
app
.
avatar
}
userAvatar=
{
shareChatData
.
userAvatar
}
variableModules=
{
shareChatData
.
app
.
variableModules
}
welcomeText=
{
shareChatData
.
app
.
welcomeText
}
onUpdateVariable=
{
(
e
)
=>
{
...
...
client/src/pages/number/index.tsx
View file @
67e10d6f
...
...
@@ -4,13 +4,12 @@ import { useGlobalStore } from '@/store/global';
import
{
useRouter
}
from
'next/router'
;
import
dynamic
from
'next/dynamic'
;
import
{
clearCookie
}
from
'@/utils/user'
;
import
{
useUserStore
}
from
'@/store/user'
;
import
{
useConfirm
}
from
'@/hooks/useConfirm'
;
import
PageContainer
from
'@/components/PageContainer'
;
import
SideTabs
from
'@/components/SideTabs'
;
import
Tabs
from
'@/components/Tabs'
;
import
UserInfo
from
'./components/Info'
;
import
{
useUserStore
}
from
'@/store/user'
;
const
BillTable
=
dynamic
(()
=>
import
(
'./components/BillTable'
),
{
ssr
:
false
...
...
@@ -39,6 +38,10 @@ const NumberSetting = ({ currentTab }: { currentTab: `${TabEnum}` }) => {
{
icon
:
'loginoutLight'
,
label
:
'登出'
,
id
:
TabEnum
.
loginout
,
Component
:
()
=>
<></>
}
]);
const
{
openConfirm
,
ConfirmChild
}
=
useConfirm
({
content
:
'确认退出登录?'
});
const
router
=
useRouter
();
const
theme
=
useTheme
();
const
{
isPc
}
=
useGlobalStore
();
...
...
@@ -47,9 +50,11 @@ const NumberSetting = ({ currentTab }: { currentTab: `${TabEnum}` }) => {
const
setCurrentTab
=
useCallback
(
(
tab
:
string
)
=>
{
if
(
tab
===
TabEnum
.
loginout
)
{
openConfirm
(()
=>
{
clearCookie
();
setUserInfo
(
null
);
router
.
replace
(
'/login'
);
})();
}
else
{
router
.
replace
({
query
:
{
...
...
@@ -58,7 +63,7 @@ const NumberSetting = ({ currentTab }: { currentTab: `${TabEnum}` }) => {
});
}
},
[
router
,
setUserInfo
]
[
openConfirm
,
router
,
setUserInfo
]
);
return
(
...
...
@@ -105,6 +110,7 @@ const NumberSetting = ({ currentTab }: { currentTab: `${TabEnum}` }) => {
{
currentTab
===
TabEnum
.
inform
&&
<
InformTable
/>
}
</
Box
>
</
Flex
>
<
ConfirmChild
/>
</
PageContainer
>
);
};
...
...
client/src/service/models/chat.ts
View file @
67e10d6f
import
{
Schema
,
model
,
models
,
Model
}
from
'mongoose'
;
import
{
ChatSchema
as
ChatType
}
from
'@/types/mongoSchema'
;
import
{
ChatRoleMap
}
from
'@/constants/chat'
;
import
{
ChatRoleMap
,
TaskResponseKeyEnum
}
from
'@/constants/chat'
;
import
{
ChatSourceEnum
,
ChatSourceMap
}
from
'@/constants/chat'
;
const
ChatSchema
=
new
Schema
({
chatId
:
{
type
:
String
,
require
:
true
},
userId
:
{
type
:
Schema
.
Types
.
ObjectId
,
ref
:
'user'
,
...
...
@@ -33,14 +37,14 @@ const ChatSchema = new Schema({
type
:
Object
,
default
:
{}
},
//
source: {
//
type: String,
//
enum: Object.keys(ChatSourceMap),
//
required: true
//
},
//
shareId: {
//
type: String
//
},
source
:
{
type
:
String
,
enum
:
Object
.
keys
(
ChatSourceMap
),
required
:
true
},
shareId
:
{
type
:
String
},
content
:
{
type
:
[
{
...
...
@@ -53,14 +57,22 @@ const ChatSchema = new Schema({
type
:
String
,
default
:
''
},
rawSearch
:
{
[
TaskResponseKeyEnum
.
responseData
]
:
{
type
:
[
{
id
:
String
,
q
:
String
,
a
:
String
,
kb_id
:
String
,
source
:
String
moduleName
:
String
,
price
:
String
,
model
:
String
,
tokens
:
Number
,
question
:
String
,
answer
:
String
,
temperature
:
Number
,
maxToken
:
Number
,
finishMessages
:
Array
,
similarity
:
Number
,
limit
:
Number
,
cqList
:
Array
,
cqResult
:
String
}
],
default
:
[]
...
...
client/src/service/models/shareChat.ts
View file @
67e10d6f
...
...
@@ -24,10 +24,6 @@ const ShareChatSchema = new Schema({
type
:
Number
,
default
:
0
},
maxContext
:
{
type
:
Number
,
default
:
20
},
lastTime
:
{
type
:
Date
}
...
...
client/src/service/moduleDispatch/chat/oneapi.ts
View file @
67e10d6f
...
...
@@ -113,7 +113,7 @@ ${quoteQA.map((item, i) => `${i + 1}. [${item.q}\n${item.a}]`).join('\n')}
const
adaptMessages
=
adaptChatItem_openAI
({
messages
:
filterMessages
,
reserveId
:
false
});
const
chatAPI
=
getOpenAIApi
();
//
console.log(adaptMessages);
console
.
log
(
adaptMessages
);
/* count response max token */
const
promptsToken
=
modelToolMap
.
countTokens
({
...
...
@@ -128,8 +128,8 @@ ${quoteQA.map((item, i) => `${i + 1}. [${item.q}\n${item.a}]`).join('\n')}
temperature
:
Number
(
temperature
||
0
),
max_tokens
:
maxToken
,
messages
:
adaptMessages
,
frequency_penalty
:
0.5
,
// 越大,重复内容越少
presence_penalty
:
-
0.5
,
// 越大,越容易出现新内容
//
frequency_penalty: 0.5, // 越大,重复内容越少
//
presence_penalty: -0.5, // 越大,越容易出现新内容
stream
},
{
...
...
client/src/service/utils/chat/saveChat.ts
0 → 100644
View file @
67e10d6f
import
{
ChatItemType
}
from
'@/types/chat'
;
import
{
Chat
,
App
}
from
'@/service/mongo'
;
import
{
ChatSourceEnum
}
from
'@/constants/chat'
;
type
Props
=
{
chatId
:
string
;
appId
:
string
;
userId
:
string
;
variables
?:
Record
<
string
,
any
>
;
isOwner
:
boolean
;
source
:
`
${
ChatSourceEnum
}
`
;
shareId
?:
string
;
content
:
[
ChatItemType
,
ChatItemType
];
};
export
async
function
saveChat
({
chatId
,
appId
,
userId
,
variables
,
isOwner
,
source
,
shareId
,
content
}:
Props
)
{
const
chatHistory
=
await
Chat
.
findOne
(
{
chatId
,
userId
},
'_id'
);
if
(
chatHistory
)
{
await
Chat
.
findOneAndUpdate
(
{
chatId
},
{
$push
:
{
content
:
{
$each
:
content
}
},
title
:
content
[
0
].
value
.
slice
(
0
,
20
),
updateTime
:
new
Date
()
}
);
}
else
{
await
Chat
.
create
({
chatId
,
userId
,
appId
,
variables
,
title
:
content
[
0
].
value
.
slice
(
0
,
20
),
source
,
shareId
,
content
:
content
});
}
if
(
isOwner
&&
source
===
ChatSourceEnum
.
online
)
{
App
.
findByIdAndUpdate
(
appId
,
{
updateTime
:
new
Date
()
});
}
}
client/src/store/chat.ts
View file @
67e10d6f
...
...
@@ -65,12 +65,12 @@ export const useChatStore = create<State>()(
},
async
delHistory
(
chatId
)
{
set
((
state
)
=>
{
state
.
history
=
state
.
history
.
filter
((
item
)
=>
item
.
_i
d
!==
chatId
);
state
.
history
=
state
.
history
.
filter
((
item
)
=>
item
.
chatI
d
!==
chatId
);
});
await
delChatHistoryById
(
chatId
);
},
updateHistory
(
history
)
{
const
index
=
get
().
history
.
findIndex
((
item
)
=>
item
.
_id
===
history
.
_i
d
);
const
index
=
get
().
history
.
findIndex
((
item
)
=>
item
.
chatId
===
history
.
chatI
d
);
set
((
state
)
=>
{
const
newHistory
=
(()
=>
{
if
(
index
>
-
1
)
{
...
...
client/src/store/shareChat.ts
View file @
67e10d6f
...
...
@@ -4,8 +4,6 @@ import { immer } from 'zustand/middleware/immer';
import
type
{
ChatSiteItemType
,
ShareChatHistoryItemType
,
ShareChatType
}
from
'@/types/chat'
;
import
{
HUMAN_ICON
}
from
'@/constants/chat'
;
import
{
customAlphabet
}
from
'nanoid'
;
const
nanoid
=
customAlphabet
(
'abcdefghijklmnopqrstuvwxyz1234567890'
,
12
);
type
State
=
{
shareChatData
:
ShareChatType
;
...
...
@@ -16,21 +14,20 @@ type State = {
prompts
:
ChatSiteItemType
[];
variables
:
Record
<
string
,
any
>
;
shareId
:
string
;
})
=>
{
newChatId
:
string
}
;
})
=>
void
;
delOneShareHistoryByChatId
:
(
chatId
:
string
)
=>
void
;
delShareChatHistoryItemById
:
(
e
:
{
chatId
:
string
;
index
:
number
})
=>
void
;
delManyShareChatHistoryByShareId
:
(
shareId
?:
string
)
=>
void
;
};
export
const
defaultHistory
:
ShareChatHistoryItemType
=
{
_i
d
:
`
${
Date
.
now
()}
`
,
chatI
d
:
`
${
Date
.
now
()}
`
,
updateTime
:
new
Date
(),
title
:
'新对话'
,
shareId
:
''
,
chats
:
[]
};
const
defaultShareChatData
:
ShareChatType
=
{
maxContext
:
5
,
userAvatar
:
HUMAN_ICON
,
app
:
{
name
:
''
,
...
...
@@ -57,32 +54,30 @@ export const useShareChatStore = create<State>()(
state
.
shareChatData
=
val
;
// update history
state
.
shareChatHistory
=
state
.
shareChatHistory
.
map
((
item
)
=>
item
.
_id
===
val
.
history
.
_i
d
?
val
.
history
:
item
item
.
chatId
===
val
.
history
.
chatI
d
?
val
.
history
:
item
);
});
},
shareChatHistory
:
[],
saveChatResponse
({
chatId
,
prompts
,
variables
,
shareId
})
{
const
history
=
get
().
shareChatHistory
.
find
((
item
)
=>
item
.
_id
===
chatId
);
const
newChatId
=
history
?
''
:
nanoid
();
const
chatHistory
=
get
().
shareChatHistory
.
find
((
item
)
=>
item
.
chatId
===
chatId
);
const
historyList
=
(()
=>
{
if
(
h
istory
)
{
if
(
chatH
istory
)
{
return
get
().
shareChatHistory
.
map
((
item
)
=>
item
.
_i
d
===
chatId
item
.
chatI
d
===
chatId
?
{
...
item
,
title
:
prompts
[
prompts
.
length
-
2
]?.
value
,
updateTime
:
new
Date
(),
chats
:
prompts
,
chats
:
chatHistory
.
chats
.
concat
(
prompts
).
slice
(
-
50
)
,
variables
}
:
item
);
}
return
get
().
shareChatHistory
.
concat
({
_id
:
newC
hatId
,
c
hatId
,
shareId
,
title
:
prompts
[
prompts
.
length
-
2
]?.
value
,
updateTime
:
new
Date
(),
...
...
@@ -97,21 +92,19 @@ export const useShareChatStore = create<State>()(
set
((
state
)
=>
{
state
.
shareChatHistory
=
historyList
.
slice
(
0
,
100
);
});
return
{
newChatId
};
},
delOneShareHistoryByChatId
(
chatId
:
string
)
{
set
((
state
)
=>
{
state
.
shareChatHistory
=
state
.
shareChatHistory
.
filter
((
item
)
=>
item
.
_id
!==
chatId
);
state
.
shareChatHistory
=
state
.
shareChatHistory
.
filter
(
(
item
)
=>
item
.
chatId
!==
chatId
);
});
},
delShareChatHistoryItemById
({
chatId
,
index
})
{
set
((
state
)
=>
{
// update history store
const
newHistoryList
=
state
.
shareChatHistory
.
map
((
item
)
=>
item
.
_i
d
===
chatId
item
.
chatI
d
===
chatId
?
{
...
item
,
chats
:
[...
item
.
chats
.
slice
(
0
,
index
),
...
item
.
chats
.
slice
(
index
+
1
)]
...
...
client/src/types/app.d.ts
View file @
67e10d6f
...
...
@@ -37,7 +37,6 @@ export interface ShareAppItem {
export
type
ShareChatEditType
=
{
name
:
string
;
maxContext
:
number
;
};
/* agent */
...
...
client/src/types/chat.d.ts
View file @
67e10d6f
import
{
ChatRoleEnum
,
rawSearchKey
}
from
'@/constants/chat'
;
import
{
ChatRoleEnum
}
from
'@/constants/chat'
;
import
type
{
InitChatResponse
,
InitShareChatResponse
}
from
'@/api/response/chat'
;
import
{
TaskResponseKeyEnum
}
from
'@/constants/chat'
;
import
{
ClassifyQuestionAgentItemType
}
from
'./app'
;
...
...
@@ -9,9 +9,7 @@ export type ChatItemType = {
_id
?:
string
;
obj
:
`
${
ChatRoleEnum
}
`
;
value
:
string
;
[
rawSearchKey
]?:
QuoteItemType
[];
quoteLen
?:
number
;
[
key
:
string
]:
any
;
[
TaskResponseKeyEnum
.
responseData
]?:
ChatHistoryItemResType
[];
};
export
type
ChatSiteItemType
=
{
...
...
@@ -19,7 +17,7 @@ export type ChatSiteItemType = {
}
&
ChatItemType
;
export
type
HistoryItemType
=
{
_i
d
:
string
;
chatI
d
:
string
;
updateTime
:
Date
;
customTitle
?:
string
;
title
:
string
;
...
...
client/src/types/index.d.ts
View file @
67e10d6f
...
...
@@ -18,7 +18,7 @@ export type FeConfigsType = {
show_register
?:
boolean
;
show_appStore
?:
boolean
;
show_userDetail
?:
boolean
;
show_git
?:
false
;
show_git
?:
boolean
;
systemTitle
?:
string
;
authorText
?:
string
;
};
...
...
client/src/types/mongoSchema.d.ts
View file @
67e10d6f
...
...
@@ -4,6 +4,7 @@ import type { DataType } from './data';
import
{
BillSourceEnum
,
InformTypeEnum
}
from
'@/constants/user'
;
import
{
TrainingModeEnum
}
from
'@/constants/plugin'
;
import
type
{
AppModuleItemType
}
from
'./app'
;
import
{
ChatSourceEnum
}
from
'@/constants/chat'
;
export
interface
UserModelSchema
{
_id
:
string
;
...
...
@@ -78,6 +79,7 @@ export interface TrainingDataSchema {
export
interface
ChatSchema
{
_id
:
string
;
chatId
:
string
;
userId
:
string
;
appId
:
string
;
updateTime
:
Date
;
...
...
@@ -85,6 +87,8 @@ export interface ChatSchema {
customTitle
:
string
;
top
:
boolean
;
variables
:
Record
<
string
,
any
>
;
source
:
`
${
ChatSourceEnum
}
`
;
shareId
?:
string
;
content
:
ChatItemType
[];
}
...
...
@@ -138,7 +142,6 @@ export interface ShareChatSchema {
appId
:
string
;
name
:
string
;
total
:
number
;
maxContext
:
number
;
lastTime
:
Date
;
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment