Skip to content

Commit

Permalink
Fix too many requests (#41)
Browse files Browse the repository at this point in the history
  • Loading branch information
swuecho authored Mar 27, 2023
1 parent fca5a5d commit 7e8226d
Show file tree
Hide file tree
Showing 9 changed files with 84 additions and 57 deletions.
2 changes: 1 addition & 1 deletion api/middleware_rateLimit.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ func RateLimitByUserID(q *sqlc_queries.Queries) func(http.Handler) http.Handler
}

if messageCount >= int64(maxRate) {
http.Error(w, "Too Many Requests", http.StatusTooManyRequests)
http.Error(w, "error.rateLimit", http.StatusTooManyRequests)
return
}
}
Expand Down
2 changes: 1 addition & 1 deletion e2e/tests/03_chat_session.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ test('test', async ({ page }) => {
await page.getByRole('complementary').getByRole('button').nth(1).click();
await page.getByPlaceholder('请输入').dblclick();
await page.getByPlaceholder('请输入').fill('This is a test topic');
await page.getByRole('main').filter({ hasText: 'New chat' }).locator('a').getByRole('button').click();
await page.getByRole('main').filter({ hasText: '新聊天' }).locator('a').getByRole('button').click();

// sleep 500ms
await page.waitForTimeout(500);
Expand Down
4 changes: 2 additions & 2 deletions e2e/tests/05_chat_session.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,13 @@ test('test', async ({ page }) => {
const session_1 = sessions_1[0];
expect(session_1.topic).toBe('test_session_topic');

await page.getByRole('button', { name: 'New chat' }).click();
await page.getByRole('button', { name: '新聊天' }).click();
await page.getByTestId('edit_session_topic').click();
await page.getByTestId('edit_session_topic_input').locator('input').click();
await page.getByTestId('edit_session_topic_input').locator('input').fill('test_session_topic_2');
await page.getByTestId('save_session_topic').click();

await page.getByRole('button', { name: 'New chat' }).click();
await page.getByRole('button', { name: '新聊天' }).click();
await page.getByTestId('edit_session_topic').click();
await page.getByTestId('edit_session_topic_input').locator('input').fill('test_session_topic_3');
await page.getByTestId('save_session_topic').click();
Expand Down
4 changes: 4 additions & 0 deletions web/src/locales/en-US.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
"unauthorizedTips": "Please sign up or login"
},
"chat": {
"new": "New Chat",
"placeholder": "What would you like to say... (Shift + Enter = newline)",
"placeholderMobile": "What would you like to say...",
"copy": "Copy",
Expand Down Expand Up @@ -79,5 +80,8 @@
"showSubMenu": "Show Submenu",
"userStat": "User Statistics",
"rateLimit10Min": "Message Limit (10 minutes)"
},
"error": {
"rateLimit": "The message sending limit has been reached, please contact the administrator."
}
}
4 changes: 4 additions & 0 deletions web/src/locales/zh-CN.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
"unauthorizedTips": "请注册或者登录"
},
"chat": {
"new": "新聊天",
"placeholder": "来说点什么吧...(Shift + Enter = 换行)",
"placeholderMobile": "来说点什么...",
"copy": "复制",
Expand Down Expand Up @@ -79,5 +80,8 @@
"reverseProxy": "反向代理",
"timeout": "超时",
"socks": "Socks"
},
"error": {
"rateLimit": "发送消息数量已经达到上限, 请联系管理员"
}
}
3 changes: 3 additions & 0 deletions web/src/locales/zh-TW.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,10 @@
"password_placeholder": "請輸入密碼",
"unauthorizedTips": "請註冊或登錄"
},
"error": {"rateLimit": "發送消息數量已經達到上限,請聯繫管理員"
},
"chat": {
"new": "新建聊天",
"placeholder": "說些什麼...(Shift + Enter = 換行)",
"placeholderMobile": "說些什麼...",
"copy": "複製",
Expand Down
5 changes: 3 additions & 2 deletions web/src/store/modules/chat/helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ const LOCAL_NAME = 'chatStorage'

export function defaultState(): Chat.ChatState {
const uuid = uuidv4()
createChatSession(uuid, 'New Chat')
return { active: uuid, history: [{ uuid, title: 'New Chat', isEdit: false }], chat: [{ uuid, data: [] }] }
const new_chat_text = 'New Chat'
createChatSession(uuid, new_chat_text)
return { active: uuid, history: [{ uuid, title: new_chat_text, isEdit: false }], chat: [{ uuid, data: [] }] }
}

export function getLocalState(): Chat.ChatState {
Expand Down
115 changes: 65 additions & 50 deletions web/src/views/chat/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -109,37 +109,60 @@ async function onConversationStream() {
const xhr = progress.event.target
const {
responseText,
status,
} = xhr
if (status === 500) {
updateChatPartial(
sessionUuid,
dataSources.value.length - 1,
{
loading: false,
error: true,
text: responseText,
},
)
}
else if (status === 429) {
updateChatPartial(
sessionUuid,
dataSources.value.length - 1,
{
loading: false,
error: true,
text: t(responseText),
},
)
}
else {
const lastIndex = responseText.lastIndexOf('data: ')
// Extract the JSON data chunk from the responseText
const chunk = responseText.slice(lastIndex + 6)
const lastIndex = responseText.lastIndexOf('data: ')
// Extract the JSON data chunk from the responseText
const chunk = responseText.slice(lastIndex + 6)
// Check if the chunk is not empty
if (chunk) {
// Parse the JSON data chunk
try {
const data = JSON.parse(chunk)
const answer = data.choices[0].delta.content
const answer_uuid = data.id.replace('chatcmpl-', '') // use answer id as uuid
updateChat(
sessionUuid,
dataSources.value.length - 1,
{
uuid: answer_uuid,
dateTime: new Date().toLocaleString(),
text: answer,
inversion: false,
error: false,
loading: false,
conversationOptions: { conversationId: data.conversationId, parentMessageId: data.id },
requestOptions: { prompt: message, options: { ...options } },
},
)
}
catch (error) {
console.log(error)
// Check if the chunk is not empty
if (chunk) {
// Parse the JSON data chunk
try {
const data = JSON.parse(chunk)
const answer = data.choices[0].delta.content
const answer_uuid = data.id.replace('chatcmpl-', '') // use answer id as uuid
updateChat(
sessionUuid,
dataSources.value.length - 1,
{
uuid: answer_uuid,
dateTime: new Date().toLocaleString(),
text: answer,
inversion: false,
error: false,
loading: false,
conversationOptions: { conversationId: data.conversationId, parentMessageId: data.id },
requestOptions: { prompt: message, options: { ...options } },
},
)
}
catch (error) {
console.log(error)
}
}
}
},
Expand All @@ -150,6 +173,8 @@ async function onConversationStream() {
const response = error.response
if (response.status === 500)
nui_msg.error(response.data.message)
else if (response.status === 429)
nui_msg.error(response.data.message)
throw error
}
finally {
Expand Down Expand Up @@ -228,7 +253,7 @@ async function onRegenerate(index: number) {
text: answer,
inversion: false,
error: false,
loading: true,
loading: false,
conversationOptions: { conversationId: data.conversationId, parentMessageId: data.id },
requestOptions: { prompt: message, options: { ...options } },
},
Expand Down Expand Up @@ -421,19 +446,15 @@ onUnmounted(() => {

<template>
<div class="flex flex-col w-full h-full">
<HeaderComponent
v-if="isMobile" :using-context="usingContext" @export="handleExport"
@toggle-using-context="showModal = true"
/>
<HeaderComponent v-if="isMobile" :using-context="usingContext" @export="handleExport"
@toggle-using-context="showModal = true" />
<main class="flex-1 overflow-hidden">
<NModal ref="sessionConfigModal" v-model:show="showModal">
<SessionConfig ref="sessionConfig" :uuid="sessionUuid" />
</NModal>
<div id="scrollRef" ref="scrollRef" class="h-full overflow-hidden overflow-y-auto">
<div
id="image-wrapper" class="w-full max-w-screen-xl m-auto dark:bg-[#101014]"
:class="[isMobile ? 'p-2' : 'p-4']"
>
<div id="image-wrapper" class="w-full max-w-screen-xl m-auto dark:bg-[#101014]"
:class="[isMobile ? 'p-2' : 'p-4']">
<template v-if="!dataSources.length">
<div class="flex items-center justify-center mt-4 text-center text-neutral-300">
<SvgIcon icon="ri:bubble-chart-fill" class="mr-2 text-3xl" />
Expand All @@ -442,11 +463,9 @@ onUnmounted(() => {
</template>
<template v-else>
<div>
<Message
v-for="(item, index) of dataSources" :key="index" :date-time="item.dateTime" :text="item.text"
<Message v-for="(item, index) of dataSources" :key="index" :date-time="item.dateTime" :text="item.text"
:inversion="item.inversion" :error="item.error" :loading="item.loading" :index="index"
@regenerate="onRegenerate(index)" @delete="handleDelete(index)" @after-edit="handleAfterEdit"
/>
@regenerate="onRegenerate(index)" @delete="handleDelete(index)" @after-edit="handleAfterEdit" />
<div class="sticky bottom-0 left-0 flex justify-center">
<NButton v-if="loading" type="warning" @click="handleStop">
<template #icon>
Expand Down Expand Up @@ -479,14 +498,10 @@ onUnmounted(() => {
</span>
</HoverButton>

<NInput
id="message_textarea" v-model:value="prompt" data-testid="message_textarea" type="textarea"
:autosize="{ minRows: 1, maxRows: isMobile ? 4 : 8 }" :placeholder="placeholder" @keypress="handleEnter"
/>
<NButton
id="send_message_button" data-testid="send_message_button" type="primary" :disabled="buttonDisabled"
@click="handleSubmit"
>
<NInput id="message_textarea" v-model:value="prompt" data-testid="message_textarea" type="textarea"
:autosize="{ minRows: 1, maxRows: isMobile ? 4 : 8 }" :placeholder="placeholder" @keypress="handleEnter" />
<NButton id="send_message_button" data-testid="send_message_button" type="primary" :disabled="buttonDisabled"
@click="handleSubmit">
<template #icon>
<span class="dark:text-black">
<SvgIcon icon="ri:send-plane-fill" />
Expand Down
2 changes: 1 addition & 1 deletion web/src/views/chat/layout/sider/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ watch(
<main class="flex flex-col flex-1 min-h-0">
<div class="p-4">
<NButton dashed block @click="handleAdd">
New chat
{{ $t('chat.new') }}
</NButton>
</div>
<div class="flex-1 min-h-0 pb-4 overflow-hidden">
Expand Down

0 comments on commit 7e8226d

Please sign in to comment.