@notebook-intelligence/notebook-intelligence 1.3.5 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -17,6 +17,7 @@ import * as monaco from 'monaco-editor/esm/vs/editor/editor.api.js';
17
17
  import { NBIAPI, GitHubCopilotLoginStatus } from './api';
18
18
  import {
19
19
  BackendMessageType,
20
+ BuiltinToolsetType,
20
21
  ContextType,
21
22
  GITHUB_COPILOT_PROVIDER_ID,
22
23
  IActiveDocumentInfo,
@@ -25,6 +26,7 @@ import {
25
26
  IChatParticipant,
26
27
  IContextItem,
27
28
  ITelemetryEmitter,
29
+ IToolSelections,
28
30
  RequestDataType,
29
31
  ResponseStreamDataType,
30
32
  TelemetryEventType
@@ -42,8 +44,15 @@ import {
42
44
  VscEyeClosed,
43
45
  VscTriangleRight,
44
46
  VscTriangleDown,
45
- VscWarning
47
+ VscWarning,
48
+ VscSettingsGear,
49
+ VscPassFilled,
50
+ VscTools,
51
+ VscTrash
46
52
  } from 'react-icons/vsc';
53
+
54
+ import { MdOutlineCheckBoxOutlineBlank, MdCheckBox } from 'react-icons/md';
55
+
47
56
  import { extractLLMGeneratedCode, isDarkTheme } from './utils';
48
57
 
49
58
  const OPENAI_COMPATIBLE_CHAT_MODEL_ID = 'openai-compatible-chat-model';
@@ -73,6 +82,8 @@ export interface IRunChatCompletionRequest {
73
82
  suffix?: string;
74
83
  existingCode?: string;
75
84
  additionalContext?: IContextItem[];
85
+ chatMode: string;
86
+ toolSelections?: IToolSelections;
76
87
  }
77
88
 
78
89
  export interface IChatSidebarOptions {
@@ -430,7 +441,9 @@ function ChatResponse(props: any) {
430
441
  </div>
431
442
  )}
432
443
  <div className="chat-message-from-title">
433
- {msg.from === 'user' ? 'User' : msg.participant?.name || 'Copilot'}
444
+ {msg.from === 'user'
445
+ ? 'User'
446
+ : msg.participant?.name || 'AI Assistant'}
434
447
  </div>
435
448
  <div
436
449
  className="chat-message-from-progress"
@@ -600,6 +613,8 @@ async function submitCompletionRequest(
600
613
  request.language || 'python',
601
614
  request.filename || 'Untitled.ipynb',
602
615
  request.additionalContext || [],
616
+ request.chatMode,
617
+ request.toolSelections || {},
603
618
  responseEmitter
604
619
  );
605
620
  case RunChatCompletionType.ExplainThis:
@@ -613,6 +628,8 @@ async function submitCompletionRequest(
613
628
  request.language || 'python',
614
629
  request.filename || 'Untitled.ipynb',
615
630
  [],
631
+ 'ask',
632
+ {},
616
633
  responseEmitter
617
634
  );
618
635
  }
@@ -630,6 +647,30 @@ async function submitCompletionRequest(
630
647
  }
631
648
  }
632
649
 
