= ({
{document.type === 'remote' ? 'Pre-loaded' : 'Private'}
-
+
{document.type !== 'remote' && (
-  {
event.stopPropagation();
handleDeleteDocument(index, document);
}}
- />
+ >
+ 
+
)}
{document.syncFrequency && (
diff --git a/frontend/src/settings/ToolConfig.tsx b/frontend/src/settings/ToolConfig.tsx
new file mode 100644
index 00000000..0de4dab9
--- /dev/null
+++ b/frontend/src/settings/ToolConfig.tsx
@@ -0,0 +1,293 @@
+import React from 'react';
+
+import userService from '../api/services/userService';
+import ArrowLeft from '../assets/arrow-left.svg';
+import Input from '../components/Input';
+import { UserTool } from './types';
+
+export default function ToolConfig({
+ tool,
+ setTool,
+ handleGoBack,
+}: {
+ tool: UserTool;
+ setTool: (tool: UserTool) => void;
+ handleGoBack: () => void;
+}) {
+ const [authKey, setAuthKey] = React.useState (
+ tool.config?.token || '',
+ );
+
+ const handleCheckboxChange = (actionIndex: number, property: string) => {
+ setTool({
+ ...tool,
+ actions: tool.actions.map((action, index) => {
+ if (index === actionIndex) {
+ return {
+ ...action,
+ parameters: {
+ ...action.parameters,
+ properties: {
+ ...action.parameters.properties,
+ [property]: {
+ ...action.parameters.properties[property],
+ filled_by_llm:
+ !action.parameters.properties[property].filled_by_llm,
+ },
+ },
+ },
+ };
+ }
+ return action;
+ }),
+ });
+ };
+
+ const handleSaveChanges = () => {
+ userService
+ .updateTool({
+ id: tool.id,
+ name: tool.name,
+ displayName: tool.displayName,
+ description: tool.description,
+ config: { token: authKey },
+ actions: tool.actions,
+ status: tool.status,
+ })
+ .then(() => {
+ handleGoBack();
+ });
+ };
+ return (
+
+
+
+ Back to all tools
+
+
+
+ Type
+
+
+ {tool.name}
+
+
+
+ {Object.keys(tool?.config).length !== 0 && (
+
+ Authentication
+
+ )}
+
+ {Object.keys(tool?.config).length !== 0 && (
+
+
+ API Key / Oauth
+
+ setAuthKey(e.target.value)}
+ borderVariant="thin"
+ placeholder="Enter API Key / Oauth"
+ >
+
+ )}
+
+
+
+
+
+
+ Actions
+
+
+ {tool.actions.map((action, actionIndex) => {
+ return (
+
+
+
+ {action.name}
+
+
+
+
+ {
+ setTool({
+ ...tool,
+ actions: tool.actions.map((act, index) => {
+ if (index === actionIndex) {
+ return {
+ ...act,
+ description: e.target.value,
+ };
+ }
+ return act;
+ }),
+ });
+ }}
+ borderVariant="thin"
+ >
+
+
+
+
+
+ | Field Name |
+ Field Type |
+ Filled by LLM |
+ FIeld description |
+ Value |
+
+
+
+ {Object.entries(action.parameters?.properties).map(
+ (param, index) => {
+ const uniqueKey = `${actionIndex}-${param[0]}`;
+ return (
+
+ | {param[0]} |
+ {param[1].type} |
+
+
+ |
+
+ {
+ setTool({
+ ...tool,
+ actions: tool.actions.map(
+ (act, index) => {
+ if (index === actionIndex) {
+ return {
+ ...act,
+ parameters: {
+ ...act.parameters,
+ properties: {
+ ...act.parameters.properties,
+ [param[0]]: {
+ ...act.parameters
+ .properties[param[0]],
+ description: e.target.value,
+ },
+ },
+ },
+ };
+ }
+ return act;
+ },
+ ),
+ });
+ }}
+ >
+ |
+
+ {
+ setTool({
+ ...tool,
+ actions: tool.actions.map(
+ (act, index) => {
+ if (index === actionIndex) {
+ return {
+ ...act,
+ parameters: {
+ ...act.parameters,
+ properties: {
+ ...act.parameters.properties,
+ [param[0]]: {
+ ...act.parameters
+ .properties[param[0]],
+ value: e.target.value,
+ },
+ },
+ },
+ };
+ }
+ return act;
+ },
+ ),
+ });
+ }}
+ >
+ |
+
+ );
+ },
+ )}
+
+
+
+
+ );
+ })}
+
+
+
+ );
+}
diff --git a/frontend/src/settings/Tools.tsx b/frontend/src/settings/Tools.tsx
new file mode 100644
index 00000000..d29ba42c
--- /dev/null
+++ b/frontend/src/settings/Tools.tsx
@@ -0,0 +1,157 @@
+import React from 'react';
+
+import userService from '../api/services/userService';
+import CogwheelIcon from '../assets/cogwheel.svg';
+import Input from '../components/Input';
+import AddToolModal from '../modals/AddToolModal';
+import { ActiveState } from '../models/misc';
+import { UserTool } from './types';
+import ToolConfig from './ToolConfig';
+
+export default function Tools() {
+ const [searchTerm, setSearchTerm] = React.useState('');
+ const [addToolModalState, setAddToolModalState] =
+ React.useState('INACTIVE');
+ const [userTools, setUserTools] = React.useState([]);
+ const [selectedTool, setSelectedTool] = React.useState(null);
+
+ const getUserTools = () => {
+ userService
+ .getUserTools()
+ .then((res) => {
+ return res.json();
+ })
+ .then((data) => {
+ setUserTools(data.tools);
+ });
+ };
+
+ const updateToolStatus = (toolId: string, newStatus: boolean) => {
+ userService
+ .updateToolStatus({ id: toolId, status: newStatus })
+ .then(() => {
+ setUserTools((prevTools) =>
+ prevTools.map((tool) =>
+ tool.id === toolId ? { ...tool, status: newStatus } : tool,
+ ),
+ );
+ })
+ .catch((error) => {
+ console.error('Failed to update tool status:', error);
+ });
+ };
+
+ const handleSettingsClick = (tool: UserTool) => {
+ setSelectedTool(tool);
+ };
+
+ const handleGoBack = () => {
+ setSelectedTool(null);
+ getUserTools();
+ };
+
+ React.useEffect(() => {
+ getUserTools();
+ }, []);
+ return (
+
+ {selectedTool ? (
+
+ ) : (
+
+
+
+
+ setSearchTerm(e.target.value)}
+ />
+
+
+
+
+ {userTools
+ .filter((tool) =>
+ tool.displayName
+ .toLowerCase()
+ .includes(searchTerm.toLowerCase()),
+ )
+ .map((tool, index) => (
+
+
+
+ 
+
+
+
+
+ {tool.displayName}
+
+
+ {tool.description}
+
+
+
+
+
+
+
+ ))}
+
+
+
+
+ )}
+
+ );
+}
diff --git a/frontend/src/settings/index.tsx b/frontend/src/settings/index.tsx
index 15c7ce08..89f29a29 100644
--- a/frontend/src/settings/index.tsx
+++ b/frontend/src/settings/index.tsx
@@ -7,8 +7,8 @@ import SettingsBar from '../components/SettingsBar';
import i18n from '../locale/i18n';
import { Doc } from '../models/misc';
import {
- selectSourceDocs,
selectPaginatedDocuments,
+ selectSourceDocs,
setPaginatedDocuments,
setSourceDocs,
} from '../preferences/preferenceSlice';
@@ -17,6 +17,7 @@ import APIKeys from './APIKeys';
import Documents from './Documents';
import General from './General';
import Logs from './Logs';
+import Tools from './Tools';
import Widgets from './Widgets';
export default function Settings() {
@@ -100,6 +101,8 @@ export default function Settings() {
return ;
case t('settings.logs.label'):
return ;
+ case t('settings.tools.label'):
+ return ;
default:
return null;
}
diff --git a/frontend/src/settings/types/index.ts b/frontend/src/settings/types/index.ts
index 52a58f23..322bdfeb 100644
--- a/frontend/src/settings/types/index.ts
+++ b/frontend/src/settings/types/index.ts
@@ -18,3 +18,32 @@ export type LogData = {
retriever_params: Record;
timestamp: string;
};
+
+export type UserTool = {
+ id: string;
+ name: string;
+ displayName: string;
+ description: string;
+ status: boolean;
+ config: {
+ [key: string]: string;
+ };
+ actions: {
+ name: string;
+ description: string;
+ parameters: {
+ properties: {
+ [key: string]: {
+ type: string;
+ description: string;
+ filled_by_llm: boolean;
+ value: string;
+ };
+ };
+ additionalProperties: boolean;
+ required: string[];
+ type: string;
+ };
+ active: boolean;
+ }[];
+};
|