feat: Add top_k Input Control to Search UI for Adjustable Graph Exploration Depth (#1202)
Fixes #1194 Summary: This PR introduces a new "Max results" (top_k) input control to the search UI, allowing users to specify how many results to return for each search. This directly controls the graph exploration depth, enabling both focused and broad explorations. Changes UI Enhancement: Added a number input labeled "Max results" (default: 10, min: 1, max: 100) to the search form, with validation and a tooltip explaining its impact. Placed the input between the search type dropdown and the submit button in SearchView.tsx State Management: Managed top_k value in component state. Included top_k in the form submission. API Integration: Updated useChat.ts to accept and send the top_k parameter in API calls to the backend. @Vasilije1990
This commit is contained in:
commit
bf1970b679
2 changed files with 46 additions and 16 deletions
|
|
@ -14,7 +14,7 @@ const fetchMessages = () => {
|
|||
.then(response => response.json());
|
||||
};
|
||||
|
||||
const sendMessage = (message: string, searchType: string) => {
|
||||
const sendMessage = (message: string, searchType: string, topK: number) => {
|
||||
return fetch("/v1/search/", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
|
|
@ -24,6 +24,7 @@ const sendMessage = (message: string, searchType: string) => {
|
|||
query: message,
|
||||
searchType,
|
||||
datasets: ["main_dataset"],
|
||||
top_k: topK,
|
||||
}),
|
||||
})
|
||||
.then(response => response.json());
|
||||
|
|
@ -45,7 +46,7 @@ export default function useChat(dataset: Dataset) {
|
|||
return setMessages(data);
|
||||
}, []);
|
||||
|
||||
const handleMessageSending = useCallback((message: string, searchType: string) => {
|
||||
const handleMessageSending = useCallback((message: string, searchType: string, topK: number) => {
|
||||
const sentMessageId = v4();
|
||||
|
||||
setMessages((messages) => [
|
||||
|
|
@ -59,7 +60,7 @@ export default function useChat(dataset: Dataset) {
|
|||
|
||||
disableSearchRun();
|
||||
|
||||
return sendMessage(message, searchType)
|
||||
return sendMessage(message, searchType, topK)
|
||||
.then(newMessages => {
|
||||
setMessages((messages) => [
|
||||
...messages,
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import classNames from "classnames";
|
|||
import { useCallback, useEffect, useRef, useState } from "react";
|
||||
|
||||
import { LoadingIndicator } from "@/ui/App";
|
||||
import { CTAButton, Select, TextArea } from "@/ui/elements";
|
||||
import { CTAButton, Select, TextArea, Input } from "@/ui/elements";
|
||||
import useChat from "@/modules/chat/hooks/useChat";
|
||||
|
||||
import styles from "./SearchView.module.css";
|
||||
|
|
@ -59,17 +59,28 @@ export default function SearchView() {
|
|||
}, [refreshChat, scrollToBottom]);
|
||||
|
||||
const [searchInputValue, setSearchInputValue] = useState("");
|
||||
// Add state for top_k
|
||||
const [topK, setTopK] = useState(10);
|
||||
|
||||
const handleSearchInputChange = useCallback((value: string) => {
|
||||
setSearchInputValue(value);
|
||||
}, []);
|
||||
|
||||
// Add handler for top_k input
|
||||
const handleTopKChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
let value = parseInt(e.target.value, 10);
|
||||
if (isNaN(value)) value = 10;
|
||||
if (value < 1) value = 1;
|
||||
if (value > 100) value = 100;
|
||||
setTopK(value);
|
||||
}, []);
|
||||
|
||||
const handleChatMessageSubmit = useCallback((event: React.FormEvent<SearchFormPayload>) => {
|
||||
event.preventDefault();
|
||||
|
||||
const formElements = event.currentTarget;
|
||||
|
||||
const searchType = formElements.searchType.value;
|
||||
|
||||
const chatInput = searchInputValue.trim();
|
||||
|
||||
if (chatInput === "") {
|
||||
|
|
@ -79,10 +90,11 @@ export default function SearchView() {
|
|||
scrollToBottom();
|
||||
|
||||
setSearchInputValue("");
|
||||
|
||||
sendMessage(chatInput, searchType)
|
||||
|
||||
// Pass topK to sendMessage
|
||||
sendMessage(chatInput, searchType, topK)
|
||||
.then(scrollToBottom)
|
||||
}, [scrollToBottom, sendMessage, searchInputValue]);
|
||||
}, [scrollToBottom, sendMessage, searchInputValue, topK]);
|
||||
|
||||
const chatFormRef = useRef<HTMLFormElement>(null);
|
||||
|
||||
|
|
@ -125,13 +137,30 @@ export default function SearchView() {
|
|||
className="resize-none min-h-14 max-h-96 overflow-y-auto"
|
||||
/>
|
||||
<div className="flex flex-row items-center justify-between gap-4">
|
||||
<div className="flex flex-row items-center gap-2">
|
||||
<label className="text-gray-600 whitespace-nowrap">Search type:</label>
|
||||
<Select name="searchType" defaultValue={searchOptions[0].value} className="max-w-2xs">
|
||||
{searchOptions.map((option) => (
|
||||
<option key={option.value} value={option.value}>{option.label}</option>
|
||||
))}
|
||||
</Select>
|
||||
<div className="flex flex-row items-center gap-4">
|
||||
<div className="flex flex-row items-center gap-2">
|
||||
<label className="text-gray-600 whitespace-nowrap">Search type:</label>
|
||||
<Select name="searchType" defaultValue={searchOptions[0].value} className="max-w-2xs">
|
||||
{searchOptions.map((option) => (
|
||||
<option key={option.value} value={option.value}>{option.label}</option>
|
||||
))}
|
||||
</Select>
|
||||
</div>
|
||||
<div className="flex flex-row items-center gap-2">
|
||||
<label className="text-gray-600 whitespace-nowrap" title="Controls how many results to return. Smaller = focused, larger = broader graph exploration.">
|
||||
Max results:
|
||||
</label>
|
||||
<Input
|
||||
type="number"
|
||||
name="topK"
|
||||
min={1}
|
||||
max={100}
|
||||
value={topK}
|
||||
onChange={handleTopKChange}
|
||||
className="w-20"
|
||||
title="Controls how many results to return. Smaller = focused, larger = broader graph exploration."
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<CTAButton disabled={isSearchRunning} type="submit">
|
||||
{isSearchRunning? "Searching..." : "Search"}
|
||||
|
|
@ -142,4 +171,4 @@ export default function SearchView() {
|
|||
</form>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue