UNPKG

@roadiehq/rag-ai

Version:

132 lines (129 loc) 5.19 kB
import React, { useState, useCallback } from 'react'; import { makeStyles, DialogTitle, Typography, IconButton, DialogContent, Box, Grid } from '@material-ui/core'; import { useHotkeys } from 'react-hotkeys-hook'; import CloseIcon from '@material-ui/icons/Close'; import { QuestionBox } from './QuestionBox.esm.js'; import { ResultRenderer } from './ResultRenderer.esm.js'; import { EmbeddingsView } from './EmbeddingsView.esm.js'; import Dialog from '@material-ui/core/Dialog'; import { ragAiApiRef } from '../../api/ragApi.esm.js'; import 'eventsource-parser/stream'; import { useApi } from '@backstage/core-plugin-api'; import { Thinking } from './Thinking.esm.js'; import { WarningPanel } from '@backstage/core-components'; const useStyles = makeStyles((theme) => ({ dialogTitle: { gap: theme.spacing(1), display: "grid", alignItems: "center", gridTemplateColumns: "1fr auto", "&> button": { marginTop: theme.spacing(1) } }, filter: { "& + &": { marginTop: theme.spacing(2.5) } }, filters: { padding: theme.spacing(2), marginTop: theme.spacing(2) }, input: { flex: 1 }, closeButton: { position: "absolute", right: theme.spacing(1), top: theme.spacing(1), color: theme.palette.grey[500] }, dialogActionsContainer: { padding: theme.spacing(1, 3) }, viewResultsLink: { verticalAlign: "0.5em" } })); const ControlledRagModal = ({ title = "AI Assistant", hotkey = "ctrl+comma", open, setOpen }) => { const classes = useStyles(); const [thinking, setThinking] = useState(false); const [questionResult, setQuestionResult] = useState(""); const [embeddings, setEmbeddings] = useState([]); const [warning, setWarning] = useState(); const ragApi = useApi(ragAiApiRef); const askLlm = useCallback( async (question, source) => { setThinking(true); setQuestionResult(""); setWarning(void 0); setEmbeddings([]); for await (const chunk of ragApi.ask(question, source)) { switch (chunk.event) { case "response": { setQuestionResult((value) => value + chunk.data); break; } case "embeddings": { setEmbeddings(JSON.parse(chunk.data)); break; } case "error": { setWarning(chunk.data); break; } case "usage": { break; } default: throw new Error(`Unknown event type: ${chunk.event}`); } } setThinking(false); }, [ragApi] ); useHotkeys(hotkey, () => setOpen(true), []); return /* @__PURE__ */ React.createElement( Dialog, { open, onClose: () => { setOpen(false); setThinking(false); setQuestionResult(""); setEmbeddings([]); }, fullWidth: true, maxWidth: "lg" }, /* @__PURE__ */ React.createElement(DialogTitle, null, /* @__PURE__ */ React.createElement(Typography, { variant: "h6" }, title), /* @__PURE__ */ React.createElement( IconButton, { "aria-label": "close", className: classes.closeButton, onClick: () => setOpen(false) }, /* @__PURE__ */ React.createElement(CloseIcon, null) )), /* @__PURE__ */ React.createElement(DialogContent, null, /* @__PURE__ */ React.createElement(Box, { className: classes.dialogTitle }, /* @__PURE__ */ React.createElement( QuestionBox, { onSubmit: askLlm, fullWidth: true, onClear: () => { setQuestionResult(""); setEmbeddings([]); } } )), warning && /* @__PURE__ */ React.createElement(WarningPanel, { severity: "warning", message: warning }), thinking && !questionResult && !warning ? /* @__PURE__ */ React.createElement(Box, { p: 6, display: "flex", justifyContent: "center", alignItems: "center" }, /* @__PURE__ */ React.createElement(Thinking, null)) : /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(Box, { py: 3 }, /* @__PURE__ */ React.createElement(Grid, { container: true }, questionResult && /* @__PURE__ */ React.createElement(Grid, { item: true, xs: 12 }, /* @__PURE__ */ React.createElement(Typography, { variant: "h6" }, "Response")), /* @__PURE__ */ React.createElement(Grid, { item: true, xs: 12 }, /* @__PURE__ */ React.createElement(ResultRenderer, { result: questionResult })))), /* @__PURE__ */ React.createElement(Box, { py: 3 }, /* @__PURE__ */ React.createElement(Grid, { container: true }, embeddings && embeddings.length > 0 && /* @__PURE__ */ React.createElement(Grid, { item: true, xs: 12 }, /* @__PURE__ */ React.createElement(Typography, { variant: "h6" }, "Additional Information")), /* @__PURE__ */ React.createElement(Grid, { item: true, xs: 12 }, /* @__PURE__ */ React.createElement(EmbeddingsView, { embeddings })))))) ); }; const UncontrolledRagModal = (props) => { const [open, setOpen] = useState(false); return /* @__PURE__ */ React.createElement(ControlledRagModal, { open, setOpen, ...props }); }; export { ControlledRagModal, UncontrolledRagModal }; //# sourceMappingURL=RagModal.esm.js.map