Add a fact checker feature with updated styling (#835)

- Add an experimental feature used for fact-checking falsifiable statements with customizable models. See attached screenshot for example. Once you input a statement that needs to be fact-checked, Khoj goes on a research spree to verify or refute it.
- Integrate frontend libraries for [Tailwind](https://tailwindcss.com/) and [ShadCN](https://ui.shadcn.com/) for easier UI development. Update corresponding styling for some existing UI components. 
- Add component for model selection 
- Add backend support for sharing arbitrary packets of data that will be consumed by specific front-end views in shareable scenarios
This commit is contained in:
sabaimran
2024-06-27 06:15:38 -07:00
committed by GitHub
parent 3b7a9358c3
commit 870d9ecdbf
35 changed files with 3294 additions and 223 deletions

View File

@@ -0,0 +1,152 @@
import { useAuthenticatedData } from '@/app/common/auth';
import React, { useEffect } from 'react';
import useSWR from 'swr';
import {
AlertDialog,
AlertDialogAction,
AlertDialogCancel,
AlertDialogContent,
AlertDialogDescription,
AlertDialogFooter,
AlertDialogHeader,
AlertDialogTitle,
} from "@/components/ui/alert-dialog";
import styles from './modelPicker.module.css';
export interface Model {
id: number;
chat_model: string;
}
// Custom fetcher function to fetch options
const fetchOptionsRequest = async (url: string) => {
const response = await fetch(url, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
},
});
return response.json();
};
export const useOptionsRequest = (url: string) => {
const { data, error } = useSWR<Model[]>(url, fetchOptionsRequest);
return {
data,
isLoading: !error && !data,
isError: error,
};
};
const fetchSelectedModel = async (url: string) => {
const response = await fetch(url, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
},
});
return response.json();
}
export const useSelectedModel = (url: string) => {
const { data, error } = useSWR<Model>(url, fetchSelectedModel);
return {
data,
isLoading: !error && !data,
isError: error,
}
}
interface ModelPickerProps {
disabled?: boolean;
setModelUsed?: (model: Model) => void;
initialModel?: Model;
}
export const ModelPicker: React.FC<any> = (props: ModelPickerProps) => {
const { data: models } = useOptionsRequest('/api/config/data/conversation/model/options');
const { data: selectedModel } = useSelectedModel('/api/config/data/conversation/model');
const [openLoginDialog, setOpenLoginDialog] = React.useState(false);
let userData = useAuthenticatedData();
useEffect(() => {
if (props.setModelUsed && selectedModel) {
props.setModelUsed(selectedModel);
}
}, [selectedModel]);
if (!models) {
return <div>Loading...</div>;
}
function onSelect(model: Model) {
if (!userData) {
setOpenLoginDialog(true);
return;
}
if (props.setModelUsed) {
props.setModelUsed(model);
}
fetch('/api/config/data/conversation/model' + '?id=' + String(model.id), { method: 'POST', body: JSON.stringify(model) })
.then((response) => {
if (!response.ok) {
throw new Error('Failed to select model');
}
})
.catch((error) => {
console.error('Failed to select model', error);
});
}
function isSelected(model: Model) {
if (props.initialModel) {
return model.id === props.initialModel.id;
}
return selectedModel?.id === model.id;
}
return (
<div className={styles.modelPicker}>
<select className={styles.modelPicker} onChange={(e) => {
const selectedModelId = Number(e.target.value);
const selectedModel = models.find((model) => model.id === selectedModelId);
if (selectedModel) {
onSelect(selectedModel);
} else {
console.error('Selected model not found', e.target.value);
}
}} disabled={props.disabled}>
{models?.map((model) => (
<option key={model.id} value={model.id} selected={isSelected(model)}>
{model.chat_model}
</option>
))}
</select>
<AlertDialog open={openLoginDialog} onOpenChange={setOpenLoginDialog}>
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogTitle>You must be logged in to configure your model.</AlertDialogTitle>
<AlertDialogDescription>Once you create an account with Khoj, you can configure your model and use a whole suite of other features. Check out our <a href="https://docs.khoj.dev/">documentation</a> to learn more.
</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel>Cancel</AlertDialogCancel>
<AlertDialogAction
onClick={() => {
window.location.href = window.location.origin + '/login';
}}>
Sign in
</AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
</div>
);
};