feat: Add reasoning UI

This commit is contained in:
n4ze3m
2025-01-24 22:29:18 +05:30
parent b39d60fc3c
commit 97daaf9dc2
31 changed files with 461 additions and 72 deletions

View File

@@ -130,7 +130,8 @@ export const saveMessageOnSuccess = async ({
message_source = "web-ui",
message_type, generationInfo,
prompt_id,
prompt_content
prompt_content,
reasoning_time_taken = 0
}: {
historyId: string | null
setHistoryId: (historyId: string) => void
@@ -145,6 +146,7 @@ export const saveMessageOnSuccess = async ({
generationInfo?: any
prompt_id?: string
prompt_content?: string
reasoning_time_taken?: number
}) => {
if (historyId) {
if (!isRegenerate) {
@@ -157,7 +159,8 @@ export const saveMessageOnSuccess = async ({
[],
1,
message_type,
generationInfo
generationInfo,
reasoning_time_taken
)
}
await saveMessage(
@@ -169,7 +172,8 @@ export const saveMessageOnSuccess = async ({
source,
2,
message_type,
generationInfo
generationInfo,
reasoning_time_taken
)
await setLastUsedChatModel(historyId, selectedModel!)
if (prompt_id || prompt_content) {
@@ -187,7 +191,8 @@ export const saveMessageOnSuccess = async ({
[],
1,
message_type,
generationInfo
generationInfo,
reasoning_time_taken
)
await saveMessage(
newHistoryId.id,
@@ -198,7 +203,8 @@ export const saveMessageOnSuccess = async ({
source,
2,
message_type,
generationInfo
generationInfo,
reasoning_time_taken
)
setHistoryId(newHistoryId.id)
await setLastUsedChatModel(newHistoryId.id, selectedModel!)

View File

@@ -36,6 +36,7 @@ import { humanMessageFormatter } from "@/utils/human-message"
import { pageAssistEmbeddingModel } from "@/models/embedding"
import { PAMemoryVectorStore } from "@/libs/PAMemoryVectorStore"
import { getScreenshotFromCurrentTab } from "@/libs/get-screenshot"
import { isReasoningEnded, isReasoningStarted, removeReasoning } from "@/libs/reasoning"
export const useMessage = () => {
const {
@@ -55,14 +56,9 @@ export const useMessage = () => {
setWebSearch,
isSearchingInternet
} = useStoreMessageOption()
const [defaultInternetSearchOn, ] = useStorage(
"defaultInternetSearchOn",
false
)
const [defaultInternetSearchOn] = useStorage("defaultInternetSearchOn", false)
const [
defaultChatWithWebsite,
] = useStorage("defaultChatWithWebsite", false)
const [defaultChatWithWebsite] = useStorage("defaultChatWithWebsite", false)
const [chatWithWebsiteEmbedding] = useStorage(
"chatWithWebsiteEmbedding",
@@ -115,10 +111,10 @@ export const useMessage = () => {
setIsProcessing(false)
setStreaming(false)
currentChatModelSettings.reset()
if(defaultInternetSearchOn) {
if (defaultInternetSearchOn) {
setWebSearch(true)
}
if(defaultChatWithWebsite) {
if (defaultChatWithWebsite) {
setChatMode("rag")
}
}
@@ -329,6 +325,7 @@ export const useMessage = () => {
})
const response = await questionOllama.invoke(promptForQuestion)
query = response.content.toString()
query = removeReasoning(query)
}
let context: string = ""
@@ -413,18 +410,36 @@ export const useMessage = () => {
}
)
let count = 0
let reasoningStartTime: Date | null = null
let reasoningEndTime: Date | null = null
let timetaken = 0
for await (const chunk of chunks) {
contentToSave += chunk?.content
fullText += chunk?.content
if (count === 0) {
setIsProcessing(true)
}
if (isReasoningStarted(fullText) && !reasoningStartTime) {
reasoningStartTime = new Date()
}
if (
reasoningStartTime &&
!reasoningEndTime &&
isReasoningEnded(fullText)
) {
reasoningEndTime = new Date()
const reasoningTime =
reasoningEndTime.getTime() - reasoningStartTime.getTime()
timetaken = reasoningTime
}
setMessages((prev) => {
return prev.map((message) => {
if (message.id === generateMessageId) {
return {
...message,
message: fullText + "▋"
message: fullText + "▋",
reasoning_time_taken: timetaken
}
}
return message
@@ -440,7 +455,8 @@ export const useMessage = () => {
...message,
message: fullText,
sources: source,
generationInfo
generationInfo,
reasoning_time_taken: timetaken
}
}
return message
@@ -470,7 +486,8 @@ export const useMessage = () => {
fullText,
source,
message_source: "copilot",
generationInfo
generationInfo,
reasoning_time_taken: timetaken
})
setIsProcessing(false)
@@ -664,18 +681,36 @@ export const useMessage = () => {
}
)
let count = 0
let reasoningStartTime: Date | undefined = undefined
let reasoningEndTime: Date | undefined = undefined
let timetaken = 0
for await (const chunk of chunks) {
contentToSave += chunk?.content
fullText += chunk?.content
if (count === 0) {
setIsProcessing(true)
}
if (isReasoningStarted(fullText) && !reasoningStartTime) {
reasoningStartTime = new Date()
}
if (
reasoningStartTime &&
!reasoningEndTime &&
isReasoningEnded(fullText)
) {
reasoningEndTime = new Date()
const reasoningTime =
reasoningEndTime.getTime() - reasoningStartTime.getTime()
timetaken = reasoningTime
}
setMessages((prev) => {
return prev.map((message) => {
if (message.id === generateMessageId) {
return {
...message,
message: fullText + "▋"
message: fullText + "▋",
reasoning_time_taken: timetaken
}
}
return message
@@ -689,7 +724,8 @@ export const useMessage = () => {
return {
...message,
message: fullText,
generationInfo
generationInfo,
reasoning_time_taken: timetaken
}
}
return message
@@ -718,7 +754,8 @@ export const useMessage = () => {
fullText,
source: [],
message_source: "copilot",
generationInfo
generationInfo,
reasoning_time_taken: timetaken
})
setIsProcessing(false)
@@ -914,18 +951,37 @@ export const useMessage = () => {
}
)
let count = 0
let reasoningStartTime: Date | null = null
let reasoningEndTime: Date | null = null
let timetaken = 0
for await (const chunk of chunks) {
contentToSave += chunk?.content
fullText += chunk?.content
if (count === 0) {
setIsProcessing(true)
}
if (isReasoningStarted(fullText) && !reasoningStartTime) {
reasoningStartTime = new Date()
}
if (
reasoningStartTime &&
!reasoningEndTime &&
isReasoningEnded(fullText)
) {
reasoningEndTime = new Date()
const reasoningTime =
reasoningEndTime.getTime() - reasoningStartTime.getTime()
timetaken = reasoningTime
}
setMessages((prev) => {
return prev.map((message) => {
if (message.id === generateMessageId) {
return {
...message,
message: fullText + "▋"
message: fullText + "▋",
reasoning_time_taken: timetaken
}
}
return message
@@ -940,7 +996,8 @@ export const useMessage = () => {
return {
...message,
message: fullText,
generationInfo
generationInfo,
reasoning_time_taken: timetaken
}
}
return message
@@ -970,7 +1027,8 @@ export const useMessage = () => {
fullText,
source: [],
message_source: "copilot",
generationInfo
generationInfo,
reasoning_time_taken: timetaken
})
setIsProcessing(false)
@@ -1158,6 +1216,7 @@ export const useMessage = () => {
})
const response = await questionOllama.invoke(promptForQuestion)
query = response.content.toString()
query = removeReasoning(query)
}
const { prompt, source } = await getSystemPromptForWeb(query)
@@ -1221,18 +1280,37 @@ export const useMessage = () => {
}
)
let count = 0
let timetaken = 0
let reasoningStartTime: Date | undefined = undefined
let reasoningEndTime: Date | undefined = undefined
for await (const chunk of chunks) {
contentToSave += chunk?.content
fullText += chunk?.content
if (count === 0) {
setIsProcessing(true)
}
if (isReasoningStarted(fullText) && !reasoningStartTime) {
reasoningStartTime = new Date()
}
if (
reasoningStartTime &&
!reasoningEndTime &&
isReasoningEnded(fullText)
) {
reasoningEndTime = new Date()
const reasoningTime =
reasoningEndTime.getTime() - reasoningStartTime.getTime()
timetaken = reasoningTime
}
setMessages((prev) => {
return prev.map((message) => {
if (message.id === generateMessageId) {
return {
...message,
message: fullText + "▋"
message: fullText + "▋",
reasoning_time_taken: timetaken
}
}
return message
@@ -1248,7 +1326,8 @@ export const useMessage = () => {
...message,
message: fullText,
sources: source,
generationInfo
generationInfo,
reasoning_time_taken: timetaken
}
}
return message
@@ -1277,7 +1356,8 @@ export const useMessage = () => {
image,
fullText,
source,
generationInfo
generationInfo,
reasoning_time_taken: timetaken
})
setIsProcessing(false)
@@ -1448,18 +1528,36 @@ export const useMessage = () => {
]
})
let count = 0
let reasoningStartTime: Date | null = null
let reasoningEndTime: Date | null = null
let timetaken = 0
for await (const chunk of chunks) {
contentToSave += chunk?.content
fullText += chunk?.content
if (count === 0) {
setIsProcessing(true)
}
if (isReasoningStarted(fullText) && !reasoningStartTime) {
reasoningStartTime = new Date()
}
if (
reasoningStartTime &&
!reasoningEndTime &&
isReasoningEnded(fullText)
) {
reasoningEndTime = new Date()
const reasoningTime =
reasoningEndTime.getTime() - reasoningStartTime.getTime()
timetaken = reasoningTime
}
setMessages((prev) => {
return prev.map((message) => {
if (message.id === generateMessageId) {
return {
...message,
message: fullText + "▋"
message: fullText + "▋",
reasoning_time_taken: timetaken
}
}
return message
@@ -1474,7 +1572,8 @@ export const useMessage = () => {
return {
...message,
message: fullText,
generationInfo
generationInfo,
reasoning_time_taken: timetaken
}
}
return message
@@ -1506,7 +1605,8 @@ export const useMessage = () => {
source: [],
message_source: "copilot",
message_type: messageType,
generationInfo
generationInfo,
reasoning_time_taken: timetaken
})
setIsProcessing(false)

View File

@@ -37,6 +37,11 @@ import { pageAssistModel } from "@/models"
import { getNoOfRetrievedDocs } from "@/services/app"
import { humanMessageFormatter } from "@/utils/human-message"
import { pageAssistEmbeddingModel } from "@/models/embedding"
import {
isReasoningEnded,
isReasoningStarted,
removeReasoning
} from "@/libs/reasoning"
export const useMessageOption = () => {
const {
@@ -76,10 +81,7 @@ export const useMessageOption = () => {
} = useStoreMessageOption()
const currentChatModelSettings = useStoreChatModelSettings()
const [selectedModel, setSelectedModel] = useStorage("selectedModel")
const [defaultInternetSearchOn, ] = useStorage(
"defaultInternetSearchOn",
false
)
const [defaultInternetSearchOn] = useStorage("defaultInternetSearchOn", false)
const [speechToTextLanguage, setSpeechToTextLanguage] = useStorage(
"speechToTextLanguage",
"en-US"
@@ -102,7 +104,7 @@ export const useMessageOption = () => {
setStreaming(false)
currentChatModelSettings.reset()
textareaRef?.current?.focus()
if(defaultInternetSearchOn) {
if (defaultInternetSearchOn) {
setWebSearch(true)
}
}
@@ -195,6 +197,7 @@ export const useMessageOption = () => {
setMessages(newMessage)
let fullText = ""
let contentToSave = ""
let timetaken = 0
try {
setIsSearchingInternet(true)
@@ -261,6 +264,7 @@ export const useMessageOption = () => {
})
const response = await questionOllama.invoke(promptForQuestion)
query = response.content.toString()
query = removeReasoning(query)
}
const { prompt, source } = await getSystemPromptForWeb(query)
@@ -325,18 +329,35 @@ export const useMessageOption = () => {
}
)
let count = 0
let reasoningStartTime: Date | undefined = undefined
let reasoningEndTime: Date | undefined = undefined
for await (const chunk of chunks) {
contentToSave += chunk?.content
fullText += chunk?.content
if (count === 0) {
setIsProcessing(true)
}
if (isReasoningStarted(fullText) && !reasoningStartTime) {
reasoningStartTime = new Date()
}
if (
reasoningStartTime &&
!reasoningEndTime &&
isReasoningEnded(fullText)
) {
reasoningEndTime = new Date()
const reasoningTime =
reasoningEndTime.getTime() - reasoningStartTime.getTime()
timetaken = reasoningTime
}
setMessages((prev) => {
return prev.map((message) => {
if (message.id === generateMessageId) {
return {
...message,
message: fullText + "▋"
message: fullText + "▋",
reasoning_time_taken: timetaken
}
}
return message
@@ -352,7 +373,8 @@ export const useMessageOption = () => {
...message,
message: fullText,
sources: source,
generationInfo
generationInfo,
reasoning_time_taken: timetaken
}
}
return message
@@ -381,7 +403,8 @@ export const useMessageOption = () => {
image,
fullText,
source,
generationInfo
generationInfo,
reasoning_time_taken: timetaken
})
setIsProcessing(false)
@@ -537,6 +560,7 @@ export const useMessageOption = () => {
setMessages(newMessage)
let fullText = ""
let contentToSave = ""
let timetaken = 0
try {
const prompt = await systemPromptForNonRagOption()
@@ -622,9 +646,28 @@ export const useMessageOption = () => {
)
let count = 0
let reasoningStartTime: Date | null = null
let reasoningEndTime: Date | null = null
for await (const chunk of chunks) {
contentToSave += chunk?.content
fullText += chunk?.content
if (isReasoningStarted(fullText) && !reasoningStartTime) {
reasoningStartTime = new Date()
}
if (
reasoningStartTime &&
!reasoningEndTime &&
isReasoningEnded(fullText)
) {
reasoningEndTime = new Date()
const reasoningTime =
reasoningEndTime.getTime() - reasoningStartTime.getTime()
timetaken = reasoningTime
}
if (count === 0) {
setIsProcessing(true)
}
@@ -633,7 +676,8 @@ export const useMessageOption = () => {
if (message.id === generateMessageId) {
return {
...message,
message: fullText + "▋"
message: fullText + "▋",
reasoning_time_taken: timetaken
}
}
return message
@@ -648,7 +692,8 @@ export const useMessageOption = () => {
return {
...message,
message: fullText,
generationInfo
generationInfo,
reasoning_time_taken: timetaken
}
}
return message
@@ -679,7 +724,8 @@ export const useMessageOption = () => {
source: [],
generationInfo,
prompt_content: promptContent,
prompt_id: promptId
prompt_id: promptId,
reasoning_time_taken: timetaken
})
setIsProcessing(false)
@@ -818,7 +864,7 @@ export const useMessageOption = () => {
knownledge_id: selectedKnowledge.id
}
)
let timetaken = 0
try {
let query = message
const { ragPrompt: systemPrompt, ragQuestionPrompt: questionPrompt } =
@@ -882,6 +928,7 @@ export const useMessageOption = () => {
})
const response = await questionOllama.invoke(promptForQuestion)
query = response.content.toString()
query = removeReasoning(query)
}
const docSize = await getNoOfRetrievedDocs()
@@ -933,18 +980,36 @@ export const useMessageOption = () => {
}
)
let count = 0
let reasoningStartTime: Date | undefined = undefined
let reasoningEndTime: Date | undefined = undefined
for await (const chunk of chunks) {
contentToSave += chunk?.content
fullText += chunk?.content
if (count === 0) {
setIsProcessing(true)
}
if (isReasoningStarted(fullText) && !reasoningStartTime) {
reasoningStartTime = new Date()
}
if (
reasoningStartTime &&
!reasoningEndTime &&
isReasoningEnded(fullText)
) {
reasoningEndTime = new Date()
const reasoningTime =
reasoningEndTime.getTime() - reasoningStartTime.getTime()
timetaken = reasoningTime
}
setMessages((prev) => {
return prev.map((message) => {
if (message.id === generateMessageId) {
return {
...message,
message: fullText + "▋"
message: fullText + "▋",
reasoning_time_taken: timetaken
}
}
return message
@@ -960,7 +1025,8 @@ export const useMessageOption = () => {
...message,
message: fullText,
sources: source,
generationInfo
generationInfo,
reasoning_time_taken: timetaken
}
}
return message
@@ -989,7 +1055,8 @@ export const useMessageOption = () => {
image,
fullText,
source,
generationInfo
generationInfo,
reasoning_time_taken: timetaken
})
setIsProcessing(false)
@@ -1206,6 +1273,6 @@ export const useMessageOption = () => {
setTemporaryChat,
useOCR,
setUseOCR,
defaultInternetSearchOn,
defaultInternetSearchOn
}
}