@notebook-intelligence/notebook-intelligence 2.4.2 → 2.6.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 +114 -95
- package/lib/api.d.ts +8 -1
- package/lib/api.js +59 -15
- package/lib/chat-sidebar.d.ts +7 -5
- package/lib/chat-sidebar.js +144 -331
- package/lib/components/checkbox.d.ts +2 -0
- package/lib/components/checkbox.js +11 -0
- package/lib/components/mcp-util.d.ts +2 -0
- package/lib/components/mcp-util.js +37 -0
- package/lib/components/pill.d.ts +2 -0
- package/lib/components/pill.js +5 -0
- package/lib/components/settings-panel.d.ts +11 -0
- package/lib/components/settings-panel.js +374 -0
- package/lib/index.js +82 -22
- package/lib/tokens.d.ts +13 -1
- package/lib/tokens.js +13 -0
- package/package.json +1 -1
- package/src/api.ts +76 -16
- package/src/chat-sidebar.tsx +286 -700
- package/src/components/checkbox.tsx +29 -0
- package/src/components/mcp-util.ts +53 -0
- package/src/components/pill.tsx +15 -0
- package/src/components/settings-panel.tsx +770 -0
- package/src/index.ts +93 -25
- package/src/tokens.ts +14 -1
- package/style/base.css +103 -2
- package/style/icons/sparkles-warning.svg +5 -0
package/src/chat-sidebar.tsx
CHANGED
|
@@ -20,7 +20,6 @@ import {
|
|
|
20
20
|
BackendMessageType,
|
|
21
21
|
BuiltinToolsetType,
|
|
22
22
|
ContextType,
|
|
23
|
-
GITHUB_COPILOT_PROVIDER_ID,
|
|
24
23
|
IActiveDocumentInfo,
|
|
25
24
|
ICellContents,
|
|
26
25
|
IChatCompletionResponseEmitter,
|
|
@@ -46,24 +45,15 @@ import {
|
|
|
46
45
|
VscEyeClosed,
|
|
47
46
|
VscTriangleRight,
|
|
48
47
|
VscTriangleDown,
|
|
49
|
-
VscWarning,
|
|
50
48
|
VscSettingsGear,
|
|
51
49
|
VscPassFilled,
|
|
52
50
|
VscTools,
|
|
53
51
|
VscTrash
|
|
54
52
|
} from 'react-icons/vsc';
|
|
55
53
|
|
|
56
|
-
import { MdOutlineCheckBoxOutlineBlank, MdCheckBox } from 'react-icons/md';
|
|
57
|
-
|
|
58
54
|
import { extractLLMGeneratedCode, isDarkTheme } from './utils';
|
|
59
|
-
import
|
|
60
|
-
|
|
61
|
-
const OPENAI_COMPATIBLE_CHAT_MODEL_ID = 'openai-compatible-chat-model';
|
|
62
|
-
const LITELLM_COMPATIBLE_CHAT_MODEL_ID = 'litellm-compatible-chat-model';
|
|
63
|
-
const OPENAI_COMPATIBLE_INLINE_COMPLETION_MODEL_ID =
|
|
64
|
-
'openai-compatible-inline-completion-model';
|
|
65
|
-
const LITELLM_COMPATIBLE_INLINE_COMPLETION_MODEL_ID =
|
|
66
|
-
'litellm-compatible-inline-completion-model';
|
|
55
|
+
import { CheckBoxItem } from './components/checkbox';
|
|
56
|
+
import { mcpServerSettingsToEnabledState } from './components/mcp-util';
|
|
67
57
|
|
|
68
58
|
export enum RunChatCompletionType {
|
|
69
59
|
Chat,
|
|
@@ -127,6 +117,8 @@ export interface IInlinePromptWidgetOptions {
|
|
|
127
117
|
existingCode: string;
|
|
128
118
|
prefix: string;
|
|
129
119
|
suffix: string;
|
|
120
|
+
language?: string;
|
|
121
|
+
filename?: string;
|
|
130
122
|
onRequestSubmitted: (prompt: string) => void;
|
|
131
123
|
onRequestCancelled: () => void;
|
|
132
124
|
onContentStream: (content: string) => void;
|
|
@@ -264,30 +256,6 @@ export class GitHubCopilotLoginDialogBody extends ReactWidget {
|
|
|
264
256
|
private _onLoggedIn: () => void;
|
|
265
257
|
}
|
|
266
258
|
|
|
267
|
-
export class ConfigurationDialogBody extends ReactWidget {
|
|
268
|
-
constructor(options: {
|
|
269
|
-
onSave: () => void;
|
|
270
|
-
onEditMCPConfigClicked: () => void;
|
|
271
|
-
}) {
|
|
272
|
-
super();
|
|
273
|
-
|
|
274
|
-
this._onEditMCPConfigClicked = options.onEditMCPConfigClicked;
|
|
275
|
-
this._onSave = options.onSave;
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
render(): JSX.Element {
|
|
279
|
-
return (
|
|
280
|
-
<ConfigurationDialogBodyComponent
|
|
281
|
-
onEditMCPConfigClicked={this._onEditMCPConfigClicked}
|
|
282
|
-
onSave={this._onSave}
|
|
283
|
-
/>
|
|
284
|
-
);
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
private _onEditMCPConfigClicked: () => void;
|
|
288
|
-
private _onSave: () => void;
|
|
289
|
-
}
|
|
290
|
-
|
|
291
259
|
interface IChatMessageContent {
|
|
292
260
|
id: string;
|
|
293
261
|
type: ResponseStreamDataType;
|
|
@@ -684,30 +652,6 @@ async function submitCompletionRequest(
|
|
|
684
652
|
}
|
|
685
653
|
}
|
|
686
654
|
|
|
687
|
-
function CheckBoxItem(props: any) {
|
|
688
|
-
const indent = props.indent || 0;
|
|
689
|
-
|
|
690
|
-
return (
|
|
691
|
-
<div
|
|
692
|
-
className={`checkbox-item checkbox-item-indent-${indent} ${props.header ? 'checkbox-item-header' : ''}`}
|
|
693
|
-
title={props.title}
|
|
694
|
-
onClick={event => props.onClick(event)}
|
|
695
|
-
>
|
|
696
|
-
<div className="checkbox-item-toggle">
|
|
697
|
-
{props.checked ? (
|
|
698
|
-
<MdCheckBox className="checkbox-icon" />
|
|
699
|
-
) : (
|
|
700
|
-
<MdOutlineCheckBoxOutlineBlank className="checkbox-icon" />
|
|
701
|
-
)}
|
|
702
|
-
{props.label}
|
|
703
|
-
</div>
|
|
704
|
-
{props.title && (
|
|
705
|
-
<div className="checkbox-item-description">{props.title}</div>
|
|
706
|
-
)}
|
|
707
|
-
</div>
|
|
708
|
-
);
|
|
709
|
-
}
|
|
710
|
-
|
|
711
655
|
function SidebarComponent(props: any) {
|
|
712
656
|
const [chatMessages, setChatMessages] = useState<IChatMessage[]>([]);
|
|
713
657
|
const [prompt, setPrompt] = useState<string>('');
|
|
@@ -743,7 +687,9 @@ function SidebarComponent(props: any) {
|
|
|
743
687
|
const [selectedToolCount, setSelectedToolCount] = useState(0);
|
|
744
688
|
const [notebookExecuteToolSelected, setNotebookExecuteToolSelected] =
|
|
745
689
|
useState(false);
|
|
746
|
-
|
|
690
|
+
|
|
691
|
+
const [renderCount, setRenderCount] = useState(1);
|
|
692
|
+
const toolConfigRef = useRef({
|
|
747
693
|
builtinToolsets: [
|
|
748
694
|
{ id: BuiltinToolsetType.NotebookEdit, name: 'Notebook edit' },
|
|
749
695
|
{ id: BuiltinToolsetType.NotebookExecute, name: 'Notebook execute' }
|
|
@@ -751,6 +697,16 @@ function SidebarComponent(props: any) {
|
|
|
751
697
|
mcpServers: [],
|
|
752
698
|
extensions: []
|
|
753
699
|
});
|
|
700
|
+
const mcpServerSettingsRef = useRef(NBIAPI.config.mcpServerSettings);
|
|
701
|
+
const [mcpServerEnabledState, setMCPServerEnabledState] = useState(
|
|
702
|
+
new Map<string, Set<string>>(
|
|
703
|
+
mcpServerSettingsToEnabledState(
|
|
704
|
+
toolConfigRef.current.mcpServers,
|
|
705
|
+
mcpServerSettingsRef.current
|
|
706
|
+
)
|
|
707
|
+
)
|
|
708
|
+
);
|
|
709
|
+
|
|
754
710
|
const [showModeTools, setShowModeTools] = useState(false);
|
|
755
711
|
const toolSelectionsInitial: any = {
|
|
756
712
|
builtinToolsets: [BuiltinToolsetType.NotebookEdit],
|
|
@@ -762,25 +718,37 @@ function SidebarComponent(props: any) {
|
|
|
762
718
|
mcpServers: {},
|
|
763
719
|
extensions: {}
|
|
764
720
|
};
|
|
765
|
-
const [toolSelections, setToolSelections] = useState(
|
|
721
|
+
const [toolSelections, setToolSelections] = useState(
|
|
722
|
+
structuredClone(toolSelectionsInitial)
|
|
723
|
+
);
|
|
766
724
|
const [hasExtensionTools, setHasExtensionTools] = useState(false);
|
|
767
725
|
const [lastScrollTime, setLastScrollTime] = useState(0);
|
|
768
726
|
const [scrollPending, setScrollPending] = useState(false);
|
|
769
727
|
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
728
|
+
useEffect(() => {
|
|
729
|
+
NBIAPI.configChanged.connect(() => {
|
|
730
|
+
toolConfigRef.current = NBIAPI.config.toolConfig;
|
|
731
|
+
mcpServerSettingsRef.current = NBIAPI.config.mcpServerSettings;
|
|
732
|
+
const newMcpServerEnabledState = mcpServerSettingsToEnabledState(
|
|
733
|
+
toolConfigRef.current.mcpServers,
|
|
734
|
+
mcpServerSettingsRef.current
|
|
735
|
+
);
|
|
736
|
+
setMCPServerEnabledState(newMcpServerEnabledState);
|
|
737
|
+
setToolSelections(structuredClone(toolSelectionsInitial));
|
|
738
|
+
setRenderCount(renderCount => renderCount + 1);
|
|
739
|
+
});
|
|
740
|
+
}, []);
|
|
773
741
|
|
|
774
742
|
useEffect(() => {
|
|
775
743
|
let hasTools = false;
|
|
776
|
-
for (const extension of
|
|
744
|
+
for (const extension of toolConfigRef.current.extensions) {
|
|
777
745
|
if (extension.toolsets.length > 0) {
|
|
778
746
|
hasTools = true;
|
|
779
747
|
break;
|
|
780
748
|
}
|
|
781
749
|
}
|
|
782
750
|
setHasExtensionTools(hasTools);
|
|
783
|
-
}, [
|
|
751
|
+
}, [toolConfigRef.current]);
|
|
784
752
|
|
|
785
753
|
useEffect(() => {
|
|
786
754
|
const builtinToolSelCount = toolSelections.builtinToolsets.length;
|
|
@@ -862,7 +830,9 @@ function SidebarComponent(props: any) {
|
|
|
862
830
|
return false;
|
|
863
831
|
}
|
|
864
832
|
|
|
865
|
-
const mcpServer =
|
|
833
|
+
const mcpServer = toolConfigRef.current.mcpServers.find(
|
|
834
|
+
server => server.id === id
|
|
835
|
+
);
|
|
866
836
|
|
|
867
837
|
const selectedServerTools: string[] = toolSelections.mcpServers[id];
|
|
868
838
|
|
|
@@ -881,10 +851,16 @@ function SidebarComponent(props: any) {
|
|
|
881
851
|
delete newConfig.mcpServers[id];
|
|
882
852
|
setToolSelections(newConfig);
|
|
883
853
|
} else {
|
|
884
|
-
const mcpServer =
|
|
854
|
+
const mcpServer = toolConfigRef.current.mcpServers.find(
|
|
855
|
+
server => server.id === id
|
|
856
|
+
);
|
|
885
857
|
const newConfig = { ...toolSelections };
|
|
886
858
|
newConfig.mcpServers[id] = structuredClone(
|
|
887
|
-
mcpServer.tools
|
|
859
|
+
mcpServer.tools
|
|
860
|
+
.filter((tool: any) =>
|
|
861
|
+
mcpServerEnabledState.get(mcpServer.id).has(tool.name)
|
|
862
|
+
)
|
|
863
|
+
.map((tool: any) => tool.name)
|
|
888
864
|
);
|
|
889
865
|
setToolSelections(newConfig);
|
|
890
866
|
}
|
|
@@ -931,7 +907,7 @@ function SidebarComponent(props: any) {
|
|
|
931
907
|
return false;
|
|
932
908
|
}
|
|
933
909
|
|
|
934
|
-
const extension =
|
|
910
|
+
const extension = toolConfigRef.current.extensions.find(
|
|
935
911
|
extension => extension.id === extensionId
|
|
936
912
|
);
|
|
937
913
|
|
|
@@ -956,7 +932,9 @@ function SidebarComponent(props: any) {
|
|
|
956
932
|
return false;
|
|
957
933
|
}
|
|
958
934
|
|
|
959
|
-
const extension =
|
|
935
|
+
const extension = toolConfigRef.current.extensions.find(
|
|
936
|
+
ext => ext.id === extensionId
|
|
937
|
+
);
|
|
960
938
|
const extensionToolset = extension.toolsets.find(
|
|
961
939
|
(toolset: any) => toolset.id === toolsetId
|
|
962
940
|
);
|
|
@@ -988,7 +966,7 @@ function SidebarComponent(props: any) {
|
|
|
988
966
|
setToolSelections(newConfig);
|
|
989
967
|
} else {
|
|
990
968
|
const newConfig = { ...toolSelections };
|
|
991
|
-
const extension =
|
|
969
|
+
const extension = toolConfigRef.current.extensions.find(
|
|
992
970
|
ext => ext.id === extensionId
|
|
993
971
|
);
|
|
994
972
|
if (extensionId in newConfig.extensions) {
|
|
@@ -1030,7 +1008,7 @@ function SidebarComponent(props: any) {
|
|
|
1030
1008
|
}
|
|
1031
1009
|
setToolSelections(newConfig);
|
|
1032
1010
|
} else {
|
|
1033
|
-
const extension =
|
|
1011
|
+
const extension = toolConfigRef.current.extensions.find(
|
|
1034
1012
|
ext => ext.id === extensionId
|
|
1035
1013
|
);
|
|
1036
1014
|
const extensionToolset = extension.toolsets.find(
|
|
@@ -1101,30 +1079,38 @@ function SidebarComponent(props: any) {
|
|
|
1101
1079
|
|
|
1102
1080
|
useEffect(() => {
|
|
1103
1081
|
const prefixes: string[] = [];
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1082
|
+
prefixes.push('/clear');
|
|
1083
|
+
|
|
1084
|
+
if (chatMode === 'ask') {
|
|
1085
|
+
const chatParticipants = NBIAPI.config.chatParticipants;
|
|
1086
|
+
for (const participant of chatParticipants) {
|
|
1087
|
+
const id = participant.id;
|
|
1088
|
+
const commands = participant.commands;
|
|
1089
|
+
const participantPrefix = id === 'default' ? '' : `@${id}`;
|
|
1090
|
+
if (participantPrefix !== '') {
|
|
1091
|
+
prefixes.push(participantPrefix);
|
|
1092
|
+
}
|
|
1093
|
+
const commandPrefix =
|
|
1094
|
+
participantPrefix === '' ? '' : `${participantPrefix} `;
|
|
1095
|
+
for (const command of commands) {
|
|
1096
|
+
prefixes.push(`${commandPrefix}/${command}`);
|
|
1097
|
+
}
|
|
1098
|
+
}
|
|
1109
1099
|
}
|
|
1110
1100
|
|
|
1111
|
-
const
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
}
|
|
1119
|
-
const commandPrefix =
|
|
1120
|
-
participantPrefix === '' ? '' : `${participantPrefix} `;
|
|
1121
|
-
for (const command of commands) {
|
|
1122
|
-
prefixes.push(`${commandPrefix}/${command}`);
|
|
1101
|
+
const mcpServers = NBIAPI.config.toolConfig.mcpServers;
|
|
1102
|
+
const mcpServerSettings = NBIAPI.config.mcpServerSettings;
|
|
1103
|
+
for (const mcpServer of mcpServers) {
|
|
1104
|
+
if (mcpServerSettings[mcpServer.id]?.disabled !== true) {
|
|
1105
|
+
for (const prompt of mcpServer.prompts) {
|
|
1106
|
+
prefixes.push(`/mcp:${mcpServer.id}:${prompt.name}`);
|
|
1107
|
+
}
|
|
1123
1108
|
}
|
|
1124
1109
|
}
|
|
1110
|
+
|
|
1125
1111
|
setOriginalPrefixes(prefixes);
|
|
1126
1112
|
setPrefixSuggestions(prefixes);
|
|
1127
|
-
}, [chatMode]);
|
|
1113
|
+
}, [chatMode, renderCount]);
|
|
1128
1114
|
|
|
1129
1115
|
useEffect(() => {
|
|
1130
1116
|
const fetchData = () => {
|
|
@@ -1160,11 +1146,41 @@ function SidebarComponent(props: any) {
|
|
|
1160
1146
|
}
|
|
1161
1147
|
};
|
|
1162
1148
|
|
|
1163
|
-
const applyPrefixSuggestion = (prefix: string) => {
|
|
1149
|
+
const applyPrefixSuggestion = async (prefix: string) => {
|
|
1150
|
+
let mcpArguments = '';
|
|
1151
|
+
if (prefix.startsWith('/mcp:')) {
|
|
1152
|
+
mcpArguments = ':';
|
|
1153
|
+
const serverId = prefix.split(':')[1];
|
|
1154
|
+
const promptName = prefix.split(':')[2];
|
|
1155
|
+
const promptConfig = NBIAPI.config.getMCPServerPrompt(
|
|
1156
|
+
serverId,
|
|
1157
|
+
promptName
|
|
1158
|
+
);
|
|
1159
|
+
if (
|
|
1160
|
+
promptConfig &&
|
|
1161
|
+
promptConfig.arguments &&
|
|
1162
|
+
promptConfig.arguments.length > 0
|
|
1163
|
+
) {
|
|
1164
|
+
const result = await props
|
|
1165
|
+
.getApp()
|
|
1166
|
+
.commands.execute('notebook-intelligence:show-form-input-dialog', {
|
|
1167
|
+
title: 'Input Parameters',
|
|
1168
|
+
fields: promptConfig.arguments
|
|
1169
|
+
});
|
|
1170
|
+
const argumentValues: string[] = [];
|
|
1171
|
+
for (const argument of promptConfig.arguments) {
|
|
1172
|
+
if (result[argument.name] !== undefined) {
|
|
1173
|
+
argumentValues.push(`${argument.name}=${result[argument.name]}`);
|
|
1174
|
+
}
|
|
1175
|
+
}
|
|
1176
|
+
mcpArguments = `(${argumentValues.join(', ')}):`;
|
|
1177
|
+
}
|
|
1178
|
+
}
|
|
1179
|
+
|
|
1164
1180
|
if (prefix.includes(prompt)) {
|
|
1165
|
-
setPrompt(`${prefix} `);
|
|
1181
|
+
setPrompt(`${prefix}${mcpArguments} `);
|
|
1166
1182
|
} else {
|
|
1167
|
-
setPrompt(`${prefix} ${prompt} `);
|
|
1183
|
+
setPrompt(`${prefix} ${prompt}${mcpArguments} `);
|
|
1168
1184
|
}
|
|
1169
1185
|
setShowPopover(false);
|
|
1170
1186
|
promptInputRef.current?.focus();
|
|
@@ -1194,7 +1210,16 @@ function SidebarComponent(props: any) {
|
|
|
1194
1210
|
|
|
1195
1211
|
const handleChatToolsButtonClick = async () => {
|
|
1196
1212
|
if (!showModeTools) {
|
|
1197
|
-
NBIAPI.fetchCapabilities()
|
|
1213
|
+
NBIAPI.fetchCapabilities().then(() => {
|
|
1214
|
+
toolConfigRef.current = NBIAPI.config.toolConfig;
|
|
1215
|
+
mcpServerSettingsRef.current = NBIAPI.config.mcpServerSettings;
|
|
1216
|
+
const newMcpServerEnabledState = mcpServerSettingsToEnabledState(
|
|
1217
|
+
toolConfigRef.current.mcpServers,
|
|
1218
|
+
mcpServerSettingsRef.current
|
|
1219
|
+
);
|
|
1220
|
+
setMCPServerEnabledState(newMcpServerEnabledState);
|
|
1221
|
+
setRenderCount(renderCount => renderCount + 1);
|
|
1222
|
+
});
|
|
1198
1223
|
}
|
|
1199
1224
|
setShowModeTools(!showModeTools);
|
|
1200
1225
|
};
|
|
@@ -1215,9 +1240,6 @@ function SidebarComponent(props: any) {
|
|
|
1215
1240
|
}
|
|
1216
1241
|
}
|
|
1217
1242
|
|
|
1218
|
-
const promptPrefix =
|
|
1219
|
-
promptPrefixParts.length > 0 ? promptPrefixParts.join(' ') + ' ' : '';
|
|
1220
|
-
|
|
1221
1243
|
lastMessageId.current = UUID.uuid4();
|
|
1222
1244
|
lastRequestTime.current = new Date();
|
|
1223
1245
|
|
|
@@ -1289,7 +1311,7 @@ function SidebarComponent(props: any) {
|
|
|
1289
1311
|
type: RunChatCompletionType.Chat,
|
|
1290
1312
|
content: extractedPrompt,
|
|
1291
1313
|
language: activeDocInfo.language,
|
|
1292
|
-
filename: activeDocInfo.
|
|
1314
|
+
filename: activeDocInfo.filePath,
|
|
1293
1315
|
additionalContext,
|
|
1294
1316
|
chatMode,
|
|
1295
1317
|
toolSelections: toolSelections
|
|
@@ -1382,7 +1404,7 @@ function SidebarComponent(props: any) {
|
|
|
1382
1404
|
}
|
|
1383
1405
|
);
|
|
1384
1406
|
|
|
1385
|
-
const newPrompt =
|
|
1407
|
+
const newPrompt = '';
|
|
1386
1408
|
|
|
1387
1409
|
setPrompt(newPrompt);
|
|
1388
1410
|
filterPrefixSuggestions(newPrompt);
|
|
@@ -1711,32 +1733,21 @@ function SidebarComponent(props: any) {
|
|
|
1711
1733
|
return `${activeDocumentInfo.filename}${cellAndLineIndicator}`;
|
|
1712
1734
|
};
|
|
1713
1735
|
|
|
1714
|
-
const
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
NBIAPI.getLoginStatus() === GitHubCopilotLoginStatus.NotLoggedIn
|
|
1719
|
-
);
|
|
1720
|
-
};
|
|
1721
|
-
const getChatEnabled = () => {
|
|
1722
|
-
return nbiConfig.chatModel.provider === GITHUB_COPILOT_PROVIDER_ID
|
|
1723
|
-
? !getGHLoginRequired()
|
|
1724
|
-
: nbiConfig.llmProviders.find(
|
|
1725
|
-
provider => provider.id === nbiConfig.chatModel.provider
|
|
1726
|
-
);
|
|
1727
|
-
};
|
|
1728
|
-
|
|
1729
|
-
const [ghLoginRequired, setGHLoginRequired] = useState(getGHLoginRequired());
|
|
1730
|
-
const [chatEnabled, setChatEnabled] = useState(getChatEnabled());
|
|
1736
|
+
const [ghLoginRequired, setGHLoginRequired] = useState(
|
|
1737
|
+
NBIAPI.getGHLoginRequired()
|
|
1738
|
+
);
|
|
1739
|
+
const [chatEnabled, setChatEnabled] = useState(NBIAPI.getChatEnabled());
|
|
1731
1740
|
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1741
|
+
useEffect(() => {
|
|
1742
|
+
NBIAPI.configChanged.connect(() => {
|
|
1743
|
+
setGHLoginRequired(NBIAPI.getGHLoginRequired());
|
|
1744
|
+
setChatEnabled(NBIAPI.getChatEnabled());
|
|
1745
|
+
});
|
|
1746
|
+
}, []);
|
|
1736
1747
|
|
|
1737
1748
|
useEffect(() => {
|
|
1738
|
-
setGHLoginRequired(getGHLoginRequired());
|
|
1739
|
-
setChatEnabled(getChatEnabled());
|
|
1749
|
+
setGHLoginRequired(NBIAPI.getGHLoginRequired());
|
|
1750
|
+
setChatEnabled(NBIAPI.getChatEnabled());
|
|
1740
1751
|
}, [ghLoginStatus]);
|
|
1741
1752
|
|
|
1742
1753
|
return (
|
|
@@ -1876,7 +1887,7 @@ function SidebarComponent(props: any) {
|
|
|
1876
1887
|
if (event.target.value === 'ask') {
|
|
1877
1888
|
setToolSelections(toolSelectionsEmpty);
|
|
1878
1889
|
} else if (event.target.value === 'agent') {
|
|
1879
|
-
setToolSelections(toolSelectionsInitial);
|
|
1890
|
+
setToolSelections(structuredClone(toolSelectionsInitial));
|
|
1880
1891
|
}
|
|
1881
1892
|
setShowModeTools(false);
|
|
1882
1893
|
setChatMode(event.target.value);
|
|
@@ -1980,7 +1991,7 @@ function SidebarComponent(props: any) {
|
|
|
1980
1991
|
<div className="mode-tools-popover-tool-list">
|
|
1981
1992
|
<div className="mode-tools-group-header">Built-in</div>
|
|
1982
1993
|
<div className="mode-tools-group mode-tools-group-built-in">
|
|
1983
|
-
{
|
|
1994
|
+
{toolConfigRef.current.builtinToolsets.map((toolset: any) => (
|
|
1984
1995
|
<CheckBoxItem
|
|
1985
1996
|
key={toolset.id}
|
|
1986
1997
|
label={toolset.name}
|
|
@@ -1995,87 +2006,113 @@ function SidebarComponent(props: any) {
|
|
|
1995
2006
|
/>
|
|
1996
2007
|
))}
|
|
1997
2008
|
</div>
|
|
1998
|
-
{
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2009
|
+
{renderCount > 0 &&
|
|
2010
|
+
mcpServerEnabledState.size > 0 &&
|
|
2011
|
+
toolConfigRef.current.mcpServers.length > 0 && (
|
|
2012
|
+
<div className="mode-tools-group-header">
|
|
2013
|
+
MCP Server Tools
|
|
2014
|
+
</div>
|
|
2015
|
+
)}
|
|
2016
|
+
{renderCount > 0 &&
|
|
2017
|
+
toolConfigRef.current.mcpServers
|
|
2018
|
+
.filter(mcpServer =>
|
|
2019
|
+
mcpServerEnabledState.has(mcpServer.id)
|
|
2020
|
+
)
|
|
2021
|
+
.map((mcpServer, index: number) => (
|
|
2022
|
+
<div className="mode-tools-group">
|
|
2023
|
+
<CheckBoxItem
|
|
2024
|
+
label={mcpServer.id}
|
|
2025
|
+
header={true}
|
|
2026
|
+
checked={getMCPServerState(mcpServer.id)}
|
|
2027
|
+
onClick={() => onMCPServerClicked(mcpServer.id)}
|
|
2028
|
+
/>
|
|
2029
|
+
{mcpServer.tools
|
|
2030
|
+
.filter((tool: any) =>
|
|
2031
|
+
mcpServerEnabledState
|
|
2032
|
+
.get(mcpServer.id)
|
|
2033
|
+
.has(tool.name)
|
|
2020
2034
|
)
|
|
2021
|
-
|
|
2022
|
-
|
|
2035
|
+
.map((tool: any, index: number) => (
|
|
2036
|
+
<CheckBoxItem
|
|
2037
|
+
label={tool.name}
|
|
2038
|
+
title={tool.description}
|
|
2039
|
+
indent={1}
|
|
2040
|
+
checked={getMCPServerToolState(
|
|
2041
|
+
mcpServer.id,
|
|
2042
|
+
tool.name
|
|
2043
|
+
)}
|
|
2044
|
+
onClick={() =>
|
|
2045
|
+
setMCPServerToolState(
|
|
2046
|
+
mcpServer.id,
|
|
2047
|
+
tool.name,
|
|
2048
|
+
!getMCPServerToolState(
|
|
2049
|
+
mcpServer.id,
|
|
2050
|
+
tool.name
|
|
2051
|
+
)
|
|
2052
|
+
)
|
|
2053
|
+
}
|
|
2054
|
+
/>
|
|
2055
|
+
))}
|
|
2056
|
+
</div>
|
|
2023
2057
|
))}
|
|
2024
|
-
</div>
|
|
2025
|
-
))}
|
|
2026
2058
|
{hasExtensionTools && (
|
|
2027
2059
|
<div className="mode-tools-group-header">Extension tools</div>
|
|
2028
2060
|
)}
|
|
2029
|
-
{
|
|
2030
|
-
|
|
2031
|
-
<
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
label={`${toolset.name} (${toolset.id})`}
|
|
2041
|
-
title={toolset.description}
|
|
2042
|
-
indent={1}
|
|
2043
|
-
checked={getExtensionToolsetState(
|
|
2044
|
-
extension.id,
|
|
2045
|
-
toolset.id
|
|
2046
|
-
)}
|
|
2047
|
-
onClick={() =>
|
|
2048
|
-
onExtensionToolsetClicked(extension.id, toolset.id)
|
|
2049
|
-
}
|
|
2050
|
-
/>
|
|
2051
|
-
{toolset.tools.map((tool: any, index: number) => (
|
|
2061
|
+
{toolConfigRef.current.extensions.map(
|
|
2062
|
+
(extension, index: number) => (
|
|
2063
|
+
<div className="mode-tools-group">
|
|
2064
|
+
<CheckBoxItem
|
|
2065
|
+
label={`${extension.name} (${extension.id})`}
|
|
2066
|
+
header={true}
|
|
2067
|
+
checked={getExtensionState(extension.id)}
|
|
2068
|
+
onClick={() => onExtensionClicked(extension.id)}
|
|
2069
|
+
/>
|
|
2070
|
+
{extension.toolsets.map((toolset: any, index: number) => (
|
|
2071
|
+
<>
|
|
2052
2072
|
<CheckBoxItem
|
|
2053
|
-
label={
|
|
2054
|
-
title={
|
|
2055
|
-
indent={
|
|
2056
|
-
checked={
|
|
2073
|
+
label={`${toolset.name} (${toolset.id})`}
|
|
2074
|
+
title={toolset.description}
|
|
2075
|
+
indent={1}
|
|
2076
|
+
checked={getExtensionToolsetState(
|
|
2057
2077
|
extension.id,
|
|
2058
|
-
toolset.id
|
|
2059
|
-
tool.name
|
|
2078
|
+
toolset.id
|
|
2060
2079
|
)}
|
|
2061
2080
|
onClick={() =>
|
|
2062
|
-
|
|
2081
|
+
onExtensionToolsetClicked(
|
|
2082
|
+
extension.id,
|
|
2083
|
+
toolset.id
|
|
2084
|
+
)
|
|
2085
|
+
}
|
|
2086
|
+
/>
|
|
2087
|
+
{toolset.tools.map((tool: any, index: number) => (
|
|
2088
|
+
<CheckBoxItem
|
|
2089
|
+
label={tool.name}
|
|
2090
|
+
title={tool.description}
|
|
2091
|
+
indent={2}
|
|
2092
|
+
checked={getExtensionToolsetToolState(
|
|
2063
2093
|
extension.id,
|
|
2064
2094
|
toolset.id,
|
|
2065
|
-
tool.name
|
|
2066
|
-
|
|
2095
|
+
tool.name
|
|
2096
|
+
)}
|
|
2097
|
+
onClick={() =>
|
|
2098
|
+
setExtensionToolsetToolState(
|
|
2067
2099
|
extension.id,
|
|
2068
2100
|
toolset.id,
|
|
2069
|
-
tool.name
|
|
2101
|
+
tool.name,
|
|
2102
|
+
!getExtensionToolsetToolState(
|
|
2103
|
+
extension.id,
|
|
2104
|
+
toolset.id,
|
|
2105
|
+
tool.name
|
|
2106
|
+
)
|
|
2070
2107
|
)
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
)
|
|
2108
|
+
}
|
|
2109
|
+
/>
|
|
2110
|
+
))}
|
|
2111
|
+
</>
|
|
2112
|
+
))}
|
|
2113
|
+
</div>
|
|
2114
|
+
)
|
|
2115
|
+
)}
|
|
2079
2116
|
</div>
|
|
2080
2117
|
</div>
|
|
2081
2118
|
)}
|
|
@@ -2224,8 +2261,8 @@ function InlinePromptComponent(props: any) {
|
|
|
2224
2261
|
chatId: UUID.uuid4(),
|
|
2225
2262
|
type: RunChatCompletionType.GenerateCode,
|
|
2226
2263
|
content: prompt,
|
|
2227
|
-
language:
|
|
2228
|
-
filename:
|
|
2264
|
+
language: props.language || 'python',
|
|
2265
|
+
filename: props.filename || 'Untitled.ipynb',
|
|
2229
2266
|
prefix: props.prefix,
|
|
2230
2267
|
suffix: props.suffix,
|
|
2231
2268
|
existingCode: props.existingCode,
|
|
@@ -2498,526 +2535,75 @@ function GitHubCopilotLoginDialogBodyComponent(props: any) {
|
|
|
2498
2535
|
);
|
|
2499
2536
|
}
|
|
2500
2537
|
|
|
2501
|
-
|
|
2502
|
-
|
|
2503
|
-
|
|
2504
|
-
const [chatModels, setChatModels] = useState([]);
|
|
2505
|
-
const [inlineCompletionModels, setInlineCompletionModels] = useState([]);
|
|
2506
|
-
const [mcpServerNames, setMcpServerNames] = useState(
|
|
2507
|
-
nbiConfig.toolConfig.mcpServers?.map((server: any) => server.id) || []
|
|
2508
|
-
);
|
|
2509
|
-
|
|
2510
|
-
const handleSaveClick = async () => {
|
|
2511
|
-
const config: any = {
|
|
2512
|
-
default_chat_mode: defaultChatMode,
|
|
2513
|
-
chat_model: {
|
|
2514
|
-
provider: chatModelProvider,
|
|
2515
|
-
model: chatModel,
|
|
2516
|
-
properties: chatModelProperties
|
|
2517
|
-
},
|
|
2518
|
-
inline_completion_model: {
|
|
2519
|
-
provider: inlineCompletionModelProvider,
|
|
2520
|
-
model: inlineCompletionModel,
|
|
2521
|
-
properties: inlineCompletionModelProperties
|
|
2522
|
-
}
|
|
2523
|
-
};
|
|
2524
|
-
|
|
2525
|
-
if (
|
|
2526
|
-
chatModelProvider === 'github-copilot' ||
|
|
2527
|
-
inlineCompletionModelProvider === 'github-copilot'
|
|
2528
|
-
) {
|
|
2529
|
-
config.store_github_access_token = storeGitHubAccessToken;
|
|
2530
|
-
}
|
|
2531
|
-
|
|
2532
|
-
await NBIAPI.setConfig(config);
|
|
2533
|
-
|
|
2534
|
-
props.onSave();
|
|
2535
|
-
};
|
|
2536
|
-
|
|
2537
|
-
const handleRefreshOllamaModelListClick = async () => {
|
|
2538
|
-
await NBIAPI.updateOllamaModelList();
|
|
2539
|
-
updateModelOptionsForProvider(chatModelProvider, 'chat');
|
|
2540
|
-
};
|
|
2538
|
+
export class FormInputDialogBody extends ReactWidget {
|
|
2539
|
+
constructor(options: { fields: any; onDone: (formData: any) => void }) {
|
|
2540
|
+
super();
|
|
2541
2541
|
|
|
2542
|
-
|
|
2543
|
-
|
|
2544
|
-
|
|
2545
|
-
const [inlineCompletionModelProvider, setInlineCompletionModelProvider] =
|
|
2546
|
-
useState(nbiConfig.inlineCompletionModel.provider || 'none');
|
|
2547
|
-
const [defaultChatMode, setDefaultChatMode] = useState<string>(
|
|
2548
|
-
nbiConfig.defaultChatMode
|
|
2549
|
-
);
|
|
2550
|
-
const [chatModel, setChatModel] = useState<string>(nbiConfig.chatModel.model);
|
|
2551
|
-
const [chatModelProperties, setChatModelProperties] = useState<any[]>([]);
|
|
2552
|
-
const [inlineCompletionModelProperties, setInlineCompletionModelProperties] =
|
|
2553
|
-
useState<any[]>([]);
|
|
2554
|
-
const [inlineCompletionModel, setInlineCompletionModel] = useState(
|
|
2555
|
-
nbiConfig.inlineCompletionModel.model
|
|
2556
|
-
);
|
|
2557
|
-
const [storeGitHubAccessToken, setStoreGitHubAccessToken] = useState(
|
|
2558
|
-
nbiConfig.storeGitHubAccessToken
|
|
2559
|
-
);
|
|
2542
|
+
this._fields = options.fields || [];
|
|
2543
|
+
this._onDone = options.onDone || (() => {});
|
|
2544
|
+
}
|
|
2560
2545
|
|
|
2561
|
-
|
|
2562
|
-
|
|
2563
|
-
|
|
2564
|
-
|
|
2565
|
-
|
|
2566
|
-
|
|
2567
|
-
} else {
|
|
2568
|
-
setInlineCompletionModelProvider(providerId);
|
|
2569
|
-
}
|
|
2570
|
-
const models =
|
|
2571
|
-
modelType === 'chat'
|
|
2572
|
-
? nbiConfig.chatModels
|
|
2573
|
-
: nbiConfig.inlineCompletionModels;
|
|
2574
|
-
const selectedModelId =
|
|
2575
|
-
modelType === 'chat'
|
|
2576
|
-
? nbiConfig.chatModel.model
|
|
2577
|
-
: nbiConfig.inlineCompletionModel.model;
|
|
2578
|
-
|
|
2579
|
-
const providerModels = models.filter(
|
|
2580
|
-
(model: any) => model.provider === providerId
|
|
2581
|
-
);
|
|
2582
|
-
if (modelType === 'chat') {
|
|
2583
|
-
setChatModels(providerModels);
|
|
2584
|
-
} else {
|
|
2585
|
-
setInlineCompletionModels(providerModels);
|
|
2586
|
-
}
|
|
2587
|
-
let selectedModel = providerModels.find(
|
|
2588
|
-
(model: any) => model.id === selectedModelId
|
|
2546
|
+
render(): JSX.Element {
|
|
2547
|
+
return (
|
|
2548
|
+
<FormInputDialogBodyComponent
|
|
2549
|
+
fields={this._fields}
|
|
2550
|
+
onDone={this._onDone}
|
|
2551
|
+
/>
|
|
2589
2552
|
);
|
|
2590
|
-
|
|
2591
|
-
selectedModel = providerModels?.[0];
|
|
2592
|
-
}
|
|
2593
|
-
if (selectedModel) {
|
|
2594
|
-
if (modelType === 'chat') {
|
|
2595
|
-
setChatModel(selectedModel.id);
|
|
2596
|
-
setChatModelProperties(selectedModel.properties);
|
|
2597
|
-
} else {
|
|
2598
|
-
setInlineCompletionModel(selectedModel.id);
|
|
2599
|
-
setInlineCompletionModelProperties(selectedModel.properties);
|
|
2600
|
-
}
|
|
2601
|
-
} else {
|
|
2602
|
-
if (modelType === 'chat') {
|
|
2603
|
-
setChatModelProperties([]);
|
|
2604
|
-
} else {
|
|
2605
|
-
setInlineCompletionModelProperties([]);
|
|
2606
|
-
}
|
|
2607
|
-
}
|
|
2608
|
-
};
|
|
2553
|
+
}
|
|
2609
2554
|
|
|
2610
|
-
|
|
2611
|
-
|
|
2612
|
-
|
|
2613
|
-
value: string
|
|
2614
|
-
) => {
|
|
2615
|
-
const modelProperties =
|
|
2616
|
-
modelType === 'chat'
|
|
2617
|
-
? chatModelProperties
|
|
2618
|
-
: inlineCompletionModelProperties;
|
|
2619
|
-
const updatedProperties = modelProperties.map((property: any) => {
|
|
2620
|
-
if (property.id === propertyId) {
|
|
2621
|
-
return { ...property, value };
|
|
2622
|
-
}
|
|
2623
|
-
return property;
|
|
2624
|
-
});
|
|
2625
|
-
if (modelType === 'chat') {
|
|
2626
|
-
setChatModelProperties(updatedProperties);
|
|
2627
|
-
} else {
|
|
2628
|
-
setInlineCompletionModelProperties(updatedProperties);
|
|
2629
|
-
}
|
|
2630
|
-
};
|
|
2555
|
+
private _fields: any;
|
|
2556
|
+
private _onDone: (formData: any) => void;
|
|
2557
|
+
}
|
|
2631
2558
|
|
|
2632
|
-
|
|
2633
|
-
|
|
2634
|
-
setMcpServerNames(data.mcpServers?.map((server: any) => server.id) || []);
|
|
2635
|
-
};
|
|
2559
|
+
function FormInputDialogBodyComponent(props: any) {
|
|
2560
|
+
const [formData, setFormData] = useState<any>({});
|
|
2636
2561
|
|
|
2637
|
-
|
|
2638
|
-
|
|
2639
|
-
|
|
2640
|
-
inlineCompletionModelProvider,
|
|
2641
|
-
'inline-completion'
|
|
2642
|
-
);
|
|
2643
|
-
}, []);
|
|
2562
|
+
const handleInputChange = (event: any) => {
|
|
2563
|
+
setFormData({ ...formData, [event.target.name]: event.target.value });
|
|
2564
|
+
};
|
|
2644
2565
|
|
|
2645
2566
|
return (
|
|
2646
|
-
<div className="
|
|
2647
|
-
<div className="
|
|
2648
|
-
<div className="
|
|
2649
|
-
|
|
2650
|
-
<div className="model-config-section-body">
|
|
2651
|
-
<div className="model-config-section-row">
|
|
2652
|
-
<div className="model-config-section-column">
|
|
2653
|
-
<div>
|
|
2654
|
-
<select
|
|
2655
|
-
className="jp-mod-styled"
|
|
2656
|
-
value={defaultChatMode}
|
|
2657
|
-
onChange={event => setDefaultChatMode(event.target.value)}
|
|
2658
|
-
>
|
|
2659
|
-
<option value="ask">Ask</option>
|
|
2660
|
-
<option value="agent">Agent</option>
|
|
2661
|
-
</select>
|
|
2662
|
-
</div>
|
|
2663
|
-
</div>
|
|
2664
|
-
<div className="model-config-section-column"> </div>
|
|
2665
|
-
</div>
|
|
2666
|
-
</div>
|
|
2667
|
-
</div>
|
|
2668
|
-
|
|
2669
|
-
<div className="model-config-section">
|
|
2670
|
-
<div className="model-config-section-header">Chat model</div>
|
|
2671
|
-
<div className="model-config-section-body">
|
|
2672
|
-
<div className="model-config-section-row">
|
|
2673
|
-
<div className="model-config-section-column">
|
|
2674
|
-
<div>Provider</div>
|
|
2675
|
-
<div>
|
|
2676
|
-
<select
|
|
2677
|
-
className="jp-mod-styled"
|
|
2678
|
-
onChange={event =>
|
|
2679
|
-
updateModelOptionsForProvider(event.target.value, 'chat')
|
|
2680
|
-
}
|
|
2681
|
-
>
|
|
2682
|
-
{llmProviders.map((provider: any, index: number) => (
|
|
2683
|
-
<option
|
|
2684
|
-
key={index}
|
|
2685
|
-
value={provider.id}
|
|
2686
|
-
selected={provider.id === chatModelProvider}
|
|
2687
|
-
>
|
|
2688
|
-
{provider.name}
|
|
2689
|
-
</option>
|
|
2690
|
-
))}
|
|
2691
|
-
<option
|
|
2692
|
-
key={-1}
|
|
2693
|
-
value="none"
|
|
2694
|
-
selected={
|
|
2695
|
-
chatModelProvider === 'none' ||
|
|
2696
|
-
!llmProviders.find(
|
|
2697
|
-
provider => provider.id === chatModelProvider
|
|
2698
|
-
)
|
|
2699
|
-
}
|
|
2700
|
-
>
|
|
2701
|
-
None
|
|
2702
|
-
</option>
|
|
2703
|
-
</select>
|
|
2704
|
-
</div>
|
|
2705
|
-
</div>
|
|
2706
|
-
{!['openai-compatible', 'litellm-compatible', 'none'].includes(
|
|
2707
|
-
chatModelProvider
|
|
2708
|
-
) &&
|
|
2709
|
-
chatModels.length > 0 && (
|
|
2710
|
-
<div className="model-config-section-column">
|
|
2711
|
-
<div>Model</div>
|
|
2712
|
-
{![
|
|
2713
|
-
OPENAI_COMPATIBLE_CHAT_MODEL_ID,
|
|
2714
|
-
LITELLM_COMPATIBLE_CHAT_MODEL_ID
|
|
2715
|
-
].includes(chatModel) &&
|
|
2716
|
-
chatModels.length > 0 && (
|
|
2717
|
-
<div>
|
|
2718
|
-
<select
|
|
2719
|
-
className="jp-mod-styled"
|
|
2720
|
-
onChange={event => setChatModel(event.target.value)}
|
|
2721
|
-
>
|
|
2722
|
-
{chatModels.map((model: any, index: number) => (
|
|
2723
|
-
<option
|
|
2724
|
-
key={index}
|
|
2725
|
-
value={model.id}
|
|
2726
|
-
selected={model.id === chatModel}
|
|
2727
|
-
>
|
|
2728
|
-
{model.name}
|
|
2729
|
-
</option>
|
|
2730
|
-
))}
|
|
2731
|
-
</select>
|
|
2732
|
-
</div>
|
|
2733
|
-
)}
|
|
2734
|
-
</div>
|
|
2735
|
-
)}
|
|
2736
|
-
</div>
|
|
2737
|
-
|
|
2738
|
-
<div className="model-config-section-row">
|
|
2739
|
-
<div className="model-config-section-column">
|
|
2740
|
-
{chatModelProvider === 'ollama' && chatModels.length === 0 && (
|
|
2741
|
-
<div className="ollama-warning-message">
|
|
2742
|
-
No Ollama models found! Make sure{' '}
|
|
2743
|
-
<a href="https://ollama.com/" target="_blank">
|
|
2744
|
-
Ollama
|
|
2745
|
-
</a>{' '}
|
|
2746
|
-
is running and models are downloaded to your computer.{' '}
|
|
2747
|
-
<a
|
|
2748
|
-
href="javascript:void(0)"
|
|
2749
|
-
onClick={handleRefreshOllamaModelListClick}
|
|
2750
|
-
>
|
|
2751
|
-
Try again
|
|
2752
|
-
</a>{' '}
|
|
2753
|
-
once ready.
|
|
2754
|
-
</div>
|
|
2755
|
-
)}
|
|
2756
|
-
</div>
|
|
2757
|
-
</div>
|
|
2758
|
-
|
|
2759
|
-
<div className="model-config-section-row">
|
|
2760
|
-
<div className="model-config-section-column">
|
|
2761
|
-
{chatModelProperties.map((property: any, index: number) => (
|
|
2762
|
-
<div className="form-field-row" key={index}>
|
|
2763
|
-
<div className="form-field-description">
|
|
2764
|
-
{property.name} {property.optional ? '(optional)' : ''}
|
|
2765
|
-
</div>
|
|
2766
|
-
<input
|
|
2767
|
-
name="chat-model-id-input"
|
|
2768
|
-
placeholder={property.description}
|
|
2769
|
-
className="jp-mod-styled"
|
|
2770
|
-
spellCheck={false}
|
|
2771
|
-
value={property.value}
|
|
2772
|
-
onChange={event =>
|
|
2773
|
-
onModelPropertyChange(
|
|
2774
|
-
'chat',
|
|
2775
|
-
property.id,
|
|
2776
|
-
event.target.value
|
|
2777
|
-
)
|
|
2778
|
-
}
|
|
2779
|
-
/>
|
|
2780
|
-
</div>
|
|
2781
|
-
))}
|
|
2782
|
-
</div>
|
|
2783
|
-
</div>
|
|
2784
|
-
</div>
|
|
2785
|
-
</div>
|
|
2786
|
-
|
|
2787
|
-
<div className="model-config-section">
|
|
2788
|
-
<div className="model-config-section-header">Auto-complete model</div>
|
|
2789
|
-
<div className="model-config-section-body">
|
|
2790
|
-
<div className="model-config-section-row">
|
|
2791
|
-
<div className="model-config-section-column">
|
|
2792
|
-
<div>Provider</div>
|
|
2793
|
-
<div>
|
|
2794
|
-
<select
|
|
2795
|
-
className="jp-mod-styled"
|
|
2796
|
-
onChange={event =>
|
|
2797
|
-
updateModelOptionsForProvider(
|
|
2798
|
-
event.target.value,
|
|
2799
|
-
'inline-completion'
|
|
2800
|
-
)
|
|
2801
|
-
}
|
|
2802
|
-
>
|
|
2803
|
-
{llmProviders.map((provider: any, index: number) => (
|
|
2804
|
-
<option
|
|
2805
|
-
key={index}
|
|
2806
|
-
value={provider.id}
|
|
2807
|
-
selected={provider.id === inlineCompletionModelProvider}
|
|
2808
|
-
>
|
|
2809
|
-
{provider.name}
|
|
2810
|
-
</option>
|
|
2811
|
-
))}
|
|
2812
|
-
<option
|
|
2813
|
-
key={-1}
|
|
2814
|
-
value="none"
|
|
2815
|
-
selected={
|
|
2816
|
-
inlineCompletionModelProvider === 'none' ||
|
|
2817
|
-
!llmProviders.find(
|
|
2818
|
-
provider =>
|
|
2819
|
-
provider.id === inlineCompletionModelProvider
|
|
2820
|
-
)
|
|
2821
|
-
}
|
|
2822
|
-
>
|
|
2823
|
-
None
|
|
2824
|
-
</option>
|
|
2825
|
-
</select>
|
|
2826
|
-
</div>
|
|
2827
|
-
</div>
|
|
2828
|
-
{!['openai-compatible', 'litellm-compatible', 'none'].includes(
|
|
2829
|
-
inlineCompletionModelProvider
|
|
2830
|
-
) && (
|
|
2831
|
-
<div className="model-config-section-column">
|
|
2832
|
-
<div>Model</div>
|
|
2833
|
-
{![
|
|
2834
|
-
OPENAI_COMPATIBLE_INLINE_COMPLETION_MODEL_ID,
|
|
2835
|
-
LITELLM_COMPATIBLE_INLINE_COMPLETION_MODEL_ID
|
|
2836
|
-
].includes(inlineCompletionModel) && (
|
|
2837
|
-
<div>
|
|
2838
|
-
<select
|
|
2839
|
-
className="jp-mod-styled"
|
|
2840
|
-
onChange={event =>
|
|
2841
|
-
setInlineCompletionModel(event.target.value)
|
|
2842
|
-
}
|
|
2843
|
-
>
|
|
2844
|
-
{inlineCompletionModels.map(
|
|
2845
|
-
(model: any, index: number) => (
|
|
2846
|
-
<option
|
|
2847
|
-
key={index}
|
|
2848
|
-
value={model.id}
|
|
2849
|
-
selected={model.id === inlineCompletionModel}
|
|
2850
|
-
>
|
|
2851
|
-
{model.name}
|
|
2852
|
-
</option>
|
|
2853
|
-
)
|
|
2854
|
-
)}
|
|
2855
|
-
</select>
|
|
2856
|
-
</div>
|
|
2857
|
-
)}
|
|
2858
|
-
</div>
|
|
2859
|
-
)}
|
|
2860
|
-
</div>
|
|
2861
|
-
|
|
2862
|
-
<div className="model-config-section-row">
|
|
2863
|
-
<div className="model-config-section-column">
|
|
2864
|
-
{inlineCompletionModelProperties.map(
|
|
2865
|
-
(property: any, index: number) => (
|
|
2866
|
-
<div className="form-field-row" key={index}>
|
|
2867
|
-
<div className="form-field-description">
|
|
2868
|
-
{property.name} {property.optional ? '(optional)' : ''}
|
|
2869
|
-
</div>
|
|
2870
|
-
<input
|
|
2871
|
-
name="inline-completion-model-id-input"
|
|
2872
|
-
placeholder={property.description}
|
|
2873
|
-
className="jp-mod-styled"
|
|
2874
|
-
spellCheck={false}
|
|
2875
|
-
value={property.value}
|
|
2876
|
-
onChange={event =>
|
|
2877
|
-
onModelPropertyChange(
|
|
2878
|
-
'inline-completion',
|
|
2879
|
-
property.id,
|
|
2880
|
-
event.target.value
|
|
2881
|
-
)
|
|
2882
|
-
}
|
|
2883
|
-
/>
|
|
2884
|
-
</div>
|
|
2885
|
-
)
|
|
2886
|
-
)}
|
|
2887
|
-
</div>
|
|
2888
|
-
</div>
|
|
2889
|
-
</div>
|
|
2567
|
+
<div className="form-input-dialog-body">
|
|
2568
|
+
<div className="form-input-dialog-body-content">
|
|
2569
|
+
<div className="form-input-dialog-body-content-title">
|
|
2570
|
+
{props.title}
|
|
2890
2571
|
</div>
|
|
2891
|
-
|
|
2892
|
-
|
|
2893
|
-
|
|
2894
|
-
|
|
2895
|
-
|
|
2896
|
-
|
|
2897
|
-
<
|
|
2898
|
-
|
|
2899
|
-
|
|
2900
|
-
>
|
|
2901
|
-
{' '}
|
|
2902
|
-
<VscWarning
|
|
2903
|
-
className="access-token-warning"
|
|
2904
|
-
title="Click to learn more about security implications"
|
|
2905
|
-
/>
|
|
2906
|
-
</a>
|
|
2907
|
-
</div>
|
|
2908
|
-
<div className="model-config-section-body">
|
|
2909
|
-
<div className="model-config-section-row">
|
|
2910
|
-
<div className="model-config-section-column">
|
|
2911
|
-
<label>
|
|
2912
|
-
<input
|
|
2913
|
-
type="checkbox"
|
|
2914
|
-
checked={storeGitHubAccessToken}
|
|
2915
|
-
onChange={event => {
|
|
2916
|
-
setStoreGitHubAccessToken(event.target.checked);
|
|
2917
|
-
}}
|
|
2918
|
-
/>
|
|
2919
|
-
Remember my GitHub Copilot access token
|
|
2920
|
-
</label>
|
|
2921
|
-
</div>
|
|
2922
|
-
</div>
|
|
2923
|
-
</div>
|
|
2924
|
-
</div>
|
|
2925
|
-
)}
|
|
2926
|
-
|
|
2927
|
-
<div className="model-config-section">
|
|
2928
|
-
<div className="model-config-section-header">
|
|
2929
|
-
MCP Servers ({mcpServerNames.length}) [
|
|
2930
|
-
<a href="javascript:void(0)" onClick={props.onEditMCPConfigClicked}>
|
|
2931
|
-
edit
|
|
2932
|
-
</a>
|
|
2933
|
-
]
|
|
2934
|
-
</div>
|
|
2935
|
-
<div className="model-config-section-body">
|
|
2936
|
-
<div className="model-config-section-row">
|
|
2937
|
-
<div className="model-config-section-column">
|
|
2938
|
-
{mcpServerNames.length === 0 && (
|
|
2939
|
-
<div>
|
|
2940
|
-
No MCP servers found. Add MCP servers in the configuration
|
|
2941
|
-
file.
|
|
2942
|
-
</div>
|
|
2943
|
-
)}
|
|
2944
|
-
{mcpServerNames.length > 0 && (
|
|
2945
|
-
<div>{mcpServerNames.sort().join(', ')}</div>
|
|
2946
|
-
)}
|
|
2947
|
-
</div>
|
|
2948
|
-
<div
|
|
2949
|
-
className="model-config-section-column"
|
|
2950
|
-
style={{ flexGrow: 'initial' }}
|
|
2572
|
+
<div className="form-input-dialog-body-content-fields">
|
|
2573
|
+
{props.fields.map((field: any) => (
|
|
2574
|
+
<div
|
|
2575
|
+
className="form-input-dialog-body-content-field"
|
|
2576
|
+
key={field.name}
|
|
2577
|
+
>
|
|
2578
|
+
<label
|
|
2579
|
+
className="form-input-dialog-body-content-field-label jp-mod-styled"
|
|
2580
|
+
htmlFor={field.name}
|
|
2951
2581
|
>
|
|
2952
|
-
|
|
2953
|
-
|
|
2954
|
-
|
|
2955
|
-
|
|
2956
|
-
|
|
2957
|
-
|
|
2958
|
-
|
|
2582
|
+
{field.name}
|
|
2583
|
+
{field.required ? ' (required)' : ''}
|
|
2584
|
+
</label>
|
|
2585
|
+
<input
|
|
2586
|
+
className="form-input-dialog-body-content-field-input jp-mod-styled"
|
|
2587
|
+
type={field.type}
|
|
2588
|
+
id={field.name}
|
|
2589
|
+
name={field.name}
|
|
2590
|
+
onChange={handleInputChange}
|
|
2591
|
+
value={formData[field.name] || ''}
|
|
2592
|
+
/>
|
|
2959
2593
|
</div>
|
|
2960
|
-
|
|
2594
|
+
))}
|
|
2961
2595
|
</div>
|
|
2962
|
-
|
|
2963
|
-
|
|
2964
|
-
|
|
2965
|
-
|
|
2966
|
-
|
|
2967
|
-
|
|
2968
|
-
|
|
2969
|
-
|
|
2970
|
-
onClick={() => {
|
|
2971
|
-
navigator.clipboard.writeText(
|
|
2972
|
-
path.join(NBIAPI.config.userConfigDir, 'config.json')
|
|
2973
|
-
);
|
|
2974
|
-
return true;
|
|
2975
|
-
}}
|
|
2976
|
-
>
|
|
2977
|
-
{path.join(NBIAPI.config.userConfigDir, 'config.json')}{' '}
|
|
2978
|
-
<span
|
|
2979
|
-
className="copy-icon"
|
|
2980
|
-
dangerouslySetInnerHTML={{ __html: copySvgstr }}
|
|
2981
|
-
></span>
|
|
2982
|
-
</span>
|
|
2983
|
-
</div>
|
|
2984
|
-
</div>
|
|
2985
|
-
</div>
|
|
2986
|
-
<div className="model-config-section-header">
|
|
2987
|
-
MCP config file path
|
|
2988
|
-
</div>
|
|
2989
|
-
<div className="model-config-section-body">
|
|
2990
|
-
<div className="model-config-section-row">
|
|
2991
|
-
<div className="model-config-section-column">
|
|
2992
|
-
<span
|
|
2993
|
-
className="user-code-span"
|
|
2994
|
-
onClick={() => {
|
|
2995
|
-
navigator.clipboard.writeText(
|
|
2996
|
-
path.join(NBIAPI.config.userConfigDir, 'mcp.json')
|
|
2997
|
-
);
|
|
2998
|
-
return true;
|
|
2999
|
-
}}
|
|
3000
|
-
>
|
|
3001
|
-
{path.join(NBIAPI.config.userConfigDir, 'mcp.json')}{' '}
|
|
3002
|
-
<span
|
|
3003
|
-
className="copy-icon"
|
|
3004
|
-
dangerouslySetInnerHTML={{ __html: copySvgstr }}
|
|
3005
|
-
></span>
|
|
3006
|
-
</span>
|
|
3007
|
-
</div>
|
|
3008
|
-
</div>
|
|
2596
|
+
<div>
|
|
2597
|
+
<div style={{ marginTop: '10px' }}>
|
|
2598
|
+
<button
|
|
2599
|
+
className="jp-Dialog-button jp-mod-accept jp-mod-styled"
|
|
2600
|
+
onClick={() => props.onDone(formData)}
|
|
2601
|
+
>
|
|
2602
|
+
<div className="jp-Dialog-buttonLabel">Done</div>
|
|
2603
|
+
</button>
|
|
3009
2604
|
</div>
|
|
3010
2605
|
</div>
|
|
3011
2606
|
</div>
|
|
3012
|
-
|
|
3013
|
-
<div className="config-dialog-footer">
|
|
3014
|
-
<button
|
|
3015
|
-
className="jp-Dialog-button jp-mod-accept jp-mod-styled"
|
|
3016
|
-
onClick={handleSaveClick}
|
|
3017
|
-
>
|
|
3018
|
-
<div className="jp-Dialog-buttonLabel">Save</div>
|
|
3019
|
-
</button>
|
|
3020
|
-
</div>
|
|
3021
2607
|
</div>
|
|
3022
2608
|
);
|
|
3023
2609
|
}
|