diff --git a/gui/package-lock.json b/gui/package-lock.json index ebb65645d..0225964cf 100644 --- a/gui/package-lock.json +++ b/gui/package-lock.json @@ -28,6 +28,7 @@ "react-grid-layout": "^1.3.4", "react-markdown": "^8.0.7", "react-spinners": "^0.13.8", + "react-tippy": "^1.4.0", "react-toastify": "^9.1.3" } }, @@ -3490,6 +3491,16 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/popper.js": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.16.1.tgz", + "integrity": "sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ==", + "deprecated": "You can find the new Popper v2 at @popperjs/core, this package is dedicated to the legacy v1", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/popperjs" + } + }, "node_modules/postcss": { "version": "8.4.14", "funding": [ @@ -3693,6 +3704,14 @@ "react-dom": "^16.0.0 || ^17.0.0 || ^18.0.0" } }, + "node_modules/react-tippy": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/react-tippy/-/react-tippy-1.4.0.tgz", + "integrity": "sha512-r/hM5XK9Ztr2ZY7IWKuRmISTlUPS/R6ddz6PO2EuxCgW+4JBcGZRPU06XcVPRDCOIiio8ryBQFrXMhFMhsuaHA==", + "dependencies": { + "popper.js": "^1.11.1" + } + }, "node_modules/react-toastify": { "version": "9.1.3", "license": "MIT", diff --git a/gui/package.json b/gui/package.json index f788aee8d..1246adca7 100644 --- a/gui/package.json +++ b/gui/package.json @@ -30,6 +30,7 @@ "react-grid-layout": "^1.3.4", "react-markdown": "^8.0.7", "react-spinners": "^0.13.8", + "react-tippy": "^1.4.0", "react-toastify": "^9.1.3" } } diff --git a/gui/pages/Content/APM/ApmDashboard.js b/gui/pages/Content/APM/ApmDashboard.js index 1459c7272..4a24fa3b5 100644 --- a/gui/pages/Content/APM/ApmDashboard.js +++ b/gui/pages/Content/APM/ApmDashboard.js @@ -8,6 +8,7 @@ import {BarGraph} from "./BarGraph.js"; import {WidthProvider, Responsive} from 'react-grid-layout'; import 'react-grid-layout/css/styles.css'; import 'react-resizable/css/styles.css'; +import { Tooltip } from 'react-tippy'; const ResponsiveGridLayout = WidthProvider(Responsive); @@ -97,6 +98,10 @@ export default function ApmDashboard() { return () => clearInterval(interval); }, []); + useEffect(() => { + console.log(toolsUsed) + }, [toolsUsed]); + const handleSelectedAgent = useCallback((index, name) => { setDropDown1(false) setDropDown2(false) @@ -279,14 +284,24 @@ export default function ApmDashboard() { ))} {run.tools_used && run.tools_used.length > 3 &&
- {(showToolTip && toolTipIndex === i) &&
- {run.tools_used.slice(3).map((tool,index) => -
{tool}
- )} -
} -
setToolTipState(true,i)} onMouseLeave={() => setToolTipState(false,i)}> - +{run.tools_used.length - 3} -
+ +
+ {run.tools_used.slice(3).map((tool,index) => +
{tool}
+ )} +
+ + } + > +
+ +{run.tools_used.length - 3} +
+
} diff --git a/gui/pages/Content/Toolkits/Metrics.js b/gui/pages/Content/Toolkits/Metrics.js index 0817cace6..27a0d3107 100644 --- a/gui/pages/Content/Toolkits/Metrics.js +++ b/gui/pages/Content/Toolkits/Metrics.js @@ -101,7 +101,7 @@ export default function Metrics({toolName, knowledgeName}) {
Call Logs - {callLogs.length > 0 ?
+ {callLogs.length > 0 ?
diff --git a/gui/pages/_app.css b/gui/pages/_app.css index f0100814c..e675693da 100644 --- a/gui/pages/_app.css +++ b/gui/pages/_app.css @@ -907,6 +907,11 @@ p { .fw_500{font-weight: 500;} +.br_4{border-radius: 4px} +.br_5{border-radius: 5px} +.br_6{border-radius: 6px} +.br_8{border-radius: 8px} + .text_9{ color: #FFF; font-family: Inter; @@ -1134,8 +1139,6 @@ p { .border_top_none{border-top: none;} .border_bottom_none{border-bottom: none;} .border_bottom_grey{border-bottom: 1px solid rgba(255, 255, 255, 0.08)} -.border_radius_8{border-radius: 8px;} -.border_radius_25{border-radius: 25px;} .bt_white{border-top: 1px solid rgba(255, 255, 255, 0.08);} @@ -1146,8 +1149,9 @@ p { .lh_17{line-height: 17px;} .lh_18{line-height: 18px;} -.padding_0{padding: 0} +.padding_0{padding: 0;} .padding_5{padding: 5px;} +.padding_6{padding: 6px;} .padding_8{padding: 8px;} .padding_10{padding: 10px;} .padding_12{padding: 12px;} @@ -1376,19 +1380,6 @@ tr{ margin: 2px; } -.tools_used_tooltip{ - position: absolute; - transform: translateX(-50%); - padding: 6px; - color: #fff; - font-size: 12px; - white-space: pre; - z-index: 100; - border-radius: 8px; - background: #2E293F; - margin-top: -40px; -} - .image_class{ background: #FFFFFF80; border-radius: 20px; @@ -1469,9 +1460,10 @@ tr{ } } -.bg_black{background: black} -.bg_white{background: white} -.bg_none{background: none} +.bg_black{background: black;} +.bg_white{background: white;} +.bg_none{background: none;} +.bg_primary{background: #2E293F;} .container { height: 100%; @@ -1885,3 +1877,8 @@ tr{ flex-direction: row; justify-content: center; } + +.tooltip-class { + background-color: green; + border-radius: 6px; +} diff --git a/superagi/agent/tool_executor.py b/superagi/agent/tool_executor.py index 017094164..303b8364a 100644 --- a/superagi/agent/tool_executor.py +++ b/superagi/agent/tool_executor.py @@ -32,7 +32,7 @@ def execute(self, session, tool_name, tool_args): status = "SUCCESS" tool = tools[tool_name] retry = False - EventHandler(session=session).create_event('tool_used', {'tool_name': tool_name, 'agent_execution_id': self.agent_execution_id}, self.agent_id, + EventHandler(session=session).create_event('tool_used', {'tool_name': tool.name, 'agent_execution_id': self.agent_execution_id}, self.agent_id, self.organisation_id), try: parsed_args = self.clean_tool_args(tool_args) diff --git a/superagi/apm/tools_handler.py b/superagi/apm/tools_handler.py index da3f97cc6..082b8062d 100644 --- a/superagi/apm/tools_handler.py +++ b/superagi/apm/tools_handler.py @@ -19,10 +19,10 @@ def __init__(self, session: Session, organisation_id: int): def get_tool_and_toolkit(self): tools_and_toolkits = self.session.query( - Tool.name.label('tool_name'), Toolkit.name.label('toolkit_name')).join( + func.lower(Tool.name).label('tool_name'), Toolkit.name.label('toolkit_name')).join( Toolkit, Tool.toolkit_id == Toolkit.id).all() - return {item.tool_name: item.toolkit_name for item in tools_and_toolkits} + return {item.tool_name.lower(): item.toolkit_name for item in tools_and_toolkits} def calculate_tool_usage(self) -> List[Dict[str, int]]: tool_usage = [] @@ -55,9 +55,11 @@ def calculate_tool_usage(self) -> List[Dict[str, int]]: 'tool_name': row.tool_name, 'unique_agents': row.unique_agents, 'total_usage': row.total_usage, - 'toolkit': tool_and_toolkit.get(row.tool_name, None) + 'toolkit': tool_and_toolkit.get(row.tool_name.lower(), None) } for row in result] + tool_usage.sort(key=lambda tool: tool['total_usage'], reverse=True) + return tool_usage def get_tool_usage_by_name(self, tool_name: str) -> Dict[str, Dict[str, int]]: diff --git a/tests/unit_tests/apm/test_tools_handler.py b/tests/unit_tests/apm/test_tools_handler.py index f805bbdf1..da13bca1e 100644 --- a/tests/unit_tests/apm/test_tools_handler.py +++ b/tests/unit_tests/apm/test_tools_handler.py @@ -27,31 +27,29 @@ def test_calculate_tool_usage(tools_handler, mock_session): tool_used_subquery.c.tool_name = 'Tool1' tool_used_subquery.c.agent_id = 1 - agent_count_subquery.c.tool_name = 'Tool1' agent_count_subquery.c.unique_agents = 1 - total_usage_subquery.c.tool_name = 'Tool1' total_usage_subquery.c.total_usage = 5 - tools_handler.get_tool_and_toolkit = MagicMock() - tools_handler.get_tool_and_toolkit.return_value = {'Tool1': 'Toolkit1'} - - mock_session.query().filter_by().subquery.return_value = tool_used_subquery - mock_session.query().group_by().subquery.return_value = agent_count_subquery - mock_session.query().group_by().subquery.return_value = total_usage_subquery + mock_session.query.return_value.filter_by.return_value.subquery.return_value = tool_used_subquery + mock_session.query.return_value.group_by.return_value.subquery.side_effect = [agent_count_subquery, total_usage_subquery] result_obj = MagicMock() result_obj.tool_name = 'Tool1' result_obj.unique_agents = 1 result_obj.total_usage = 5 - mock_session.query().join().all.return_value = [result_obj] + + mock_session.query.return_value.join.return_value.all.return_value = [result_obj] + + tools_handler.get_tool_and_toolkit = MagicMock(return_value={'tool1': 'Toolkit1'}) result = tools_handler.calculate_tool_usage() assert isinstance(result, list) expected_output = [{'tool_name': 'Tool1', 'unique_agents': 1, 'total_usage': 5, 'toolkit': 'Toolkit1'}] + assert result == expected_output def test_get_tool_and_toolkit(tools_handler, mock_session):