@notebook-intelligence/notebook-intelligence 1.3.4 → 2.0.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 +365 -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 +630 -19
- package/src/index.ts +252 -1
- package/src/tokens.ts +15 -0
- package/style/base.css +167 -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,26 @@ async function submitCompletionRequest(
|
|
|
630
647
|
}
|
|
631
648
|
}
|
|
632
649
|
|
|
650
|
+
function CheckBoxItem(props: any) {
|
|
651
|
+
const indent = props.indent || 0;
|
|
652
|
+
|
|
653
|
+
return (
|
|
654
|
+
<>
|
|
655
|
+
<div
|
|
656
|
+
className={`checkbox-item checkbox-item-indent-${indent}`}
|
|
657
|
+
onClick={event => props.onClick(event)}
|
|
658
|
+
>
|
|
659
|
+
{props.checked ? (
|
|
660
|
+
<MdCheckBox className="checkbox-icon" />
|
|
661
|
+
) : (
|
|
662
|
+
<MdOutlineCheckBoxOutlineBlank className="checkbox-icon" />
|
|
663
|
+
)}
|
|
664
|
+
{props.label}
|
|
665
|
+
</div>
|
|
666
|
+
</>
|
|
667
|
+
);
|
|
668
|
+
}
|
|
669
|
+
|
|
633
670
|
function SidebarComponent(props: any) {
|
|
634
671
|
const [chatMessages, setChatMessages] = useState<IChatMessage[]>([]);
|
|
635
672
|
const [prompt, setPrompt] = useState<string>('');
|
|
@@ -658,9 +695,373 @@ function SidebarComponent(props: any) {
|
|
|
658
695
|
useState<IActiveDocumentInfo | null>(null);
|
|
659
696
|
const [currentFileContextTitle, setCurrentFileContextTitle] = useState('');
|
|
660
697
|
const telemetryEmitter: ITelemetryEmitter = props.getTelemetryEmitter();
|
|
698
|
+
const [chatMode, setChatMode] = useState('ask');
|
|
699
|
+
const [toolSelectionTitle, setToolSelectionTitle] =
|
|
700
|
+
useState('Tool selection');
|
|
701
|
+
const [selectedToolCount, setSelectedToolCount] = useState(0);
|
|
702
|
+
const [notebookExecuteToolSelected, setNotebookExecuteToolSelected] =
|
|
703
|
+
useState(false);
|
|
704
|
+
const [toolConfig, setToolConfig] = useState({
|
|
705
|
+
builtinToolsets: [
|
|
706
|
+
{ id: BuiltinToolsetType.NotebookEdit, name: 'Notebook edit' },
|
|
707
|
+
{ id: BuiltinToolsetType.NotebookExecute, name: 'Notebook execute' }
|
|
708
|
+
],
|
|
709
|
+
mcpServers: [],
|
|
710
|
+
extensions: []
|
|
711
|
+
});
|
|
712
|
+
const [showModeTools, setShowModeTools] = useState(false);
|
|
713
|
+
const toolSelectionsInitial: any = {
|
|
714
|
+
builtinToolsets: [BuiltinToolsetType.NotebookEdit],
|
|
715
|
+
mcpServers: {},
|
|
716
|
+
extensions: {}
|
|
717
|
+
};
|
|
718
|
+
const toolSelectionsEmpty: any = {
|
|
719
|
+
builtinToolsets: [],
|
|
720
|
+
mcpServers: {},
|
|
721
|
+
extensions: {}
|
|
722
|
+
};
|
|
723
|
+
const [toolSelections, setToolSelections] = useState(toolSelectionsInitial);
|
|
724
|
+
const [hasExtensionTools, setHasExtensionTools] = useState(false);
|
|
725
|
+
|
|
726
|
+
NBIAPI.configChanged.connect(() => {
|
|
727
|
+
setToolConfig(NBIAPI.config.toolConfig);
|
|
728
|
+
});
|
|
729
|
+
|
|
730
|
+
useEffect(() => {
|
|
731
|
+
let hasTools = false;
|
|
732
|
+
for (const extension of toolConfig.extensions) {
|
|
733
|
+
if (extension.toolsets.length > 0) {
|
|
734
|
+
hasTools = true;
|
|
735
|
+
break;
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
setHasExtensionTools(hasTools);
|
|
739
|
+
}, [toolConfig]);
|
|
740
|
+
|
|
741
|
+
useEffect(() => {
|
|
742
|
+
const builtinToolSelCount = toolSelections.builtinToolsets.length;
|
|
743
|
+
let mcpServerToolSelCount = 0;
|
|
744
|
+
let extensionToolSelCount = 0;
|
|
745
|
+
|
|
746
|
+
for (const serverId in toolSelections.mcpServers) {
|
|
747
|
+
const mcpServerTools = toolSelections.mcpServers[serverId];
|
|
748
|
+
mcpServerToolSelCount += mcpServerTools.length;
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
for (const extensionId in toolSelections.extensions) {
|
|
752
|
+
const extensionToolsets = toolSelections.extensions[extensionId];
|
|
753
|
+
for (const toolsetId in extensionToolsets) {
|
|
754
|
+
const toolsetTools = extensionToolsets[toolsetId];
|
|
755
|
+
extensionToolSelCount += toolsetTools.length;
|
|
756
|
+
}
|
|
757
|
+
}
|
|
758
|
+
|
|
759
|
+
const typeCounts = [];
|
|
760
|
+
if (builtinToolSelCount > 0) {
|
|
761
|
+
typeCounts.push(`${builtinToolSelCount} built-in`);
|
|
762
|
+
}
|
|
763
|
+
if (mcpServerToolSelCount > 0) {
|
|
764
|
+
typeCounts.push(`${mcpServerToolSelCount} mcp`);
|
|
765
|
+
}
|
|
766
|
+
if (extensionToolSelCount > 0) {
|
|
767
|
+
typeCounts.push(`${extensionToolSelCount} ext`);
|
|
768
|
+
}
|
|
769
|
+
|
|
770
|
+
setSelectedToolCount(
|
|
771
|
+
builtinToolSelCount + mcpServerToolSelCount + extensionToolSelCount
|
|
772
|
+
);
|
|
773
|
+
setNotebookExecuteToolSelected(
|
|
774
|
+
toolSelections.builtinToolsets.includes(
|
|
775
|
+
BuiltinToolsetType.NotebookExecute
|
|
776
|
+
)
|
|
777
|
+
);
|
|
778
|
+
setToolSelectionTitle(
|
|
779
|
+
typeCounts.length === 0
|
|
780
|
+
? 'Tool selection'
|
|
781
|
+
: `Tool selection (${typeCounts.join(', ')})`
|
|
782
|
+
);
|
|
783
|
+
}, [toolSelections]);
|
|
784
|
+
|
|
785
|
+
const onClearToolsButtonClicked = () => {
|
|
786
|
+
setToolSelections(toolSelectionsEmpty);
|
|
787
|
+
};
|
|
788
|
+
|
|
789
|
+
const getBuiltinToolsetState = (toolsetName: string): boolean => {
|
|
790
|
+
return toolSelections.builtinToolsets.includes(toolsetName);
|
|
791
|
+
};
|
|
792
|
+
|
|
793
|
+
const setBuiltinToolsetState = (toolsetName: string, enabled: boolean) => {
|
|
794
|
+
const newConfig = { ...toolSelections };
|
|
795
|
+
if (enabled) {
|
|
796
|
+
if (!toolSelections.builtinToolsets.includes(toolsetName)) {
|
|
797
|
+
newConfig.builtinToolsets.push(toolsetName);
|
|
798
|
+
}
|
|
799
|
+
} else {
|
|
800
|
+
const index = newConfig.builtinToolsets.indexOf(toolsetName);
|
|
801
|
+
if (index !== -1) {
|
|
802
|
+
newConfig.builtinToolsets.splice(index, 1);
|
|
803
|
+
}
|
|
804
|
+
}
|
|
805
|
+
setToolSelections(newConfig);
|
|
806
|
+
};
|
|
807
|
+
|
|
808
|
+
const anyMCPServerToolSelected = (id: string) => {
|
|
809
|
+
if (!(id in toolSelections.mcpServers)) {
|
|
810
|
+
return false;
|
|
811
|
+
}
|
|
812
|
+
|
|
813
|
+
return toolSelections.mcpServers[id].length > 0;
|
|
814
|
+
};
|
|
815
|
+
|
|
816
|
+
const getMCPServerState = (id: string): boolean => {
|
|
817
|
+
if (!(id in toolSelections.mcpServers)) {
|
|
818
|
+
return false;
|
|
819
|
+
}
|
|
820
|
+
|
|
821
|
+
const mcpServer = toolConfig.mcpServers.find(server => server.id === id);
|
|
822
|
+
|
|
823
|
+
const selectedServerTools: string[] = toolSelections.mcpServers[id];
|
|
824
|
+
|
|
825
|
+
for (const tool of mcpServer.tools) {
|
|
826
|
+
if (!selectedServerTools.includes(tool)) {
|
|
827
|
+
return false;
|
|
828
|
+
}
|
|
829
|
+
}
|
|
830
|
+
|
|
831
|
+
return true;
|
|
832
|
+
};
|
|
833
|
+
|
|
834
|
+
const onMCPServerClicked = (id: string) => {
|
|
835
|
+
if (anyMCPServerToolSelected(id)) {
|
|
836
|
+
const newConfig = { ...toolSelections };
|
|
837
|
+
delete newConfig.mcpServers[id];
|
|
838
|
+
setToolSelections(newConfig);
|
|
839
|
+
} else {
|
|
840
|
+
const mcpServer = toolConfig.mcpServers.find(server => server.id === id);
|
|
841
|
+
const newConfig = { ...toolSelections };
|
|
842
|
+
newConfig.mcpServers[id] = structuredClone(mcpServer.tools);
|
|
843
|
+
setToolSelections(newConfig);
|
|
844
|
+
}
|
|
845
|
+
};
|
|
846
|
+
|
|
847
|
+
const getMCPServerToolState = (serverId: string, toolId: string): boolean => {
|
|
848
|
+
if (!(serverId in toolSelections.mcpServers)) {
|
|
849
|
+
return false;
|
|
850
|
+
}
|
|
851
|
+
|
|
852
|
+
const selectedServerTools: string[] = toolSelections.mcpServers[serverId];
|
|
853
|
+
|
|
854
|
+
return selectedServerTools.includes(toolId);
|
|
855
|
+
};
|
|
856
|
+
|
|
857
|
+
const setMCPServerToolState = (
|
|
858
|
+
serverId: string,
|
|
859
|
+
toolId: string,
|
|
860
|
+
checked: boolean
|
|
861
|
+
) => {
|
|
862
|
+
const newConfig = { ...toolSelections };
|
|
863
|
+
|
|
864
|
+
if (checked && !(serverId in newConfig.mcpServers)) {
|
|
865
|
+
newConfig.mcpServers[serverId] = [];
|
|
866
|
+
}
|
|
867
|
+
|
|
868
|
+
const selectedServerTools: string[] = newConfig.mcpServers[serverId];
|
|
869
|
+
|
|
870
|
+
if (checked) {
|
|
871
|
+
selectedServerTools.push(toolId);
|
|
872
|
+
} else {
|
|
873
|
+
const index = selectedServerTools.indexOf(toolId);
|
|
874
|
+
if (index !== -1) {
|
|
875
|
+
selectedServerTools.splice(index, 1);
|
|
876
|
+
}
|
|
877
|
+
}
|
|
878
|
+
|
|
879
|
+
setToolSelections(newConfig);
|
|
880
|
+
};
|
|
881
|
+
|
|
882
|
+
// all toolsets and tools of the extension are selected
|
|
883
|
+
const getExtensionState = (extensionId: string): boolean => {
|
|
884
|
+
if (!(extensionId in toolSelections.extensions)) {
|
|
885
|
+
return false;
|
|
886
|
+
}
|
|
887
|
+
|
|
888
|
+
const extension = toolConfig.extensions.find(
|
|
889
|
+
extension => extension.id === extensionId
|
|
890
|
+
);
|
|
891
|
+
|
|
892
|
+
for (const toolset of extension.toolsets) {
|
|
893
|
+
if (!getExtensionToolsetState(extensionId, toolset.id)) {
|
|
894
|
+
return false;
|
|
895
|
+
}
|
|
896
|
+
}
|
|
897
|
+
|
|
898
|
+
return true;
|
|
899
|
+
};
|
|
900
|
+
|
|
901
|
+
const getExtensionToolsetState = (
|
|
902
|
+
extensionId: string,
|
|
903
|
+
toolsetId: string
|
|
904
|
+
): boolean => {
|
|
905
|
+
if (!(extensionId in toolSelections.extensions)) {
|
|
906
|
+
return false;
|
|
907
|
+
}
|
|
908
|
+
|
|
909
|
+
if (!(toolsetId in toolSelections.extensions[extensionId])) {
|
|
910
|
+
return false;
|
|
911
|
+
}
|
|
912
|
+
|
|
913
|
+
const extension = toolConfig.extensions.find(ext => ext.id === extensionId);
|
|
914
|
+
const extensionToolset = extension.toolsets.find(
|
|
915
|
+
(toolset: any) => toolset.id === toolsetId
|
|
916
|
+
);
|
|
917
|
+
|
|
918
|
+
const selectedToolsetTools: string[] =
|
|
919
|
+
toolSelections.extensions[extensionId][toolsetId];
|
|
920
|
+
|
|
921
|
+
for (const tool of extensionToolset.tools) {
|
|
922
|
+
if (!selectedToolsetTools.includes(tool)) {
|
|
923
|
+
return false;
|
|
924
|
+
}
|
|
925
|
+
}
|
|
926
|
+
|
|
927
|
+
return true;
|
|
928
|
+
};
|
|
929
|
+
|
|
930
|
+
const anyExtensionToolsetSelected = (extensionId: string) => {
|
|
931
|
+
if (!(extensionId in toolSelections.extensions)) {
|
|
932
|
+
return false;
|
|
933
|
+
}
|
|
934
|
+
|
|
935
|
+
return Object.keys(toolSelections.extensions[extensionId]).length > 0;
|
|
936
|
+
};
|
|
937
|
+
|
|
938
|
+
const onExtensionClicked = (extensionId: string) => {
|
|
939
|
+
if (anyExtensionToolsetSelected(extensionId)) {
|
|
940
|
+
const newConfig = { ...toolSelections };
|
|
941
|
+
delete newConfig.extensions[extensionId];
|
|
942
|
+
setToolSelections(newConfig);
|
|
943
|
+
} else {
|
|
944
|
+
const newConfig = { ...toolSelections };
|
|
945
|
+
const extension = toolConfig.extensions.find(
|
|
946
|
+
ext => ext.id === extensionId
|
|
947
|
+
);
|
|
948
|
+
if (extensionId in newConfig.extensions) {
|
|
949
|
+
delete newConfig.extensions[extensionId];
|
|
950
|
+
}
|
|
951
|
+
newConfig.extensions[extensionId] = {};
|
|
952
|
+
for (const toolset of extension.toolsets) {
|
|
953
|
+
newConfig.extensions[extensionId][toolset.id] = structuredClone(
|
|
954
|
+
toolset.tools
|
|
955
|
+
);
|
|
956
|
+
}
|
|
957
|
+
setToolSelections(newConfig);
|
|
958
|
+
}
|
|
959
|
+
};
|
|
960
|
+
|
|
961
|
+
const anyExtensionToolsetToolSelected = (
|
|
962
|
+
extensionId: string,
|
|
963
|
+
toolsetId: string
|
|
964
|
+
) => {
|
|
965
|
+
if (!(extensionId in toolSelections.extensions)) {
|
|
966
|
+
return false;
|
|
967
|
+
}
|
|
968
|
+
|
|
969
|
+
if (!(toolsetId in toolSelections.extensions[extensionId])) {
|
|
970
|
+
return false;
|
|
971
|
+
}
|
|
972
|
+
|
|
973
|
+
return toolSelections.extensions[extensionId][toolsetId].length > 0;
|
|
974
|
+
};
|
|
975
|
+
|
|
976
|
+
const onExtensionToolsetClicked = (
|
|
977
|
+
extensionId: string,
|
|
978
|
+
toolsetId: string
|
|
979
|
+
) => {
|
|
980
|
+
if (anyExtensionToolsetToolSelected(extensionId, toolsetId)) {
|
|
981
|
+
const newConfig = { ...toolSelections };
|
|
982
|
+
if (toolsetId in newConfig.extensions[extensionId]) {
|
|
983
|
+
delete newConfig.extensions[extensionId][toolsetId];
|
|
984
|
+
}
|
|
985
|
+
setToolSelections(newConfig);
|
|
986
|
+
} else {
|
|
987
|
+
const extension = toolConfig.extensions.find(
|
|
988
|
+
ext => ext.id === extensionId
|
|
989
|
+
);
|
|
990
|
+
const extensionToolset = extension.toolsets.find(
|
|
991
|
+
(toolset: any) => toolset.id === toolsetId
|
|
992
|
+
);
|
|
993
|
+
const newConfig = { ...toolSelections };
|
|
994
|
+
if (!(extensionId in newConfig.extensions)) {
|
|
995
|
+
newConfig.extensions[extensionId] = {};
|
|
996
|
+
}
|
|
997
|
+
newConfig.extensions[extensionId][toolsetId] = structuredClone(
|
|
998
|
+
extensionToolset.tools
|
|
999
|
+
);
|
|
1000
|
+
setToolSelections(newConfig);
|
|
1001
|
+
}
|
|
1002
|
+
};
|
|
1003
|
+
|
|
1004
|
+
const getExtensionToolsetToolState = (
|
|
1005
|
+
extensionId: string,
|
|
1006
|
+
toolsetId: string,
|
|
1007
|
+
toolId: string
|
|
1008
|
+
): boolean => {
|
|
1009
|
+
if (!(extensionId in toolSelections.extensions)) {
|
|
1010
|
+
return false;
|
|
1011
|
+
}
|
|
1012
|
+
|
|
1013
|
+
const selectedExtensionToolsets: any =
|
|
1014
|
+
toolSelections.extensions[extensionId];
|
|
1015
|
+
|
|
1016
|
+
if (!(toolsetId in selectedExtensionToolsets)) {
|
|
1017
|
+
return false;
|
|
1018
|
+
}
|
|
1019
|
+
|
|
1020
|
+
const selectedServerTools: string[] = selectedExtensionToolsets[toolsetId];
|
|
1021
|
+
|
|
1022
|
+
return selectedServerTools.includes(toolId);
|
|
1023
|
+
};
|
|
1024
|
+
|
|
1025
|
+
const setExtensionToolsetToolState = (
|
|
1026
|
+
extensionId: string,
|
|
1027
|
+
toolsetId: string,
|
|
1028
|
+
toolId: string,
|
|
1029
|
+
checked: boolean
|
|
1030
|
+
) => {
|
|
1031
|
+
const newConfig = { ...toolSelections };
|
|
1032
|
+
|
|
1033
|
+
if (checked && !(extensionId in newConfig.extensions)) {
|
|
1034
|
+
newConfig.extensions[extensionId] = {};
|
|
1035
|
+
}
|
|
1036
|
+
|
|
1037
|
+
if (checked && !(toolsetId in newConfig.extensions[extensionId])) {
|
|
1038
|
+
newConfig.extensions[extensionId][toolsetId] = [];
|
|
1039
|
+
}
|
|
1040
|
+
|
|
1041
|
+
const selectedTools: string[] =
|
|
1042
|
+
newConfig.extensions[extensionId][toolsetId];
|
|
1043
|
+
|
|
1044
|
+
if (checked) {
|
|
1045
|
+
selectedTools.push(toolId);
|
|
1046
|
+
} else {
|
|
1047
|
+
const index = selectedTools.indexOf(toolId);
|
|
1048
|
+
if (index !== -1) {
|
|
1049
|
+
selectedTools.splice(index, 1);
|
|
1050
|
+
}
|
|
1051
|
+
}
|
|
1052
|
+
|
|
1053
|
+
setToolSelections(newConfig);
|
|
1054
|
+
};
|
|
661
1055
|
|
|
662
1056
|
useEffect(() => {
|
|
663
1057
|
const prefixes: string[] = [];
|
|
1058
|
+
if (chatMode !== 'ask') {
|
|
1059
|
+
prefixes.push('/clear');
|
|
1060
|
+
setOriginalPrefixes(prefixes);
|
|
1061
|
+
setPrefixSuggestions(prefixes);
|
|
1062
|
+
return;
|
|
1063
|
+
}
|
|
1064
|
+
|
|
664
1065
|
const chatParticipants = NBIAPI.config.chatParticipants;
|
|
665
1066
|
for (const participant of chatParticipants) {
|
|
666
1067
|
const id = participant.id;
|
|
@@ -677,7 +1078,7 @@ function SidebarComponent(props: any) {
|
|
|
677
1078
|
}
|
|
678
1079
|
setOriginalPrefixes(prefixes);
|
|
679
1080
|
setPrefixSuggestions(prefixes);
|
|
680
|
-
}, []);
|
|
1081
|
+
}, [chatMode]);
|
|
681
1082
|
|
|
682
1083
|
useEffect(() => {
|
|
683
1084
|
const fetchData = () => {
|
|
@@ -730,6 +1131,7 @@ function SidebarComponent(props: any) {
|
|
|
730
1131
|
};
|
|
731
1132
|
|
|
732
1133
|
const handleSubmitStopChatButtonClick = async () => {
|
|
1134
|
+
setShowModeTools(false);
|
|
733
1135
|
if (!copilotRequestInProgress) {
|
|
734
1136
|
handleUserInputSubmit();
|
|
735
1137
|
} else {
|
|
@@ -737,6 +1139,20 @@ function SidebarComponent(props: any) {
|
|
|
737
1139
|
}
|
|
738
1140
|
};
|
|
739
1141
|
|
|
1142
|
+
const handleSettingsButtonClick = async () => {
|
|
1143
|
+
setShowModeTools(false);
|
|
1144
|
+
props
|
|
1145
|
+
.getApp()
|
|
1146
|
+
.commands.execute('notebook-intelligence:open-configuration-dialog');
|
|
1147
|
+
};
|
|
1148
|
+
|
|
1149
|
+
const handleChatToolsButtonClick = async () => {
|
|
1150
|
+
if (!showModeTools) {
|
|
1151
|
+
NBIAPI.fetchCapabilities();
|
|
1152
|
+
}
|
|
1153
|
+
setShowModeTools(!showModeTools);
|
|
1154
|
+
};
|
|
1155
|
+
|
|
740
1156
|
const handleUserInputSubmit = async () => {
|
|
741
1157
|
setPromptHistoryIndex(promptHistory.length + 1);
|
|
742
1158
|
setPromptHistory([...promptHistory, prompt]);
|
|
@@ -828,7 +1244,9 @@ function SidebarComponent(props: any) {
|
|
|
828
1244
|
content: extractedPrompt,
|
|
829
1245
|
language: activeDocInfo.language,
|
|
830
1246
|
filename: activeDocInfo.filename,
|
|
831
|
-
additionalContext
|
|
1247
|
+
additionalContext,
|
|
1248
|
+
chatMode,
|
|
1249
|
+
toolSelections: toolSelections
|
|
832
1250
|
},
|
|
833
1251
|
{
|
|
834
1252
|
emit: async response => {
|
|
@@ -986,6 +1404,7 @@ function SidebarComponent(props: any) {
|
|
|
986
1404
|
event.stopPropagation();
|
|
987
1405
|
event.preventDefault();
|
|
988
1406
|
setShowPopover(false);
|
|
1407
|
+
setShowModeTools(false);
|
|
989
1408
|
setSelectedPrefixSuggestionIndex(0);
|
|
990
1409
|
} else if (event.key === 'ArrowUp') {
|
|
991
1410
|
event.stopPropagation();
|
|
@@ -1260,6 +1679,12 @@ function SidebarComponent(props: any) {
|
|
|
1260
1679
|
<div className="sidebar">
|
|
1261
1680
|
<div className="sidebar-header">
|
|
1262
1681
|
<div className="sidebar-title">Notebook Intelligence</div>
|
|
1682
|
+
<div
|
|
1683
|
+
className="user-input-footer-button"
|
|
1684
|
+
onClick={() => handleSettingsButtonClick()}
|
|
1685
|
+
>
|
|
1686
|
+
<VscSettingsGear />
|
|
1687
|
+
</div>
|
|
1263
1688
|
</div>
|
|
1264
1689
|
{!chatEnabled && !ghLoginRequired && (
|
|
1265
1690
|
<div className="sidebar-login-info">
|
|
@@ -1333,7 +1758,7 @@ function SidebarComponent(props: any) {
|
|
|
1333
1758
|
rows={3}
|
|
1334
1759
|
onChange={onPromptChange}
|
|
1335
1760
|
onKeyDown={onPromptKeyDown}
|
|
1336
|
-
placeholder="Ask
|
|
1761
|
+
placeholder="Ask Notebook Intelligence..."
|
|
1337
1762
|
spellCheck={false}
|
|
1338
1763
|
value={prompt}
|
|
1339
1764
|
/>
|
|
@@ -1362,19 +1787,56 @@ function SidebarComponent(props: any) {
|
|
|
1362
1787
|
</div>
|
|
1363
1788
|
)}
|
|
1364
1789
|
<div className="user-input-footer">
|
|
1365
|
-
|
|
1366
|
-
<
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1790
|
+
{chatMode === 'ask' && (
|
|
1791
|
+
<div>
|
|
1792
|
+
<a
|
|
1793
|
+
href="javascript:void(0)"
|
|
1794
|
+
onClick={() => {
|
|
1795
|
+
setShowPopover(true);
|
|
1796
|
+
promptInputRef.current?.focus();
|
|
1797
|
+
}}
|
|
1798
|
+
title="Select chat participant"
|
|
1799
|
+
>
|
|
1800
|
+
@
|
|
1801
|
+
</a>
|
|
1802
|
+
</div>
|
|
1803
|
+
)}
|
|
1377
1804
|
<div style={{ flexGrow: 1 }}></div>
|
|
1805
|
+
<div className="chat-mode-widgets-container">
|
|
1806
|
+
<div>
|
|
1807
|
+
<select
|
|
1808
|
+
className="chat-mode-select"
|
|
1809
|
+
title="Chat mode"
|
|
1810
|
+
value={chatMode}
|
|
1811
|
+
onChange={event => {
|
|
1812
|
+
if (event.target.value === 'ask') {
|
|
1813
|
+
setToolSelections(toolSelectionsEmpty);
|
|
1814
|
+
} else if (event.target.value === 'agent') {
|
|
1815
|
+
setToolSelections(toolSelectionsInitial);
|
|
1816
|
+
}
|
|
1817
|
+
setShowModeTools(false);
|
|
1818
|
+
setChatMode(event.target.value);
|
|
1819
|
+
}}
|
|
1820
|
+
>
|
|
1821
|
+
<option value="ask">Ask</option>
|
|
1822
|
+
<option value="agent">Agent</option>
|
|
1823
|
+
</select>
|
|
1824
|
+
</div>
|
|
1825
|
+
{chatMode !== 'ask' && (
|
|
1826
|
+
<div
|
|
1827
|
+
className={`user-input-footer-button tools-button ${notebookExecuteToolSelected ? 'tools-button-warning' : selectedToolCount > 0 ? 'tools-button-active' : ''}`}
|
|
1828
|
+
onClick={() => handleChatToolsButtonClick()}
|
|
1829
|
+
title={
|
|
1830
|
+
notebookExecuteToolSelected
|
|
1831
|
+
? `Notebook execute tool selected!\n${toolSelectionTitle}`
|
|
1832
|
+
: toolSelectionTitle
|
|
1833
|
+
}
|
|
1834
|
+
>
|
|
1835
|
+
<VscTools />
|
|
1836
|
+
{selectedToolCount > 0 && <>{selectedToolCount}</>}
|
|
1837
|
+
</div>
|
|
1838
|
+
)}
|
|
1839
|
+
</div>
|
|
1378
1840
|
<div>
|
|
1379
1841
|
<button
|
|
1380
1842
|
className="jp-Dialog-button jp-mod-accept jp-mod-styled send-button"
|
|
@@ -1399,6 +1861,154 @@ function SidebarComponent(props: any) {
|
|
|
1399
1861
|
))}
|
|
1400
1862
|
</div>
|
|
1401
1863
|
)}
|
|
1864
|
+
{showModeTools && (
|
|
1865
|
+
<div
|
|
1866
|
+
className="mode-tools-popover"
|
|
1867
|
+
tabIndex={1}
|
|
1868
|
+
autoFocus={true}
|
|
1869
|
+
onKeyDown={(event: KeyboardEvent<HTMLDivElement>) => {
|
|
1870
|
+
if (event.key === 'Escape' || event.key === 'Enter') {
|
|
1871
|
+
event.stopPropagation();
|
|
1872
|
+
event.preventDefault();
|
|
1873
|
+
setShowModeTools(false);
|
|
1874
|
+
}
|
|
1875
|
+
}}
|
|
1876
|
+
>
|
|
1877
|
+
<div className="mode-tools-popover-header">
|
|
1878
|
+
<div className="mode-tools-popover-header-icon">
|
|
1879
|
+
<VscTools />
|
|
1880
|
+
</div>
|
|
1881
|
+
<div className="mode-tools-popover-title">
|
|
1882
|
+
{toolSelectionTitle}
|
|
1883
|
+
</div>
|
|
1884
|
+
<div
|
|
1885
|
+
className="mode-tools-popover-clear-tools-button"
|
|
1886
|
+
style={{
|
|
1887
|
+
visibility: selectedToolCount > 0 ? 'visible' : 'hidden'
|
|
1888
|
+
}}
|
|
1889
|
+
>
|
|
1890
|
+
<div>
|
|
1891
|
+
<VscTrash />
|
|
1892
|
+
</div>
|
|
1893
|
+
<div>
|
|
1894
|
+
<a
|
|
1895
|
+
href="javascript:void(0);"
|
|
1896
|
+
onClick={onClearToolsButtonClicked}
|
|
1897
|
+
>
|
|
1898
|
+
clear
|
|
1899
|
+
</a>
|
|
1900
|
+
</div>
|
|
1901
|
+
</div>
|
|
1902
|
+
<div
|
|
1903
|
+
className="mode-tools-popover-close-button"
|
|
1904
|
+
onClick={() => setShowModeTools(false)}
|
|
1905
|
+
>
|
|
1906
|
+
{/* <button
|
|
1907
|
+
className="jp-Dialog-button jp-mod-accept jp-mod-styled send-button"
|
|
1908
|
+
> */}
|
|
1909
|
+
<div>
|
|
1910
|
+
<VscPassFilled />
|
|
1911
|
+
</div>
|
|
1912
|
+
{/* </button> */}
|
|
1913
|
+
<div>Done</div>
|
|
1914
|
+
</div>
|
|
1915
|
+
</div>
|
|
1916
|
+
<div className="mode-tools-popover-tool-list">
|
|
1917
|
+
<div className="mode-tools-group-header">Built-in</div>
|
|
1918
|
+
<div className="mode-tools-group">
|
|
1919
|
+
{toolConfig.builtinToolsets.map((toolset: any) => (
|
|
1920
|
+
<CheckBoxItem
|
|
1921
|
+
key={toolset.id}
|
|
1922
|
+
label={toolset.name}
|
|
1923
|
+
checked={getBuiltinToolsetState(toolset.id)}
|
|
1924
|
+
onClick={() => {
|
|
1925
|
+
setBuiltinToolsetState(
|
|
1926
|
+
toolset.id,
|
|
1927
|
+
!getBuiltinToolsetState(toolset.id)
|
|
1928
|
+
);
|
|
1929
|
+
}}
|
|
1930
|
+
/>
|
|
1931
|
+
))}
|
|
1932
|
+
</div>
|
|
1933
|
+
{toolConfig.mcpServers.length > 0 && (
|
|
1934
|
+
<div className="mode-tools-group-header">MCP Servers</div>
|
|
1935
|
+
)}
|
|
1936
|
+
{toolConfig.mcpServers.map((mcpServer, index: number) => (
|
|
1937
|
+
<div className="mode-tools-group">
|
|
1938
|
+
<CheckBoxItem
|
|
1939
|
+
label={mcpServer.id}
|
|
1940
|
+
checked={getMCPServerState(mcpServer.id)}
|
|
1941
|
+
onClick={() => onMCPServerClicked(mcpServer.id)}
|
|
1942
|
+
/>
|
|
1943
|
+
{mcpServer.tools.map((tool: any, index: number) => (
|
|
1944
|
+
<CheckBoxItem
|
|
1945
|
+
label={tool}
|
|
1946
|
+
indent={1}
|
|
1947
|
+
checked={getMCPServerToolState(mcpServer.id, tool)}
|
|
1948
|
+
onClick={() =>
|
|
1949
|
+
setMCPServerToolState(
|
|
1950
|
+
mcpServer.id,
|
|
1951
|
+
tool,
|
|
1952
|
+
!getMCPServerToolState(mcpServer.id, tool)
|
|
1953
|
+
)
|
|
1954
|
+
}
|
|
1955
|
+
/>
|
|
1956
|
+
))}
|
|
1957
|
+
</div>
|
|
1958
|
+
))}
|
|
1959
|
+
{hasExtensionTools && (
|
|
1960
|
+
<div className="mode-tools-group-header">Extension tools</div>
|
|
1961
|
+
)}
|
|
1962
|
+
{toolConfig.extensions.map((extension, index: number) => (
|
|
1963
|
+
<div className="mode-tools-group">
|
|
1964
|
+
<CheckBoxItem
|
|
1965
|
+
label={`${extension.name} (${extension.id})`}
|
|
1966
|
+
checked={getExtensionState(extension.id)}
|
|
1967
|
+
onClick={() => onExtensionClicked(extension.id)}
|
|
1968
|
+
/>
|
|
1969
|
+
{extension.toolsets.map((toolset: any, index: number) => (
|
|
1970
|
+
<>
|
|
1971
|
+
<CheckBoxItem
|
|
1972
|
+
label={`${toolset.name} (${toolset.id})`}
|
|
1973
|
+
indent={1}
|
|
1974
|
+
checked={getExtensionToolsetState(
|
|
1975
|
+
extension.id,
|
|
1976
|
+
toolset.id
|
|
1977
|
+
)}
|
|
1978
|
+
onClick={() =>
|
|
1979
|
+
onExtensionToolsetClicked(extension.id, toolset.id)
|
|
1980
|
+
}
|
|
1981
|
+
/>
|
|
1982
|
+
{toolset.tools.map((tool: any, index: number) => (
|
|
1983
|
+
<CheckBoxItem
|
|
1984
|
+
label={tool}
|
|
1985
|
+
indent={2}
|
|
1986
|
+
checked={getExtensionToolsetToolState(
|
|
1987
|
+
extension.id,
|
|
1988
|
+
toolset.id,
|
|
1989
|
+
tool
|
|
1990
|
+
)}
|
|
1991
|
+
onClick={() =>
|
|
1992
|
+
setExtensionToolsetToolState(
|
|
1993
|
+
extension.id,
|
|
1994
|
+
toolset.id,
|
|
1995
|
+
tool,
|
|
1996
|
+
!getExtensionToolsetToolState(
|
|
1997
|
+
extension.id,
|
|
1998
|
+
toolset.id,
|
|
1999
|
+
tool
|
|
2000
|
+
)
|
|
2001
|
+
)
|
|
2002
|
+
}
|
|
2003
|
+
/>
|
|
2004
|
+
))}
|
|
2005
|
+
</>
|
|
2006
|
+
))}
|
|
2007
|
+
</div>
|
|
2008
|
+
))}
|
|
2009
|
+
</div>
|
|
2010
|
+
</div>
|
|
2011
|
+
)}
|
|
1402
2012
|
</div>
|
|
1403
2013
|
)}
|
|
1404
2014
|
</div>
|
|
@@ -1548,7 +2158,8 @@ function InlinePromptComponent(props: any) {
|
|
|
1548
2158
|
filename: undefined,
|
|
1549
2159
|
prefix: props.prefix,
|
|
1550
2160
|
suffix: props.suffix,
|
|
1551
|
-
existingCode: props.existingCode
|
|
2161
|
+
existingCode: props.existingCode,
|
|
2162
|
+
chatMode: 'ask'
|
|
1552
2163
|
},
|
|
1553
2164
|
{
|
|
1554
2165
|
emit: async response => {
|
|
@@ -1595,7 +2206,7 @@ function InlinePromptComponent(props: any) {
|
|
|
1595
2206
|
rows={3}
|
|
1596
2207
|
onChange={onPromptChange}
|
|
1597
2208
|
onKeyDown={onPromptKeyDown}
|
|
1598
|
-
placeholder="Ask
|
|
2209
|
+
placeholder="Ask Notebook Intelligence to generate Python code..."
|
|
1599
2210
|
spellCheck={false}
|
|
1600
2211
|
value={prompt}
|
|
1601
2212
|
/>
|