Feat: support query mode prefix in retrieval input
This commit is contained in:
@@ -10,6 +10,7 @@ import QuerySettings from '@/components/retrieval/QuerySettings'
|
|||||||
import { ChatMessage, MessageWithError } from '@/components/retrieval/ChatMessage'
|
import { ChatMessage, MessageWithError } from '@/components/retrieval/ChatMessage'
|
||||||
import { EraserIcon, SendIcon } from 'lucide-react'
|
import { EraserIcon, SendIcon } from 'lucide-react'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
|
import type { QueryMode } from '@/api/lightrag'
|
||||||
|
|
||||||
export default function RetrievalTesting() {
|
export default function RetrievalTesting() {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
@@ -18,6 +19,7 @@ export default function RetrievalTesting() {
|
|||||||
)
|
)
|
||||||
const [inputValue, setInputValue] = useState('')
|
const [inputValue, setInputValue] = useState('')
|
||||||
const [isLoading, setIsLoading] = useState(false)
|
const [isLoading, setIsLoading] = useState(false)
|
||||||
|
const [inputError, setInputError] = useState('') // Error message for input
|
||||||
// Reference to track if we should follow scroll during streaming (using ref for synchronous updates)
|
// Reference to track if we should follow scroll during streaming (using ref for synchronous updates)
|
||||||
const shouldFollowScrollRef = useRef(true)
|
const shouldFollowScrollRef = useRef(true)
|
||||||
// Reference to track if user interaction is from the form area
|
// Reference to track if user interaction is from the form area
|
||||||
@@ -47,7 +49,38 @@ export default function RetrievalTesting() {
|
|||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
if (!inputValue.trim() || isLoading) return
|
if (!inputValue.trim() || isLoading) return
|
||||||
|
|
||||||
|
// Parse query mode prefix
|
||||||
|
const allowedModes: QueryMode[] = ['naive', 'local', 'global', 'hybrid', 'mix', 'bypass']
|
||||||
|
const prefixMatch = inputValue.match(/^\/(\w+)\s+(.+)/)
|
||||||
|
let modeOverride: QueryMode | undefined = undefined
|
||||||
|
let actualQuery = inputValue
|
||||||
|
|
||||||
|
// If input starts with a slash, but does not match the valid prefix pattern, treat as error
|
||||||
|
if (/^\/\S+/.test(inputValue) && !prefixMatch) {
|
||||||
|
setInputError(t('retrievePanel.retrieval.queryModePrefixInvalid'))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (prefixMatch) {
|
||||||
|
const mode = prefixMatch[1] as QueryMode
|
||||||
|
const query = prefixMatch[2]
|
||||||
|
if (!allowedModes.includes(mode)) {
|
||||||
|
setInputError(
|
||||||
|
t('retrievePanel.retrieval.queryModeError', {
|
||||||
|
modes: 'naive, local, global, hybrid, mix, bypass',
|
||||||
|
})
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
modeOverride = mode
|
||||||
|
actualQuery = query
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear error message
|
||||||
|
setInputError('')
|
||||||
|
|
||||||
// Create messages
|
// Create messages
|
||||||
|
// Save the original input (with prefix if any) in userMessage.content for display
|
||||||
const userMessage: Message = {
|
const userMessage: Message = {
|
||||||
content: inputValue,
|
content: inputValue,
|
||||||
role: 'user'
|
role: 'user'
|
||||||
@@ -103,11 +136,12 @@ export default function RetrievalTesting() {
|
|||||||
const state = useSettingsStore.getState()
|
const state = useSettingsStore.getState()
|
||||||
const queryParams = {
|
const queryParams = {
|
||||||
...state.querySettings,
|
...state.querySettings,
|
||||||
query: userMessage.content,
|
query: actualQuery,
|
||||||
conversation_history: prevMessages
|
conversation_history: prevMessages
|
||||||
.filter((m) => m.isError !== true)
|
.filter((m) => m.isError !== true)
|
||||||
.slice(-(state.querySettings.history_turns || 0) * 2)
|
.slice(-(state.querySettings.history_turns || 0) * 2)
|
||||||
.map((m) => ({ role: m.role, content: m.content }))
|
.map((m) => ({ role: m.role, content: m.content })),
|
||||||
|
...(modeOverride ? { mode: modeOverride } : {})
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -270,10 +304,17 @@ export default function RetrievalTesting() {
|
|||||||
id="query-input"
|
id="query-input"
|
||||||
className="w-full"
|
className="w-full"
|
||||||
value={inputValue}
|
value={inputValue}
|
||||||
onChange={(e) => setInputValue(e.target.value)}
|
onChange={(e) => {
|
||||||
|
setInputValue(e.target.value)
|
||||||
|
if (inputError) setInputError('')
|
||||||
|
}}
|
||||||
placeholder={t('retrievePanel.retrieval.placeholder')}
|
placeholder={t('retrievePanel.retrieval.placeholder')}
|
||||||
disabled={isLoading}
|
disabled={isLoading}
|
||||||
/>
|
/>
|
||||||
|
{/* Error message below input */}
|
||||||
|
{inputError && (
|
||||||
|
<div className="absolute left-0 top-full mt-1 text-xs text-red-500">{inputError}</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
<Button type="submit" variant="default" disabled={isLoading} size="sm">
|
<Button type="submit" variant="default" disabled={isLoading} size="sm">
|
||||||
<SendIcon />
|
<SendIcon />
|
||||||
|
@@ -303,8 +303,10 @@
|
|||||||
"startPrompt": "ابدأ الاسترجاع بكتابة استفسارك أدناه",
|
"startPrompt": "ابدأ الاسترجاع بكتابة استفسارك أدناه",
|
||||||
"clear": "مسح",
|
"clear": "مسح",
|
||||||
"send": "إرسال",
|
"send": "إرسال",
|
||||||
"placeholder": "اكتب استفسارك...",
|
"placeholder": "اكتب استفسارك... (بادئة وضع الاستعلام: /<Query Mode>)",
|
||||||
"error": "خطأ: فشل الحصول على الرد"
|
"error": "خطأ: فشل الحصول على الرد",
|
||||||
|
"queryModeError": "يُسمح فقط بأنماط الاستعلام التالية: {{modes}}",
|
||||||
|
"queryModePrefixInvalid": "بادئة وضع الاستعلام غير صالحة. استخدم: /<الوضع> [مسافة] استفسارك"
|
||||||
},
|
},
|
||||||
"querySettings": {
|
"querySettings": {
|
||||||
"parametersTitle": "المعلمات",
|
"parametersTitle": "المعلمات",
|
||||||
|
@@ -303,8 +303,10 @@
|
|||||||
"startPrompt": "Start a retrieval by typing your query below",
|
"startPrompt": "Start a retrieval by typing your query below",
|
||||||
"clear": "Clear",
|
"clear": "Clear",
|
||||||
"send": "Send",
|
"send": "Send",
|
||||||
"placeholder": "Type your query...",
|
"placeholder": "Type your query... (Query mode prefix: /<Query Mode>)",
|
||||||
"error": "Error: Failed to get response"
|
"error": "Error: Failed to get response",
|
||||||
|
"queryModeError": "Only supports the following query modes: {{modes}}",
|
||||||
|
"queryModePrefixInvalid": "Invalid query mode prefix. Use: /<mode> [space] your query"
|
||||||
},
|
},
|
||||||
"querySettings": {
|
"querySettings": {
|
||||||
"parametersTitle": "Parameters",
|
"parametersTitle": "Parameters",
|
||||||
|
@@ -303,8 +303,10 @@
|
|||||||
"startPrompt": "Démarrez une récupération en tapant votre requête ci-dessous",
|
"startPrompt": "Démarrez une récupération en tapant votre requête ci-dessous",
|
||||||
"clear": "Effacer",
|
"clear": "Effacer",
|
||||||
"send": "Envoyer",
|
"send": "Envoyer",
|
||||||
"placeholder": "Tapez votre requête...",
|
"placeholder": "Tapez votre requête... (Préfixe du mode de requête : /<Query Mode>)",
|
||||||
"error": "Erreur : Échec de l'obtention de la réponse"
|
"error": "Erreur : Échec de l'obtention de la réponse",
|
||||||
|
"queryModeError": "Seuls les modes de requête suivants sont pris en charge : {{modes}}",
|
||||||
|
"queryModePrefixInvalid": "Préfixe de mode de requête invalide. Utilisez : /<mode> [espace] votre requête"
|
||||||
},
|
},
|
||||||
"querySettings": {
|
"querySettings": {
|
||||||
"parametersTitle": "Paramètres",
|
"parametersTitle": "Paramètres",
|
||||||
|
@@ -304,8 +304,10 @@
|
|||||||
"startPrompt": "输入查询开始检索",
|
"startPrompt": "输入查询开始检索",
|
||||||
"clear": "清空",
|
"clear": "清空",
|
||||||
"send": "发送",
|
"send": "发送",
|
||||||
"placeholder": "输入查询...",
|
"placeholder": "输入查询...(查询模式前缀:/<Query Mode>)",
|
||||||
"error": "错误:获取响应失败"
|
"error": "错误:获取响应失败",
|
||||||
|
"queryModeError": "仅支持以下查询模式:{{modes}}",
|
||||||
|
"queryModePrefixInvalid": "无效的查询模式前缀。请使用:/<模式> [空格] 查询内容"
|
||||||
},
|
},
|
||||||
"querySettings": {
|
"querySettings": {
|
||||||
"parametersTitle": "参数",
|
"parametersTitle": "参数",
|
||||||
|
@@ -303,8 +303,10 @@
|
|||||||
"startPrompt": "輸入查詢開始檢索",
|
"startPrompt": "輸入查詢開始檢索",
|
||||||
"clear": "清空",
|
"clear": "清空",
|
||||||
"send": "送出",
|
"send": "送出",
|
||||||
"placeholder": "輸入查詢...",
|
"placeholder": "輸入查詢...(查詢模式前綴:/<Query Mode>)",
|
||||||
"error": "錯誤:取得回應失敗"
|
"error": "錯誤:取得回應失敗",
|
||||||
|
"queryModeError": "僅支援以下查詢模式:{{modes}}",
|
||||||
|
"queryModePrefixInvalid": "無效的查詢模式前綴。請使用:/<模式> [空格] 查詢內容"
|
||||||
},
|
},
|
||||||
"querySettings": {
|
"querySettings": {
|
||||||
"parametersTitle": "參數",
|
"parametersTitle": "參數",
|
||||||
|
Reference in New Issue
Block a user