650
+ function CheckBoxItem(props: any) {
651
+ const indent = props.indent || 0;
652
+
653
+ return (
654
+ <div
655
+ className={`checkbox-item checkbox-item-indent-${indent} ${props.header ? 'checkbox-item-header' : ''}`}
656
+ title={props.title}
657
+ onClick={event => props.onClick(event)}
658
+ >
659
+ <div className="checkbox-item-toggle">
660
+ {props.checked ? (
661
+ <MdCheckBox className="checkbox-icon" />
662
+ ) : (
663
+ <MdOutlineCheckBoxOutlineBlank className="checkbox-icon" />
664
+ )}
665
+ {props.label}
666
+ </div>
667
+ {props.title && (
668
+ <div className="checkbox-item-description">{props.title}</div>
669
+ )}
670
+ </div>
671
+ );
672
+ }
673
+
633
674
  function SidebarComponent(props: any) {
634
675
  const [chatMessages, setChatMessages] = useState<IChatMessage[]>([]);
635
676
  const [prompt, setPrompt] = useState<string>('');
@@ -658,9 +699,375 @@ function SidebarComponent(props: any) {
658
699
  useState<IActiveDocumentInfo | null>(null);
659
700
  const [currentFileContextTitle, setCurrentFileContextTitle] = useState('');
660
701
  const telemetryEmitter: ITelemetryEmitter = props.getTelemetryEmitter();
702
+ const [chatMode, setChatMode] = useState('ask');
703
+ const [toolSelectionTitle, setToolSelectionTitle] =
704
+ useState('Tool selection');
705
+ const [selectedToolCount, setSelectedToolCount] = useState(0);
706
+ const [notebookExecuteToolSelected, setNotebookExecuteToolSelected] =
707
+ useState(false);
708
+ const [toolConfig, setToolConfig] = useState({
709
+ builtinToolsets: [
710
+ { id: BuiltinToolsetType.NotebookEdit, name: 'Notebook edit' },
711
+ { id: BuiltinToolsetType.NotebookExecute, name: 'Notebook execute' }
712
+ ],
713
+ mcpServers: [],
714
+ extensions: []
715
+ });
716
+ const [showModeTools, setShowModeTools] = useState(false);
717
+ const toolSelectionsInitial: any = {
718
+ builtinToolsets: [BuiltinToolsetType.NotebookEdit],
719
+ mcpServers: {},
720
+ extensions: {}
721
+ };
722
+ const toolSelectionsEmpty: any = {
723
+ builtinToolsets: [],
724
+ mcpServers: {},
725
+ extensions: {}
726
+ };
727
+ const [toolSelections, setToolSelections] = useState(toolSelectionsInitial);
728
+ const [hasExtensionTools, setHasExtensionTools] = useState(false);
729
+
730
+ NBIAPI.configChanged.connect(() => {
731
+ setToolConfig(NBIAPI.config.toolConfig);
732
+ });
733
+
734
+ useEffect(() => {
735
+ let hasTools = false;
736
+ for (const extension of toolConfig.extensions) {
737
+ if (extension.toolsets.length > 0) {
738
+ hasTools = true;
739
+ break;
740
+ }
741
+ }
742
+ setHasExtensionTools(hasTools);
743
+ }, [toolConfig]);
744
+
745
+ useEffect(() => {
746
+ const builtinToolSelCount = toolSelections.builtinToolsets.length;
747
+ let mcpServerToolSelCount = 0;
748
+ let extensionToolSelCount = 0;
749
+
750
+ for (const serverId in toolSelections.mcpServers) {
751
+ const mcpServerTools = toolSelections.mcpServers[serverId];
752
+ mcpServerToolSelCount += mcpServerTools.length;
753
+ }
754
+
755
+ for (const extensionId in toolSelections.extensions) {
756
+ const extensionToolsets = toolSelections.extensions[extensionId];
757
+ for (const toolsetId in extensionToolsets) {
758
+ const toolsetTools = extensionToolsets[toolsetId];
759
+ extensionToolSelCount += toolsetTools.length;
760
+ }
761
+ }
762
+
763
+ const typeCounts = [];
764
+ if (builtinToolSelCount > 0) {
765
+ typeCounts.push(`${builtinToolSelCount} built-in`);
766
+ }
767
+ if (mcpServerToolSelCount > 0) {
768
+ typeCounts.push(`${mcpServerToolSelCount} mcp`);
769
+ }
770
+ if (extensionToolSelCount > 0) {
771
+ typeCounts.push(`${extensionToolSelCount} ext`);
772
+ }
773
+
774
+ setSelectedToolCount(
775
+ builtinToolSelCount + mcpServerToolSelCount + extensionToolSelCount
776
+ );
777
+ setNotebookExecuteToolSelected(
778
+ toolSelections.builtinToolsets.includes(
779
+ BuiltinToolsetType.NotebookExecute
780
+ )
781
+ );
782
+ setToolSelectionTitle(
783
+ typeCounts.length === 0
784
+ ? 'Tool selection'
785
+ : `Tool selection (${typeCounts.join(', ')})`
786
+ );
787
+ }, [toolSelections]);
788
+
789
+ const onClearToolsButtonClicked = () => {
790
+ setToolSelections(toolSelectionsEmpty);
791
+ };
792
+
793
+ const getBuiltinToolsetState = (toolsetName: string): boolean => {
794
+ return toolSelections.builtinToolsets.includes(toolsetName);
795
+ };
796
+
797
+ const setBuiltinToolsetState = (toolsetName: string, enabled: boolean) => {
798
+ const newConfig = { ...toolSelections };
799
+ if (enabled) {
800
+ if (!toolSelections.builtinToolsets.includes(toolsetName)) {
801
+ newConfig.builtinToolsets.push(toolsetName);
802
+ }
803
+ } else {
804
+ const index = newConfig.builtinToolsets.indexOf(toolsetName);
805
+ if (index !== -1) {
806
+ newConfig.builtinToolsets.splice(index, 1);
807
+ }
808
+ }
809
+ setToolSelections(newConfig);
810
+ };
811
+
812
+ const anyMCPServerToolSelected = (id: string) => {
813
+ if (!(id in toolSelections.mcpServers)) {
814
+ return false;
815
+ }
816
+
817
+ return toolSelections.mcpServers[id].length > 0;
818
+ };
819
+
820
+ const getMCPServerState = (id: string): boolean => {
821
+ if (!(id in toolSelections.mcpServers)) {
822
+ return false;
823
+ }
824
+
825
+ const mcpServer = toolConfig.mcpServers.find(server => server.id === id);
826
+
827
+ const selectedServerTools: string[] = toolSelections.mcpServers[id];
828
+
829
+ for (const tool of mcpServer.tools) {
830
+ if (!selectedServerTools.includes(tool.name)) {
831
+ return false;
832
+ }
833
+ }
834
+
835
+ return true;
836
+ };
837
+
838
+ const onMCPServerClicked = (id: string) => {
839
+ if (anyMCPServerToolSelected(id)) {
840
+ const newConfig = { ...toolSelections };
841
+ delete newConfig.mcpServers[id];
842
+ setToolSelections(newConfig);
843
+ } else {
844
+ const mcpServer = toolConfig.mcpServers.find(server => server.id === id);
845
+ const newConfig = { ...toolSelections };
846
+ newConfig.mcpServers[id] = structuredClone(
847
+ mcpServer.tools.map((tool: any) => tool.name)
848
+ );
849
+ setToolSelections(newConfig);
850
+ }
851
+ };
852
+
853
+ const getMCPServerToolState = (serverId: string, toolId: string): boolean => {
854
+ if (!(serverId in toolSelections.mcpServers)) {
855
+ return false;
856
+ }
857
+
858
+ const selectedServerTools: string[] = toolSelections.mcpServers[serverId];
859
+
860
+ return selectedServerTools.includes(toolId);
861
+ };
862
+
863
+ const setMCPServerToolState = (
864
+ serverId: string,
865
+ toolId: string,
866
+ checked: boolean
867
+ ) => {
868
+ const newConfig = { ...toolSelections };
869
+
870
+ if (checked && !(serverId in newConfig.mcpServers)) {
871
+ newConfig.mcpServers[serverId] = [];
872
+ }
873
+
874
+ const selectedServerTools: string[] = newConfig.mcpServers[serverId];
875
+
876
+ if (checked) {
877
+ selectedServerTools.push(toolId);
878
+ } else {
879
+ const index = selectedServerTools.indexOf(toolId);
880
+ if (index !== -1) {
881
+ selectedServerTools.splice(index, 1);
882
+ }
883
+ }
884
+
885
+ setToolSelections(newConfig);
886
+ };
887
+
888
+ // all toolsets and tools of the extension are selected
889
+ const getExtensionState = (extensionId: string): boolean => {
890
+ if (!(extensionId in toolSelections.extensions)) {
891
+ return false;
892
+ }
893
+
894
+ const extension = toolConfig.extensions.find(
895
+ extension => extension.id === extensionId
896
+ );
897
+
898
+ for (const toolset of extension.toolsets) {
899
+ if (!getExtensionToolsetState(extensionId, toolset.id)) {
900
+ return false;
901
+ }
902
+ }
903
+
904
+ return true;
905
+ };
906
+
907
+ const getExtensionToolsetState = (
908
+ extensionId: string,
909
+ toolsetId: string
910
+ ): boolean => {
911
+ if (!(extensionId in toolSelections.extensions)) {
912
+ return false;
913
+ }
914
+
915
+ if (!(toolsetId in toolSelections.extensions[extensionId])) {
916
+ return false;
917
+ }
918
+
919
+ const extension = toolConfig.extensions.find(ext => ext.id === extensionId);
920
+ const extensionToolset = extension.toolsets.find(
921
+ (toolset: any) => toolset.id === toolsetId
922
+ );
923
+
924
+ const selectedToolsetTools: string[] =
925
+ toolSelections.extensions[extensionId][toolsetId];
926
+
927
+ for (const tool of extensionToolset.tools) {
928
+ if (!selectedToolsetTools.includes(tool)) {
929
+ return false;
930
+ }
931
+ }
932
+
933
+ return true;
934
+ };
935
+
936
+ const anyExtensionToolsetSelected = (extensionId: string) => {
937
+ if (!(extensionId in toolSelections.extensions)) {
938
+ return false;
939
+ }
940
+
941
+ return Object.keys(toolSelections.extensions[extensionId]).length > 0;
942
+ };
943
+
944
+ const onExtensionClicked = (extensionId: string) => {
945
+ if (anyExtensionToolsetSelected(extensionId)) {
946
+ const newConfig = { ...toolSelections };
947
+ delete newConfig.extensions[extensionId];
948
+ setToolSelections(newConfig);
949
+ } else {
950
+ const newConfig = { ...toolSelections };
951
+ const extension = toolConfig.extensions.find(
952
+ ext => ext.id === extensionId
953
+ );
954
+ if (extensionId in newConfig.extensions) {
955
+ delete newConfig.extensions[extensionId];
956
+ }
957
+ newConfig.extensions[extensionId] = {};
958
+ for (const toolset of extension.toolsets) {
959
+ newConfig.extensions[extensionId][toolset.id] = structuredClone(
960
+ toolset.tools
961
+ );
962
+ }
963
+ setToolSelections(newConfig);
964
+ }
965
+ };
966
+
967
+ const anyExtensionToolsetToolSelected = (
968
+ extensionId: string,
969
+ toolsetId: string
970
+ ) => {
971
+ if (!(extensionId in toolSelections.extensions)) {
972
+ return false;
973
+ }
974
+
975
+ if (!(toolsetId in toolSelections.extensions[extensionId])) {
976
+ return false;
977
+ }
978
+
979
+ return toolSelections.extensions[extensionId][toolsetId].length > 0;
980
+ };
981
+
982
+ const onExtensionToolsetClicked = (
983
+ extensionId: string,
984
+ toolsetId: string
985
+ ) => {
986
+ if (anyExtensionToolsetToolSelected(extensionId, toolsetId)) {
987
+ const newConfig = { ...toolSelections };
988
+ if (toolsetId in newConfig.extensions[extensionId]) {
989
+ delete newConfig.extensions[extensionId][toolsetId];
990
+ }
991
+ setToolSelections(newConfig);
992
+ } else {
993
+ const extension = toolConfig.extensions.find(
994
+ ext => ext.id === extensionId
995
+ );
996
+ const extensionToolset = extension.toolsets.find(
997
+ (toolset: any) => toolset.id === toolsetId
998
+ );
999
+ const newConfig = { ...toolSelections };
1000
+ if (!(extensionId in newConfig.extensions)) {
1001
+ newConfig.extensions[extensionId] = {};
1002
+ }
1003
+ newConfig.extensions[extensionId][toolsetId] = structuredClone(
1004
+ extensionToolset.tools
1005
+ );
1006
+ setToolSelections(newConfig);
1007
+ }
1008
+ };
1009
+
1010
+ const getExtensionToolsetToolState = (
1011
+ extensionId: string,
1012
+ toolsetId: string,
1013
+ toolId: string
1014
+ ): boolean => {
1015
+ if (!(extensionId in toolSelections.extensions)) {
1016
+ return false;
1017
+ }
1018
+
1019
+ const selectedExtensionToolsets: any =
1020
+ toolSelections.extensions[extensionId];
1021
+
1022
+ if (!(toolsetId in selectedExtensionToolsets)) {
1023
+ return false;
1024
+ }
1025
+
1026
+ const selectedServerTools: string[] = selectedExtensionToolsets[toolsetId];
1027
+
1028
+ return selectedServerTools.includes(toolId);
1029
+ };
1030
+
1031
+ const setExtensionToolsetToolState = (
1032
+ extensionId: string,
1033
+ toolsetId: string,
1034
+ toolId: string,
1035
+ checked: boolean
1036
+ ) => {
1037
+ const newConfig = { ...toolSelections };
1038
+
1039
+ if (checked && !(extensionId in newConfig.extensions)) {
1040
+ newConfig.extensions[extensionId] = {};
1041
+ }
1042
+
1043
+ if (checked && !(toolsetId in newConfig.extensions[extensionId])) {
1044
+ newConfig.extensions[extensionId][toolsetId] = [];
1045
+ }
1046
+
1047
+ const selectedTools: string[] =
1048
+ newConfig.extensions[extensionId][toolsetId];
1049
+
1050
+ if (checked) {
1051
+ selectedTools.push(toolId);
1052
+ } else {
1053
+ const index = selectedTools.indexOf(toolId);
1054
+ if (index !== -1) {
1055
+ selectedTools.splice(index, 1);
1056
+ }
1057
+ }
1058
+
1059
+ setToolSelections(newConfig);
1060
+ };
661
1061
 
662
1062
  useEffect(() => {
663
1063
  const prefixes: string[] = [];
1064
+ if (chatMode !== 'ask') {
1065
+ prefixes.push('/clear');
1066
+ setOriginalPrefixes(prefixes);
1067
+ setPrefixSuggestions(prefixes);
1068
+ return;
1069
+ }
1070
+
664
1071
  const chatParticipants = NBIAPI.config.chatParticipants;
665
1072
  for (const participant of chatParticipants) {
666
1073
  const id = participant.id;
@@ -677,7 +1084,7 @@ function SidebarComponent(props: any) {
677
1084
  }
678
1085
  setOriginalPrefixes(prefixes);
679
1086
  setPrefixSuggestions(prefixes);
680
- }, []);
1087
+ }, [chatMode]);
681
1088
 
682
1089
  useEffect(() => {
683
1090
  const fetchData = () => {
@@ -730,6 +1137,7 @@ function SidebarComponent(props: any) {
730
1137
  };
731
1138
 
732
1139
  const handleSubmitStopChatButtonClick = async () => {
1140
+ setShowModeTools(false);
733
1141
  if (!copilotRequestInProgress) {
734
1142
  handleUserInputSubmit();
735
1143
  } else {
@@ -737,6 +1145,20 @@ function SidebarComponent(props: any) {
737
1145
  }
738
1146
  };
739
1147
 
1148
+ const handleSettingsButtonClick = async () => {
1149
+ setShowModeTools(false);
1150
+ props
1151
+ .getApp()
1152
+ .commands.execute('notebook-intelligence:open-configuration-dialog');
1153
+ };
1154
+
1155
+ const handleChatToolsButtonClick = async () => {
1156
+ if (!showModeTools) {
1157
+ NBIAPI.fetchCapabilities();
1158
+ }
1159
+ setShowModeTools(!showModeTools);
1160
+ };
1161
+
740
1162
  const handleUserInputSubmit = async () => {
741
1163
  setPromptHistoryIndex(promptHistory.length + 1);
742
1164
  setPromptHistory([...promptHistory, prompt]);
@@ -828,7 +1250,9 @@ function SidebarComponent(props: any) {
828
1250
  content: extractedPrompt,
829
1251
  language: activeDocInfo.language,
830
1252
  filename: activeDocInfo.filename,
831
- additionalContext
1253
+ additionalContext,
1254
+ chatMode,
1255
+ toolSelections: toolSelections
832
1256
  },
833
1257
  {
834
1258
  emit: async response => {
@@ -986,6 +1410,7 @@ function SidebarComponent(props: any) {
986
1410
  event.stopPropagation();
987
1411
  event.preventDefault();
988
1412
  setShowPopover(false);
1413
+ setShowModeTools(false);
989
1414
  setSelectedPrefixSuggestionIndex(0);
990
1415
  } else if (event.key === 'ArrowUp') {
991
1416
  event.stopPropagation();
@@ -1260,6 +1685,12 @@ function SidebarComponent(props: any) {
1260
1685
  <div className="sidebar">
1261
1686
  <div className="sidebar-header">
1262
1687
  <div className="sidebar-title">Notebook Intelligence</div>
1688
+ <div
1689
+ className="user-input-footer-button"
1690
+ onClick={() => handleSettingsButtonClick()}
1691
+ >
1692
+ <VscSettingsGear />
1693
+ </div>
1263
1694
  </div>
1264
1695
  {!chatEnabled && !ghLoginRequired && (
1265
1696
  <div className="sidebar-login-info">
@@ -1333,7 +1764,7 @@ function SidebarComponent(props: any) {
1333
1764
  rows={3}
1334
1765
  onChange={onPromptChange}
1335
1766
  onKeyDown={onPromptKeyDown}
1336
- placeholder="Ask Copilot..."
1767
+ placeholder="Ask Notebook Intelligence..."
1337
1768
  spellCheck={false}
1338
1769
  value={prompt}
1339
1770
  />
@@ -1362,19 +1793,56 @@ function SidebarComponent(props: any) {
1362
1793
  </div>
1363
1794
  )}
1364
1795
  <div className="user-input-footer">
1365
- <div>
1366
- <a
1367
- href="javascript:void(0)"
1368
- onClick={() => {
1369
- setShowPopover(true);
1370
- promptInputRef.current?.focus();
1371
- }}
1372
- title="Select chat participant"
1373
- >
1374
- @
1375
- </a>
1376
- </div>
1796
+ {chatMode === 'ask' && (
1797
+ <div>
1798
+ <a
1799
+ href="javascript:void(0)"
1800
+ onClick={() => {
1801
+ setShowPopover(true);
1802
+ promptInputRef.current?.focus();
1803
+ }}
1804
+ title="Select chat participant"
1805
+ >
1806
+ @
1807
+ </a>
1808
+ </div>
1809
+ )}
1377
1810
  <div style={{ flexGrow: 1 }}></div>
1811
+ <div className="chat-mode-widgets-container">
1812
+ <div>
1813
+ <select
1814
+ className="chat-mode-select"
1815
+ title="Chat mode"
1816
+ value={chatMode}
1817
+ onChange={event => {
1818
+ if (event.target.value === 'ask') {
1819
+ setToolSelections(toolSelectionsEmpty);
1820
+ } else if (event.target.value === 'agent') {
1821
+ setToolSelections(toolSelectionsInitial);
1822
+ }
1823
+ setShowModeTools(false);
1824
+ setChatMode(event.target.value);
1825
+ }}
1826
+ >
1827
+ <option value="ask">Ask</option>
1828
+ <option value="agent">Agent</option>
1829
+ </select>
1830
+ </div>
1831
+ {chatMode !== 'ask' && (
1832
+ <div
1833
+ className={`user-input-footer-button tools-button ${notebookExecuteToolSelected ? 'tools-button-warning' : selectedToolCount > 0 ? 'tools-button-active' : ''}`}
1834
+ onClick={() => handleChatToolsButtonClick()}
1835
+ title={
1836
+ notebookExecuteToolSelected
1837
+ ? `Notebook execute tool selected!\n${toolSelectionTitle}`
1838
+ : toolSelectionTitle
1839
+ }
1840
+ >
1841
+ <VscTools />
1842
+ {selectedToolCount > 0 && <>{selectedToolCount}</>}
1843
+ </div>
1844
+ )}
1845
+ </div>
1378
1846
  <div>
1379
1847
  <button
1380
1848
  className="jp-Dialog-button jp-mod-accept jp-mod-styled send-button"
@@ -1399,6 +1867,158 @@ function SidebarComponent(props: any) {
1399
1867
  ))}
1400
1868
  </div>
1401
1869
  )}
1870
+ {showModeTools && (
1871
+ <div
1872
+ className="mode-tools-popover"
1873
+ tabIndex={1}
1874
+ autoFocus={true}
1875
+ onKeyDown={(event: KeyboardEvent<HTMLDivElement>) => {
1876
+ if (event.key === 'Escape' || event.key === 'Enter') {
1877
+ event.stopPropagation();
1878
+ event.preventDefault();
1879
+ setShowModeTools(false);
1880
+ }
1881
+ }}
1882
+ >
1883
+ <div className="mode-tools-popover-header">
1884
+ <div className="mode-tools-popover-header-icon">
1885
+ <VscTools />
1886
+ </div>
1887
+ <div className="mode-tools-popover-title">
1888
+ {toolSelectionTitle}
1889
+ </div>
1890
+ <div
1891
+ className="mode-tools-popover-clear-tools-button"
1892
+ style={{
1893
+ visibility: selectedToolCount > 0 ? 'visible' : 'hidden'
1894
+ }}
1895
+ >
1896
+ <div>
1897
+ <VscTrash />
1898
+ </div>
1899
+ <div>
1900
+ <a
1901
+ href="javascript:void(0);"
1902
+ onClick={onClearToolsButtonClicked}
1903
+ >
1904
+ clear
1905
+ </a>
1906
+ </div>
1907
+ </div>
1908
+ <div
1909
+ className="mode-tools-popover-close-button"
1910
+ onClick={() => setShowModeTools(false)}
1911
+ >
1912
+ {/* <button
1913
+ className="jp-Dialog-button jp-mod-accept jp-mod-styled send-button"
1914
+ > */}
1915
+ <div>
1916
+ <VscPassFilled />
1917
+ </div>
1918
+ {/* </button> */}
1919
+ <div>Done</div>
1920
+ </div>
1921
+ </div>
1922
+ <div className="mode-tools-popover-tool-list">
1923
+ <div className="mode-tools-group-header">Built-in</div>
1924
+ <div className="mode-tools-group mode-tools-group-built-in">
1925
+ {toolConfig.builtinToolsets.map((toolset: any) => (
1926
+ <CheckBoxItem
1927
+ key={toolset.id}
1928
+ label={toolset.name}
1929
+ checked={getBuiltinToolsetState(toolset.id)}
1930
+ header={true}
1931
+ onClick={() => {
1932
+ setBuiltinToolsetState(
1933
+ toolset.id,
1934
+ !getBuiltinToolsetState(toolset.id)
1935
+ );
1936
+ }}
1937
+ />
1938
+ ))}
1939
+ </div>
1940
+ {toolConfig.mcpServers.length > 0 && (
1941
+ <div className="mode-tools-group-header">MCP Servers</div>
1942
+ )}
1943
+ {toolConfig.mcpServers.map((mcpServer, index: number) => (
1944
+ <div className="mode-tools-group">
1945
+ <CheckBoxItem
1946
+ label={mcpServer.id}
1947
+ header={true}
1948
+ checked={getMCPServerState(mcpServer.id)}
1949
+ onClick={() => onMCPServerClicked(mcpServer.id)}
1950
+ />
1951
+ {mcpServer.tools.map((tool: any, index: number) => (
1952
+ <CheckBoxItem
1953
+ label={tool.name}
1954
+ title={tool.description}
1955
+ indent={1}
1956
+ checked={getMCPServerToolState(mcpServer.id, tool.name)}
1957
+ onClick={() =>
1958
+ setMCPServerToolState(
1959
+ mcpServer.id,
1960
+ tool.name,
1961
+ !getMCPServerToolState(mcpServer.id, tool.name)
1962
+ )
1963
+ }
1964
+ />
1965
+ ))}
1966
+ </div>
1967
+ ))}
1968
+ {hasExtensionTools && (
1969
+ <div className="mode-tools-group-header">Extension tools</div>
1970
+ )}
1971
+ {toolConfig.extensions.map((extension, index: number) => (
1972
+ <div className="mode-tools-group">
1973
+ <CheckBoxItem
1974
+ label={`${extension.name} (${extension.id})`}
1975
+ header={true}
1976
+ checked={getExtensionState(extension.id)}
1977
+ onClick={() => onExtensionClicked(extension.id)}
1978
+ />
1979
+ {extension.toolsets.map((toolset: any, index: number) => (
1980
+ <>
1981
+ <CheckBoxItem
1982
+ label={`${toolset.name} (${toolset.id})`}
1983
+ indent={1}
1984
+ checked={getExtensionToolsetState(
1985
+ extension.id,
1986
+ toolset.id
1987
+ )}
1988
+ onClick={() =>
1989
+ onExtensionToolsetClicked(extension.id, toolset.id)
1990
+ }
1991
+ />
1992
+ {toolset.tools.map((tool: any, index: number) => (
1993
+ <CheckBoxItem
1994
+ label={tool}
1995
+ indent={2}
1996
+ checked={getExtensionToolsetToolState(
1997
+ extension.id,
1998
+ toolset.id,
1999
+ tool
2000
+ )}
2001
+ onClick={() =>
2002
+ setExtensionToolsetToolState(
2003
+ extension.id,
2004
+ toolset.id,
2005
+ tool,
2006
+ !getExtensionToolsetToolState(
2007
+ extension.id,
2008
+ toolset.id,
2009
+ tool
2010
+ )
2011
+ )
2012
+ }
2013
+ />
2014
+ ))}
2015
+ </>
2016
+ ))}
2017
+ </div>
2018
+ ))}
2019
+ </div>
2020
+ </div>
2021
+ )}
1402
2022
  </div>
1403
2023
  )}
1404
2024
  </div>
@@ -1548,7 +2168,8 @@ function InlinePromptComponent(props: any) {
1548
2168
  filename: undefined,
1549
2169
  prefix: props.prefix,
1550
2170
  suffix: props.suffix,
1551
- existingCode: props.existingCode
2171
+ existingCode: props.existingCode,
2172
+ chatMode: 'ask'
1552
2173
  },
1553
2174
  {
1554
2175
  emit: async response => {
@@ -1595,7 +2216,7 @@ function InlinePromptComponent(props: any) {
1595
2216
  rows={3}
1596
2217
  onChange={onPromptChange}
1597
2218
  onKeyDown={onPromptKeyDown}
1598
- placeholder="Ask Copilot to generate Python code..."
2219
+ placeholder="Ask Notebook Intelligence to generate Python code..."
1599
2220
  spellCheck={false}
1600
2221
  value={prompt}
1601
2222
  />