@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.
- package/README.md +1 -1
- package/lib/api.d.ts +3 -2
- package/lib/api.js +13 -2
- package/lib/chat-sidebar.d.ts +3 -1
- package/lib/chat-sidebar.js +366 -14
- package/lib/index.js +199 -1
- package/lib/tokens.d.ts +13 -0
- package/lib/tokens.js +5 -0
- package/package.json +1 -1
- package/src/api.ts +16 -1
- package/src/chat-sidebar.tsx +640 -19
- package/src/index.ts +252 -1
- package/src/tokens.ts +15 -0
- package/style/base.css +196 -3
package/src/chat-sidebar.tsx
CHANGED
|
@@ -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'
|
|
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
|
|
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
|
-
|
|
1366
|
-
<
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
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
|
|
2219
|
+
placeholder="Ask Notebook Intelligence to generate Python code..."
|
|
1599
2220
|
spellCheck={false}
|
|
1600
2221
|
value={prompt}
|
|
1601
2222
|
/>
|