@notebook-intelligence/notebook-intelligence 2.4.1 → 2.5.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 +17 -111
- package/lib/api.d.ts +2 -1
- package/lib/api.js +31 -15
- package/lib/chat-sidebar.d.ts +0 -9
- package/lib/chat-sidebar.js +58 -293
- 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 +26 -21
- package/lib/tokens.d.ts +11 -1
- package/lib/tokens.js +11 -0
- package/package.json +1 -1
- package/src/api.ts +34 -16
- package/src/chat-sidebar.tsx +159 -671
- 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 +29 -24
- package/src/tokens.ts +12 -1
- package/style/base.css +77 -2
package/src/chat-sidebar.tsx
CHANGED
|
@@ -46,24 +46,15 @@ import {
|
|
|
46
46
|
VscEyeClosed,
|
|
47
47
|
VscTriangleRight,
|
|
48
48
|
VscTriangleDown,
|
|
49
|
-
VscWarning,
|
|
50
49
|
VscSettingsGear,
|
|
51
50
|
VscPassFilled,
|
|
52
51
|
VscTools,
|
|
53
52
|
VscTrash
|
|
54
53
|
} from 'react-icons/vsc';
|
|
55
54
|
|
|
56
|
-
import { MdOutlineCheckBoxOutlineBlank, MdCheckBox } from 'react-icons/md';
|
|
57
|
-
|
|
58
55
|
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';
|
|
56
|
+
import { CheckBoxItem } from './components/checkbox';
|
|
57
|
+
import { mcpServerSettingsToEnabledState } from './components/mcp-util';
|
|
67
58
|
|
|
68
59
|
export enum RunChatCompletionType {
|
|
69
60
|
Chat,
|
|
@@ -264,30 +255,6 @@ export class GitHubCopilotLoginDialogBody extends ReactWidget {
|
|
|
264
255
|
private _onLoggedIn: () => void;
|
|
265
256
|
}
|
|
266
257
|
|
|
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
258
|
interface IChatMessageContent {
|
|
292
259
|
id: string;
|
|
293
260
|
type: ResponseStreamDataType;
|
|
@@ -684,30 +651,6 @@ async function submitCompletionRequest(
|
|
|
684
651
|
}
|
|
685
652
|
}
|
|
686
653
|
|
|
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
654
|
function SidebarComponent(props: any) {
|
|
712
655
|
const [chatMessages, setChatMessages] = useState<IChatMessage[]>([]);
|
|
713
656
|
const [prompt, setPrompt] = useState<string>('');
|
|
@@ -743,7 +686,9 @@ function SidebarComponent(props: any) {
|
|
|
743
686
|
const [selectedToolCount, setSelectedToolCount] = useState(0);
|
|
744
687
|
const [notebookExecuteToolSelected, setNotebookExecuteToolSelected] =
|
|
745
688
|
useState(false);
|
|
746
|
-
|
|
689
|
+
|
|
690
|
+
const [renderCount, setRenderCount] = useState(1);
|
|
691
|
+
const toolConfigRef = useRef({
|
|
747
692
|
builtinToolsets: [
|
|
748
693
|
{ id: BuiltinToolsetType.NotebookEdit, name: 'Notebook edit' },
|
|
749
694
|
{ id: BuiltinToolsetType.NotebookExecute, name: 'Notebook execute' }
|
|
@@ -751,6 +696,16 @@ function SidebarComponent(props: any) {
|
|
|
751
696
|
mcpServers: [],
|
|
752
697
|
extensions: []
|
|
753
698
|
});
|
|
699
|
+
const mcpServerSettingsRef = useRef(NBIAPI.config.mcpServerSettings);
|
|
700
|
+
const [mcpServerEnabledState, setMCPServerEnabledState] = useState(
|
|
701
|
+
new Map<string, Set<string>>(
|
|
702
|
+
mcpServerSettingsToEnabledState(
|
|
703
|
+
toolConfigRef.current.mcpServers,
|
|
704
|
+
mcpServerSettingsRef.current
|
|
705
|
+
)
|
|
706
|
+
)
|
|
707
|
+
);
|
|
708
|
+
|
|
754
709
|
const [showModeTools, setShowModeTools] = useState(false);
|
|
755
710
|
const toolSelectionsInitial: any = {
|
|
756
711
|
builtinToolsets: [BuiltinToolsetType.NotebookEdit],
|
|
@@ -762,25 +717,37 @@ function SidebarComponent(props: any) {
|
|
|
762
717
|
mcpServers: {},
|
|
763
718
|
extensions: {}
|
|
764
719
|
};
|
|
765
|
-
const [toolSelections, setToolSelections] = useState(
|
|
720
|
+
const [toolSelections, setToolSelections] = useState(
|
|
721
|
+
structuredClone(toolSelectionsInitial)
|
|
722
|
+
);
|
|
766
723
|
const [hasExtensionTools, setHasExtensionTools] = useState(false);
|
|
767
724
|
const [lastScrollTime, setLastScrollTime] = useState(0);
|
|
768
725
|
const [scrollPending, setScrollPending] = useState(false);
|
|
769
726
|
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
727
|
+
useEffect(() => {
|
|
728
|
+
NBIAPI.configChanged.connect(() => {
|
|
729
|
+
toolConfigRef.current = NBIAPI.config.toolConfig;
|
|
730
|
+
mcpServerSettingsRef.current = NBIAPI.config.mcpServerSettings;
|
|
731
|
+
const newMcpServerEnabledState = mcpServerSettingsToEnabledState(
|
|
732
|
+
toolConfigRef.current.mcpServers,
|
|
733
|
+
mcpServerSettingsRef.current
|
|
734
|
+
);
|
|
735
|
+
setMCPServerEnabledState(newMcpServerEnabledState);
|
|
736
|
+
setToolSelections(structuredClone(toolSelectionsInitial));
|
|
737
|
+
setRenderCount(renderCount => renderCount + 1);
|
|
738
|
+
});
|
|
739
|
+
}, []);
|
|
773
740
|
|
|
774
741
|
useEffect(() => {
|
|
775
742
|
let hasTools = false;
|
|
776
|
-
for (const extension of
|
|
743
|
+
for (const extension of toolConfigRef.current.extensions) {
|
|
777
744
|
if (extension.toolsets.length > 0) {
|
|
778
745
|
hasTools = true;
|
|
779
746
|
break;
|
|
780
747
|
}
|
|
781
748
|
}
|
|
782
749
|
setHasExtensionTools(hasTools);
|
|
783
|
-
}, [
|
|
750
|
+
}, [toolConfigRef.current]);
|
|
784
751
|
|
|
785
752
|
useEffect(() => {
|
|
786
753
|
const builtinToolSelCount = toolSelections.builtinToolsets.length;
|
|
@@ -862,7 +829,9 @@ function SidebarComponent(props: any) {
|
|
|
862
829
|
return false;
|
|
863
830
|
}
|
|
864
831
|
|
|
865
|
-
const mcpServer =
|
|
832
|
+
const mcpServer = toolConfigRef.current.mcpServers.find(
|
|
833
|
+
server => server.id === id
|
|
834
|
+
);
|
|
866
835
|
|
|
867
836
|
const selectedServerTools: string[] = toolSelections.mcpServers[id];
|
|
868
837
|
|
|
@@ -881,10 +850,16 @@ function SidebarComponent(props: any) {
|
|
|
881
850
|
delete newConfig.mcpServers[id];
|
|
882
851
|
setToolSelections(newConfig);
|
|
883
852
|
} else {
|
|
884
|
-
const mcpServer =
|
|
853
|
+
const mcpServer = toolConfigRef.current.mcpServers.find(
|
|
854
|
+
server => server.id === id
|
|
855
|
+
);
|
|
885
856
|
const newConfig = { ...toolSelections };
|
|
886
857
|
newConfig.mcpServers[id] = structuredClone(
|
|
887
|
-
mcpServer.tools
|
|
858
|
+
mcpServer.tools
|
|
859
|
+
.filter((tool: any) =>
|
|
860
|
+
mcpServerEnabledState.get(mcpServer.id).has(tool.name)
|
|
861
|
+
)
|
|
862
|
+
.map((tool: any) => tool.name)
|
|
888
863
|
);
|
|
889
864
|
setToolSelections(newConfig);
|
|
890
865
|
}
|
|
@@ -931,7 +906,7 @@ function SidebarComponent(props: any) {
|
|
|
931
906
|
return false;
|
|
932
907
|
}
|
|
933
908
|
|
|
934
|
-
const extension =
|
|
909
|
+
const extension = toolConfigRef.current.extensions.find(
|
|
935
910
|
extension => extension.id === extensionId
|
|
936
911
|
);
|
|
937
912
|
|
|
@@ -956,7 +931,9 @@ function SidebarComponent(props: any) {
|
|
|
956
931
|
return false;
|
|
957
932
|
}
|
|
958
933
|
|
|
959
|
-
const extension =
|
|
934
|
+
const extension = toolConfigRef.current.extensions.find(
|
|
935
|
+
ext => ext.id === extensionId
|
|
936
|
+
);
|
|
960
937
|
const extensionToolset = extension.toolsets.find(
|
|
961
938
|
(toolset: any) => toolset.id === toolsetId
|
|
962
939
|
);
|
|
@@ -988,7 +965,7 @@ function SidebarComponent(props: any) {
|
|
|
988
965
|
setToolSelections(newConfig);
|
|
989
966
|
} else {
|
|
990
967
|
const newConfig = { ...toolSelections };
|
|
991
|
-
const extension =
|
|
968
|
+
const extension = toolConfigRef.current.extensions.find(
|
|
992
969
|
ext => ext.id === extensionId
|
|
993
970
|
);
|
|
994
971
|
if (extensionId in newConfig.extensions) {
|
|
@@ -1030,7 +1007,7 @@ function SidebarComponent(props: any) {
|
|
|
1030
1007
|
}
|
|
1031
1008
|
setToolSelections(newConfig);
|
|
1032
1009
|
} else {
|
|
1033
|
-
const extension =
|
|
1010
|
+
const extension = toolConfigRef.current.extensions.find(
|
|
1034
1011
|
ext => ext.id === extensionId
|
|
1035
1012
|
);
|
|
1036
1013
|
const extensionToolset = extension.toolsets.find(
|
|
@@ -1194,7 +1171,16 @@ function SidebarComponent(props: any) {
|
|
|
1194
1171
|
|
|
1195
1172
|
const handleChatToolsButtonClick = async () => {
|
|
1196
1173
|
if (!showModeTools) {
|
|
1197
|
-
NBIAPI.fetchCapabilities()
|
|
1174
|
+
NBIAPI.fetchCapabilities().then(() => {
|
|
1175
|
+
toolConfigRef.current = NBIAPI.config.toolConfig;
|
|
1176
|
+
mcpServerSettingsRef.current = NBIAPI.config.mcpServerSettings;
|
|
1177
|
+
const newMcpServerEnabledState = mcpServerSettingsToEnabledState(
|
|
1178
|
+
toolConfigRef.current.mcpServers,
|
|
1179
|
+
mcpServerSettingsRef.current
|
|
1180
|
+
);
|
|
1181
|
+
setMCPServerEnabledState(newMcpServerEnabledState);
|
|
1182
|
+
setRenderCount(renderCount => renderCount + 1);
|
|
1183
|
+
});
|
|
1198
1184
|
}
|
|
1199
1185
|
setShowModeTools(!showModeTools);
|
|
1200
1186
|
};
|
|
@@ -1729,10 +1715,12 @@ function SidebarComponent(props: any) {
|
|
|
1729
1715
|
const [ghLoginRequired, setGHLoginRequired] = useState(getGHLoginRequired());
|
|
1730
1716
|
const [chatEnabled, setChatEnabled] = useState(getChatEnabled());
|
|
1731
1717
|
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1718
|
+
useEffect(() => {
|
|
1719
|
+
NBIAPI.configChanged.connect(() => {
|
|
1720
|
+
setGHLoginRequired(getGHLoginRequired());
|
|
1721
|
+
setChatEnabled(getChatEnabled());
|
|
1722
|
+
});
|
|
1723
|
+
}, []);
|
|
1736
1724
|
|
|
1737
1725
|
useEffect(() => {
|
|
1738
1726
|
setGHLoginRequired(getGHLoginRequired());
|
|
@@ -1876,7 +1864,7 @@ function SidebarComponent(props: any) {
|
|
|
1876
1864
|
if (event.target.value === 'ask') {
|
|
1877
1865
|
setToolSelections(toolSelectionsEmpty);
|
|
1878
1866
|
} else if (event.target.value === 'agent') {
|
|
1879
|
-
setToolSelections(toolSelectionsInitial);
|
|
1867
|
+
setToolSelections(structuredClone(toolSelectionsInitial));
|
|
1880
1868
|
}
|
|
1881
1869
|
setShowModeTools(false);
|
|
1882
1870
|
setChatMode(event.target.value);
|
|
@@ -1980,7 +1968,7 @@ function SidebarComponent(props: any) {
|
|
|
1980
1968
|
<div className="mode-tools-popover-tool-list">
|
|
1981
1969
|
<div className="mode-tools-group-header">Built-in</div>
|
|
1982
1970
|
<div className="mode-tools-group mode-tools-group-built-in">
|
|
1983
|
-
{
|
|
1971
|
+
{toolConfigRef.current.builtinToolsets.map((toolset: any) => (
|
|
1984
1972
|
<CheckBoxItem
|
|
1985
1973
|
key={toolset.id}
|
|
1986
1974
|
label={toolset.name}
|
|
@@ -1995,87 +1983,111 @@ function SidebarComponent(props: any) {
|
|
|
1995
1983
|
/>
|
|
1996
1984
|
))}
|
|
1997
1985
|
</div>
|
|
1998
|
-
{
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
1986
|
+
{renderCount > 0 &&
|
|
1987
|
+
mcpServerEnabledState.size > 0 &&
|
|
1988
|
+
toolConfigRef.current.mcpServers.length > 0 && (
|
|
1989
|
+
<div className="mode-tools-group-header">MCP Servers</div>
|
|
1990
|
+
)}
|
|
1991
|
+
{renderCount > 0 &&
|
|
1992
|
+
toolConfigRef.current.mcpServers
|
|
1993
|
+
.filter(mcpServer =>
|
|
1994
|
+
mcpServerEnabledState.has(mcpServer.id)
|
|
1995
|
+
)
|
|
1996
|
+
.map((mcpServer, index: number) => (
|
|
1997
|
+
<div className="mode-tools-group">
|
|
1998
|
+
<CheckBoxItem
|
|
1999
|
+
label={mcpServer.id}
|
|
2000
|
+
header={true}
|
|
2001
|
+
checked={getMCPServerState(mcpServer.id)}
|
|
2002
|
+
onClick={() => onMCPServerClicked(mcpServer.id)}
|
|
2003
|
+
/>
|
|
2004
|
+
{mcpServer.tools
|
|
2005
|
+
.filter((tool: any) =>
|
|
2006
|
+
mcpServerEnabledState
|
|
2007
|
+
.get(mcpServer.id)
|
|
2008
|
+
.has(tool.name)
|
|
2020
2009
|
)
|
|
2021
|
-
|
|
2022
|
-
|
|
2010
|
+
.map((tool: any, index: number) => (
|
|
2011
|
+
<CheckBoxItem
|
|
2012
|
+
label={tool.name}
|
|
2013
|
+
title={tool.description}
|
|
2014
|
+
indent={1}
|
|
2015
|
+
checked={getMCPServerToolState(
|
|
2016
|
+
mcpServer.id,
|
|
2017
|
+
tool.name
|
|
2018
|
+
)}
|
|
2019
|
+
onClick={() =>
|
|
2020
|
+
setMCPServerToolState(
|
|
2021
|
+
mcpServer.id,
|
|
2022
|
+
tool.name,
|
|
2023
|
+
!getMCPServerToolState(
|
|
2024
|
+
mcpServer.id,
|
|
2025
|
+
tool.name
|
|
2026
|
+
)
|
|
2027
|
+
)
|
|
2028
|
+
}
|
|
2029
|
+
/>
|
|
2030
|
+
))}
|
|
2031
|
+
</div>
|
|
2023
2032
|
))}
|
|
2024
|
-
</div>
|
|
2025
|
-
))}
|
|
2026
2033
|
{hasExtensionTools && (
|
|
2027
2034
|
<div className="mode-tools-group-header">Extension tools</div>
|
|
2028
2035
|
)}
|
|
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) => (
|
|
2036
|
+
{toolConfigRef.current.extensions.map(
|
|
2037
|
+
(extension, index: number) => (
|
|
2038
|
+
<div className="mode-tools-group">
|
|
2039
|
+
<CheckBoxItem
|
|
2040
|
+
label={`${extension.name} (${extension.id})`}
|
|
2041
|
+
header={true}
|
|
2042
|
+
checked={getExtensionState(extension.id)}
|
|
2043
|
+
onClick={() => onExtensionClicked(extension.id)}
|
|
2044
|
+
/>
|
|
2045
|
+
{extension.toolsets.map((toolset: any, index: number) => (
|
|
2046
|
+
<>
|
|
2052
2047
|
<CheckBoxItem
|
|
2053
|
-
label={
|
|
2054
|
-
title={
|
|
2055
|
-
indent={
|
|
2056
|
-
checked={
|
|
2048
|
+
label={`${toolset.name} (${toolset.id})`}
|
|
2049
|
+
title={toolset.description}
|
|
2050
|
+
indent={1}
|
|
2051
|
+
checked={getExtensionToolsetState(
|
|
2057
2052
|
extension.id,
|
|
2058
|
-
toolset.id
|
|
2059
|
-
tool.name
|
|
2053
|
+
toolset.id
|
|
2060
2054
|
)}
|
|
2061
2055
|
onClick={() =>
|
|
2062
|
-
|
|
2056
|
+
onExtensionToolsetClicked(
|
|
2057
|
+
extension.id,
|
|
2058
|
+
toolset.id
|
|
2059
|
+
)
|
|
2060
|
+
}
|
|
2061
|
+
/>
|
|
2062
|
+
{toolset.tools.map((tool: any, index: number) => (
|
|
2063
|
+
<CheckBoxItem
|
|
2064
|
+
label={tool.name}
|
|
2065
|
+
title={tool.description}
|
|
2066
|
+
indent={2}
|
|
2067
|
+
checked={getExtensionToolsetToolState(
|
|
2063
2068
|
extension.id,
|
|
2064
2069
|
toolset.id,
|
|
2065
|
-
tool.name
|
|
2066
|
-
|
|
2070
|
+
tool.name
|
|
2071
|
+
)}
|
|
2072
|
+
onClick={() =>
|
|
2073
|
+
setExtensionToolsetToolState(
|
|
2067
2074
|
extension.id,
|
|
2068
2075
|
toolset.id,
|
|
2069
|
-
tool.name
|
|
2076
|
+
tool.name,
|
|
2077
|
+
!getExtensionToolsetToolState(
|
|
2078
|
+
extension.id,
|
|
2079
|
+
toolset.id,
|
|
2080
|
+
tool.name
|
|
2081
|
+
)
|
|
2070
2082
|
)
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
)
|
|
2083
|
+
}
|
|
2084
|
+
/>
|
|
2085
|
+
))}
|
|
2086
|
+
</>
|
|
2087
|
+
))}
|
|
2088
|
+
</div>
|
|
2089
|
+
)
|
|
2090
|
+
)}
|
|
2079
2091
|
</div>
|
|
2080
2092
|
</div>
|
|
2081
2093
|
)}
|
|
@@ -2497,527 +2509,3 @@ function GitHubCopilotLoginDialogBodyComponent(props: any) {
|
|
|
2497
2509
|
</div>
|
|
2498
2510
|
);
|
|
2499
2511
|
}
|
|
2500
|
-
|
|
2501
|
-
function ConfigurationDialogBodyComponent(props: any) {
|
|
2502
|
-
const nbiConfig = NBIAPI.config;
|
|
2503
|
-
const llmProviders = nbiConfig.llmProviders;
|
|
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
|
-
};
|
|
2541
|
-
|
|
2542
|
-
const [chatModelProvider, setChatModelProvider] = useState(
|
|
2543
|
-
nbiConfig.chatModel.provider || 'none'
|
|
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
|
-
);
|
|
2560
|
-
|
|
2561
|
-
const updateModelOptionsForProvider = (
|
|
2562
|
-
providerId: string,
|
|
2563
|
-
modelType: 'chat' | 'inline-completion'
|
|
2564
|
-
) => {
|
|
2565
|
-
if (modelType === 'chat') {
|
|
2566
|
-
setChatModelProvider(providerId);
|
|
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
|
|
2589
|
-
);
|
|
2590
|
-
if (!selectedModel) {
|
|
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
|
-
};
|
|
2609
|
-
|
|
2610
|
-
const onModelPropertyChange = (
|
|
2611
|
-
modelType: 'chat' | 'inline-completion',
|
|
2612
|
-
propertyId: string,
|
|
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
|
-
};
|
|
2631
|
-
|
|
2632
|
-
const handleReloadMCPServersClick = async () => {
|
|
2633
|
-
const data = await NBIAPI.reloadMCPServerList();
|
|
2634
|
-
setMcpServerNames(data.mcpServers?.map((server: any) => server.id) || []);
|
|
2635
|
-
};
|
|
2636
|
-
|
|
2637
|
-
useEffect(() => {
|
|
2638
|
-
updateModelOptionsForProvider(chatModelProvider, 'chat');
|
|
2639
|
-
updateModelOptionsForProvider(
|
|
2640
|
-
inlineCompletionModelProvider,
|
|
2641
|
-
'inline-completion'
|
|
2642
|
-
);
|
|
2643
|
-
}, []);
|
|
2644
|
-
|
|
2645
|
-
return (
|
|
2646
|
-
<div className="config-dialog">
|
|
2647
|
-
<div className="config-dialog-body">
|
|
2648
|
-
<div className="model-config-section">
|
|
2649
|
-
<div className="model-config-section-header">Default chat mode</div>
|
|
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>
|
|
2890
|
-
</div>
|
|
2891
|
-
|
|
2892
|
-
{(chatModelProvider === 'github-copilot' ||
|
|
2893
|
-
inlineCompletionModelProvider === 'github-copilot') && (
|
|
2894
|
-
<div className="model-config-section">
|
|
2895
|
-
<div className="model-config-section-header access-token-config-header">
|
|
2896
|
-
GitHub Copilot login{' '}
|
|
2897
|
-
<a
|
|
2898
|
-
href="https://github.com/notebook-intelligence/notebook-intelligence/blob/main/README.md#remembering-github-copilot-login"
|
|
2899
|
-
target="_blank"
|
|
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' }}
|
|
2951
|
-
>
|
|
2952
|
-
<button
|
|
2953
|
-
className="jp-Dialog-button jp-mod-reject jp-mod-styled"
|
|
2954
|
-
onClick={handleReloadMCPServersClick}
|
|
2955
|
-
>
|
|
2956
|
-
<div className="jp-Dialog-buttonLabel">Reload</div>
|
|
2957
|
-
</button>
|
|
2958
|
-
</div>
|
|
2959
|
-
</div>
|
|
2960
|
-
</div>
|
|
2961
|
-
</div>
|
|
2962
|
-
|
|
2963
|
-
<div className="model-config-section">
|
|
2964
|
-
<div className="model-config-section-header">Config file path</div>
|
|
2965
|
-
<div className="model-config-section-body">
|
|
2966
|
-
<div className="model-config-section-row">
|
|
2967
|
-
<div className="model-config-section-column">
|
|
2968
|
-
<span
|
|
2969
|
-
className="user-code-span"
|
|
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>
|
|
3009
|
-
</div>
|
|
3010
|
-
</div>
|
|
3011
|
-
</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
|
-
</div>
|
|
3022
|
-
);
|
|
3023
|
-
}
|