@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.
@@ -4,20 +4,16 @@ import { ReactWidget } from '@jupyterlab/apputils';
4
4
  import { UUID } from '@lumino/coreutils';
5
5
  import * as monaco from 'monaco-editor/esm/vs/editor/editor.api.js';
6
6
  import { NBIAPI, GitHubCopilotLoginStatus } from './api';
7
- import { BackendMessageType, BuiltinToolsetType, ContextType, GITHUB_COPILOT_PROVIDER_ID, RequestDataType, ResponseStreamDataType, TelemetryEventType } from './tokens';
7
+ import { BackendMessageType, BuiltinToolsetType, ContextType, RequestDataType, ResponseStreamDataType, TelemetryEventType } from './tokens';
8
8
  import { MarkdownRenderer as OriginalMarkdownRenderer } from './markdown-renderer';
9
9
  const MarkdownRenderer = memo(OriginalMarkdownRenderer);
10
10
  import copySvgstr from '../style/icons/copy.svg';
11
11
  import copilotSvgstr from '../style/icons/copilot.svg';
12
12
  import copilotWarningSvgstr from '../style/icons/copilot-warning.svg';
13
- import { VscSend, VscStopCircle, VscEye, VscEyeClosed, VscTriangleRight, VscTriangleDown, VscWarning, VscSettingsGear, VscPassFilled, VscTools, VscTrash } from 'react-icons/vsc';
14
- import { MdOutlineCheckBoxOutlineBlank, MdCheckBox } from 'react-icons/md';
13
+ import { VscSend, VscStopCircle, VscEye, VscEyeClosed, VscTriangleRight, VscTriangleDown, VscSettingsGear, VscPassFilled, VscTools, VscTrash } from 'react-icons/vsc';
15
14
  import { extractLLMGeneratedCode, isDarkTheme } from './utils';
16
- import * as path from 'path';
17
- const OPENAI_COMPATIBLE_CHAT_MODEL_ID = 'openai-compatible-chat-model';
18
- const LITELLM_COMPATIBLE_CHAT_MODEL_ID = 'litellm-compatible-chat-model';
19
- const OPENAI_COMPATIBLE_INLINE_COMPLETION_MODEL_ID = 'openai-compatible-inline-completion-model';
20
- const LITELLM_COMPATIBLE_INLINE_COMPLETION_MODEL_ID = 'litellm-compatible-inline-completion-model';
15
+ import { CheckBoxItem } from './components/checkbox';
16
+ import { mcpServerSettingsToEnabledState } from './components/mcp-util';
21
17
  export var RunChatCompletionType;
22
18
  (function (RunChatCompletionType) {
23
19
  RunChatCompletionType[RunChatCompletionType["Chat"] = 0] = "Chat";
@@ -128,16 +124,6 @@ export class GitHubCopilotLoginDialogBody extends ReactWidget {
128
124
  return (React.createElement(GitHubCopilotLoginDialogBodyComponent, { onLoggedIn: () => this._onLoggedIn() }));
129
125
  }
130
126
  }
131
- export class ConfigurationDialogBody extends ReactWidget {
132
- constructor(options) {
133
- super();
134
- this._onEditMCPConfigClicked = options.onEditMCPConfigClicked;
135
- this._onSave = options.onSave;
136
- }
137
- render() {
138
- return (React.createElement(ConfigurationDialogBodyComponent, { onEditMCPConfigClicked: this._onEditMCPConfigClicked, onSave: this._onSave }));
139
- }
140
- }
141
127
  const answeredForms = new Map();
142
128
  function ChatResponseHTMLFrame(props) {
143
129
  const iframSrc = useMemo(() => URL.createObjectURL(new Blob([props.source], { type: 'text/html' })), []);
@@ -329,14 +315,6 @@ async function submitCompletionRequest(request, responseEmitter) {
329
315
  return NBIAPI.generateCode(request.chatId, request.content, request.prefix || '', request.suffix || '', request.existingCode || '', request.language || 'python', request.filename || 'Untitled.ipynb', responseEmitter);
330
316
  }
331
317
  }
332
- function CheckBoxItem(props) {
333
- const indent = props.indent || 0;
334
- return (React.createElement("div", { className: `checkbox-item checkbox-item-indent-${indent} ${props.header ? 'checkbox-item-header' : ''}`, title: props.title, onClick: event => props.onClick(event) },
335
- React.createElement("div", { className: "checkbox-item-toggle" },
336
- props.checked ? (React.createElement(MdCheckBox, { className: "checkbox-icon" })) : (React.createElement(MdOutlineCheckBoxOutlineBlank, { className: "checkbox-icon" })),
337
- props.label),
338
- props.title && (React.createElement("div", { className: "checkbox-item-description" }, props.title))));
339
- }
340
318
  function SidebarComponent(props) {
341
319
  const [chatMessages, setChatMessages] = useState([]);
342
320
  const [prompt, setPrompt] = useState('');
@@ -364,7 +342,8 @@ function SidebarComponent(props) {
364
342
  const [toolSelectionTitle, setToolSelectionTitle] = useState('Tool selection');
365
343
  const [selectedToolCount, setSelectedToolCount] = useState(0);
366
344
  const [notebookExecuteToolSelected, setNotebookExecuteToolSelected] = useState(false);
367
- const [toolConfig, setToolConfig] = useState({
345
+ const [renderCount, setRenderCount] = useState(1);
346
+ const toolConfigRef = useRef({
368
347
  builtinToolsets: [
369
348
  { id: BuiltinToolsetType.NotebookEdit, name: 'Notebook edit' },
370
349
  { id: BuiltinToolsetType.NotebookExecute, name: 'Notebook execute' }
@@ -372,6 +351,8 @@ function SidebarComponent(props) {
372
351
  mcpServers: [],
373
352
  extensions: []
374
353
  });
354
+ const mcpServerSettingsRef = useRef(NBIAPI.config.mcpServerSettings);
355
+ const [mcpServerEnabledState, setMCPServerEnabledState] = useState(new Map(mcpServerSettingsToEnabledState(toolConfigRef.current.mcpServers, mcpServerSettingsRef.current)));
375
356
  const [showModeTools, setShowModeTools] = useState(false);
376
357
  const toolSelectionsInitial = {
377
358
  builtinToolsets: [BuiltinToolsetType.NotebookEdit],
@@ -383,23 +364,30 @@ function SidebarComponent(props) {
383
364
  mcpServers: {},
384
365
  extensions: {}
385
366
  };
386
- const [toolSelections, setToolSelections] = useState(toolSelectionsInitial);
367
+ const [toolSelections, setToolSelections] = useState(structuredClone(toolSelectionsInitial));
387
368
  const [hasExtensionTools, setHasExtensionTools] = useState(false);
388
369
  const [lastScrollTime, setLastScrollTime] = useState(0);
389
370
  const [scrollPending, setScrollPending] = useState(false);
390
- NBIAPI.configChanged.connect(() => {
391
- setToolConfig(NBIAPI.config.toolConfig);
392
- });
371
+ useEffect(() => {
372
+ NBIAPI.configChanged.connect(() => {
373
+ toolConfigRef.current = NBIAPI.config.toolConfig;
374
+ mcpServerSettingsRef.current = NBIAPI.config.mcpServerSettings;
375
+ const newMcpServerEnabledState = mcpServerSettingsToEnabledState(toolConfigRef.current.mcpServers, mcpServerSettingsRef.current);
376
+ setMCPServerEnabledState(newMcpServerEnabledState);
377
+ setToolSelections(structuredClone(toolSelectionsInitial));
378
+ setRenderCount(renderCount => renderCount + 1);
379
+ });
380
+ }, []);
393
381
  useEffect(() => {
394
382
  let hasTools = false;
395
- for (const extension of toolConfig.extensions) {
383
+ for (const extension of toolConfigRef.current.extensions) {
396
384
  if (extension.toolsets.length > 0) {
397
385
  hasTools = true;
398
386
  break;
399
387
  }
400
388
  }
401
389
  setHasExtensionTools(hasTools);
402
- }, [toolConfig]);
390
+ }, [toolConfigRef.current]);
403
391
  useEffect(() => {
404
392
  const builtinToolSelCount = toolSelections.builtinToolsets.length;
405
393
  let mcpServerToolSelCount = 0;
@@ -462,7 +450,7 @@ function SidebarComponent(props) {
462
450
  if (!(id in toolSelections.mcpServers)) {
463
451
  return false;
464
452
  }
465
- const mcpServer = toolConfig.mcpServers.find(server => server.id === id);
453
+ const mcpServer = toolConfigRef.current.mcpServers.find(server => server.id === id);
466
454
  const selectedServerTools = toolSelections.mcpServers[id];
467
455
  for (const tool of mcpServer.tools) {
468
456
  if (!selectedServerTools.includes(tool.name)) {
@@ -478,9 +466,11 @@ function SidebarComponent(props) {
478
466
  setToolSelections(newConfig);
479
467
  }
480
468
  else {
481
- const mcpServer = toolConfig.mcpServers.find(server => server.id === id);
469
+ const mcpServer = toolConfigRef.current.mcpServers.find(server => server.id === id);
482
470
  const newConfig = { ...toolSelections };
483
- newConfig.mcpServers[id] = structuredClone(mcpServer.tools.map((tool) => tool.name));
471
+ newConfig.mcpServers[id] = structuredClone(mcpServer.tools
472
+ .filter((tool) => mcpServerEnabledState.get(mcpServer.id).has(tool.name))
473
+ .map((tool) => tool.name));
484
474
  setToolSelections(newConfig);
485
475
  }
486
476
  };
@@ -513,7 +503,7 @@ function SidebarComponent(props) {
513
503
  if (!(extensionId in toolSelections.extensions)) {
514
504
  return false;
515
505
  }
516
- const extension = toolConfig.extensions.find(extension => extension.id === extensionId);
506
+ const extension = toolConfigRef.current.extensions.find(extension => extension.id === extensionId);
517
507
  for (const toolset of extension.toolsets) {
518
508
  if (!getExtensionToolsetState(extensionId, toolset.id)) {
519
509
  return false;
@@ -528,7 +518,7 @@ function SidebarComponent(props) {
528
518
  if (!(toolsetId in toolSelections.extensions[extensionId])) {
529
519
  return false;
530
520
  }
531
- const extension = toolConfig.extensions.find(ext => ext.id === extensionId);
521
+ const extension = toolConfigRef.current.extensions.find(ext => ext.id === extensionId);
532
522
  const extensionToolset = extension.toolsets.find((toolset) => toolset.id === toolsetId);
533
523
  const selectedToolsetTools = toolSelections.extensions[extensionId][toolsetId];
534
524
  for (const tool of extensionToolset.tools) {
@@ -552,7 +542,7 @@ function SidebarComponent(props) {
552
542
  }
553
543
  else {
554
544
  const newConfig = { ...toolSelections };
555
- const extension = toolConfig.extensions.find(ext => ext.id === extensionId);
545
+ const extension = toolConfigRef.current.extensions.find(ext => ext.id === extensionId);
556
546
  if (extensionId in newConfig.extensions) {
557
547
  delete newConfig.extensions[extensionId];
558
548
  }
@@ -581,7 +571,7 @@ function SidebarComponent(props) {
581
571
  setToolSelections(newConfig);
582
572
  }
583
573
  else {
584
- const extension = toolConfig.extensions.find(ext => ext.id === extensionId);
574
+ const extension = toolConfigRef.current.extensions.find(ext => ext.id === extensionId);
585
575
  const extensionToolset = extension.toolsets.find((toolset) => toolset.id === toolsetId);
586
576
  const newConfig = { ...toolSelections };
587
577
  if (!(extensionId in newConfig.extensions)) {
@@ -623,29 +613,36 @@ function SidebarComponent(props) {
623
613
  setToolSelections(newConfig);
624
614
  };
625
615
  useEffect(() => {
616
+ var _a;
626
617
  const prefixes = [];
627
- if (chatMode !== 'ask') {
628
- prefixes.push('/clear');
629
- setOriginalPrefixes(prefixes);
630
- setPrefixSuggestions(prefixes);
631
- return;
632
- }
633
- const chatParticipants = NBIAPI.config.chatParticipants;
634
- for (const participant of chatParticipants) {
635
- const id = participant.id;
636
- const commands = participant.commands;
637
- const participantPrefix = id === 'default' ? '' : `@${id}`;
638
- if (participantPrefix !== '') {
639
- prefixes.push(participantPrefix);
618
+ prefixes.push('/clear');
619
+ if (chatMode === 'ask') {
620
+ const chatParticipants = NBIAPI.config.chatParticipants;
621
+ for (const participant of chatParticipants) {
622
+ const id = participant.id;
623
+ const commands = participant.commands;
624
+ const participantPrefix = id === 'default' ? '' : `@${id}`;
625
+ if (participantPrefix !== '') {
626
+ prefixes.push(participantPrefix);
627
+ }
628
+ const commandPrefix = participantPrefix === '' ? '' : `${participantPrefix} `;
629
+ for (const command of commands) {
630
+ prefixes.push(`${commandPrefix}/${command}`);
631
+ }
640
632
  }
641
- const commandPrefix = participantPrefix === '' ? '' : `${participantPrefix} `;
642
- for (const command of commands) {
643
- prefixes.push(`${commandPrefix}/${command}`);
633
+ }
634
+ const mcpServers = NBIAPI.config.toolConfig.mcpServers;
635
+ const mcpServerSettings = NBIAPI.config.mcpServerSettings;
636
+ for (const mcpServer of mcpServers) {
637
+ if (((_a = mcpServerSettings[mcpServer.id]) === null || _a === void 0 ? void 0 : _a.disabled) !== true) {
638
+ for (const prompt of mcpServer.prompts) {
639
+ prefixes.push(`/mcp:${mcpServer.id}:${prompt.name}`);
640
+ }
644
641
  }
645
642
  }
646
643
  setOriginalPrefixes(prefixes);
647
644
  setPrefixSuggestions(prefixes);
648
- }, [chatMode]);
645
+ }, [chatMode, renderCount]);
649
646
  useEffect(() => {
650
647
  const fetchData = () => {
651
648
  setGHLoginStatus(NBIAPI.getLoginStatus());
@@ -674,13 +671,37 @@ function SidebarComponent(props) {
674
671
  setShowPopover(false);
675
672
  }
676
673
  };
677
- const applyPrefixSuggestion = (prefix) => {
674
+ const applyPrefixSuggestion = async (prefix) => {
678
675
  var _a;
676
+ let mcpArguments = '';
677
+ if (prefix.startsWith('/mcp:')) {
678
+ mcpArguments = ':';
679
+ const serverId = prefix.split(':')[1];
680
+ const promptName = prefix.split(':')[2];
681
+ const promptConfig = NBIAPI.config.getMCPServerPrompt(serverId, promptName);
682
+ if (promptConfig &&
683
+ promptConfig.arguments &&
684
+ promptConfig.arguments.length > 0) {
685
+ const result = await props
686
+ .getApp()
687
+ .commands.execute('notebook-intelligence:show-form-input-dialog', {
688
+ title: 'Input Parameters',
689
+ fields: promptConfig.arguments
690
+ });
691
+ const argumentValues = [];
692
+ for (const argument of promptConfig.arguments) {
693
+ if (result[argument.name] !== undefined) {
694
+ argumentValues.push(`${argument.name}=${result[argument.name]}`);
695
+ }
696
+ }
697
+ mcpArguments = `(${argumentValues.join(', ')}):`;
698
+ }
699
+ }
679
700
  if (prefix.includes(prompt)) {
680
- setPrompt(`${prefix} `);
701
+ setPrompt(`${prefix}${mcpArguments} `);
681
702
  }
682
703
  else {
683
- setPrompt(`${prefix} ${prompt} `);
704
+ setPrompt(`${prefix} ${prompt}${mcpArguments} `);
684
705
  }
685
706
  setShowPopover(false);
686
707
  (_a = promptInputRef.current) === null || _a === void 0 ? void 0 : _a.focus();
@@ -707,7 +728,13 @@ function SidebarComponent(props) {
707
728
  };
708
729
  const handleChatToolsButtonClick = async () => {
709
730
  if (!showModeTools) {
710
- NBIAPI.fetchCapabilities();
731
+ NBIAPI.fetchCapabilities().then(() => {
732
+ toolConfigRef.current = NBIAPI.config.toolConfig;
733
+ mcpServerSettingsRef.current = NBIAPI.config.mcpServerSettings;
734
+ const newMcpServerEnabledState = mcpServerSettingsToEnabledState(toolConfigRef.current.mcpServers, mcpServerSettingsRef.current);
735
+ setMCPServerEnabledState(newMcpServerEnabledState);
736
+ setRenderCount(renderCount => renderCount + 1);
737
+ });
711
738
  }
712
739
  setShowModeTools(!showModeTools);
713
740
  };
@@ -725,7 +752,6 @@ function SidebarComponent(props) {
725
752
  }
726
753
  }
727
754
  }
728
- const promptPrefix = promptPrefixParts.length > 0 ? promptPrefixParts.join(' ') + ' ' : '';
729
755
  lastMessageId.current = UUID.uuid4();
730
756
  lastRequestTime.current = new Date();
731
757
  const newList = [
@@ -784,7 +810,7 @@ function SidebarComponent(props) {
784
810
  type: RunChatCompletionType.Chat,
785
811
  content: extractedPrompt,
786
812
  language: activeDocInfo.language,
787
- filename: activeDocInfo.filename,
813
+ filename: activeDocInfo.filePath,
788
814
  additionalContext,
789
815
  chatMode,
790
816
  toolSelections: toolSelections
@@ -867,7 +893,7 @@ function SidebarComponent(props) {
867
893
  ]);
868
894
  }
869
895
  });
870
- const newPrompt = prompt.startsWith('/settings') ? '' : promptPrefix;
896
+ const newPrompt = '';
871
897
  setPrompt(newPrompt);
872
898
  filterPrefixSuggestions(newPrompt);
873
899
  telemetryEmitter.emitTelemetryEvent({
@@ -1134,25 +1160,17 @@ function SidebarComponent(props) {
1134
1160
  }
1135
1161
  return `${activeDocumentInfo.filename}${cellAndLineIndicator}`;
1136
1162
  };
1137
- const nbiConfig = NBIAPI.config;
1138
- const getGHLoginRequired = () => {
1139
- return (nbiConfig.usingGitHubCopilotModel &&
1140
- NBIAPI.getLoginStatus() === GitHubCopilotLoginStatus.NotLoggedIn);
1141
- };
1142
- const getChatEnabled = () => {
1143
- return nbiConfig.chatModel.provider === GITHUB_COPILOT_PROVIDER_ID
1144
- ? !getGHLoginRequired()
1145
- : nbiConfig.llmProviders.find(provider => provider.id === nbiConfig.chatModel.provider);
1146
- };
1147
- const [ghLoginRequired, setGHLoginRequired] = useState(getGHLoginRequired());
1148
- const [chatEnabled, setChatEnabled] = useState(getChatEnabled());
1149
- NBIAPI.configChanged.connect(() => {
1150
- setGHLoginRequired(getGHLoginRequired());
1151
- setChatEnabled(getChatEnabled());
1152
- });
1163
+ const [ghLoginRequired, setGHLoginRequired] = useState(NBIAPI.getGHLoginRequired());
1164
+ const [chatEnabled, setChatEnabled] = useState(NBIAPI.getChatEnabled());
1153
1165
  useEffect(() => {
1154
- setGHLoginRequired(getGHLoginRequired());
1155
- setChatEnabled(getChatEnabled());
1166
+ NBIAPI.configChanged.connect(() => {
1167
+ setGHLoginRequired(NBIAPI.getGHLoginRequired());
1168
+ setChatEnabled(NBIAPI.getChatEnabled());
1169
+ });
1170
+ }, []);
1171
+ useEffect(() => {
1172
+ setGHLoginRequired(NBIAPI.getGHLoginRequired());
1173
+ setChatEnabled(NBIAPI.getChatEnabled());
1156
1174
  }, [ghLoginStatus]);
1157
1175
  return (React.createElement("div", { className: "sidebar" },
1158
1176
  React.createElement("div", { className: "sidebar-header" },
@@ -1200,7 +1218,7 @@ function SidebarComponent(props) {
1200
1218
  setToolSelections(toolSelectionsEmpty);
1201
1219
  }
1202
1220
  else if (event.target.value === 'agent') {
1203
- setToolSelections(toolSelectionsInitial);
1221
+ setToolSelections(structuredClone(toolSelectionsInitial));
1204
1222
  }
1205
1223
  setShowModeTools(false);
1206
1224
  setChatMode(event.target.value);
@@ -1239,15 +1257,24 @@ function SidebarComponent(props) {
1239
1257
  React.createElement("div", null, "Done"))),
1240
1258
  React.createElement("div", { className: "mode-tools-popover-tool-list" },
1241
1259
  React.createElement("div", { className: "mode-tools-group-header" }, "Built-in"),
1242
- React.createElement("div", { className: "mode-tools-group mode-tools-group-built-in" }, toolConfig.builtinToolsets.map((toolset) => (React.createElement(CheckBoxItem, { key: toolset.id, label: toolset.name, checked: getBuiltinToolsetState(toolset.id), header: true, onClick: () => {
1260
+ React.createElement("div", { className: "mode-tools-group mode-tools-group-built-in" }, toolConfigRef.current.builtinToolsets.map((toolset) => (React.createElement(CheckBoxItem, { key: toolset.id, label: toolset.name, checked: getBuiltinToolsetState(toolset.id), header: true, onClick: () => {
1243
1261
  setBuiltinToolsetState(toolset.id, !getBuiltinToolsetState(toolset.id));
1244
1262
  } })))),
1245
- toolConfig.mcpServers.length > 0 && (React.createElement("div", { className: "mode-tools-group-header" }, "MCP Servers")),
1246
- toolConfig.mcpServers.map((mcpServer, index) => (React.createElement("div", { className: "mode-tools-group" },
1247
- React.createElement(CheckBoxItem, { label: mcpServer.id, header: true, checked: getMCPServerState(mcpServer.id), onClick: () => onMCPServerClicked(mcpServer.id) }),
1248
- mcpServer.tools.map((tool, index) => (React.createElement(CheckBoxItem, { label: tool.name, title: tool.description, indent: 1, checked: getMCPServerToolState(mcpServer.id, tool.name), onClick: () => setMCPServerToolState(mcpServer.id, tool.name, !getMCPServerToolState(mcpServer.id, tool.name)) })))))),
1263
+ renderCount > 0 &&
1264
+ mcpServerEnabledState.size > 0 &&
1265
+ toolConfigRef.current.mcpServers.length > 0 && (React.createElement("div", { className: "mode-tools-group-header" }, "MCP Server Tools")),
1266
+ renderCount > 0 &&
1267
+ toolConfigRef.current.mcpServers
1268
+ .filter(mcpServer => mcpServerEnabledState.has(mcpServer.id))
1269
+ .map((mcpServer, index) => (React.createElement("div", { className: "mode-tools-group" },
1270
+ React.createElement(CheckBoxItem, { label: mcpServer.id, header: true, checked: getMCPServerState(mcpServer.id), onClick: () => onMCPServerClicked(mcpServer.id) }),
1271
+ mcpServer.tools
1272
+ .filter((tool) => mcpServerEnabledState
1273
+ .get(mcpServer.id)
1274
+ .has(tool.name))
1275
+ .map((tool, index) => (React.createElement(CheckBoxItem, { label: tool.name, title: tool.description, indent: 1, checked: getMCPServerToolState(mcpServer.id, tool.name), onClick: () => setMCPServerToolState(mcpServer.id, tool.name, !getMCPServerToolState(mcpServer.id, tool.name)) })))))),
1249
1276
  hasExtensionTools && (React.createElement("div", { className: "mode-tools-group-header" }, "Extension tools")),
1250
- toolConfig.extensions.map((extension, index) => (React.createElement("div", { className: "mode-tools-group" },
1277
+ toolConfigRef.current.extensions.map((extension, index) => (React.createElement("div", { className: "mode-tools-group" },
1251
1278
  React.createElement(CheckBoxItem, { label: `${extension.name} (${extension.id})`, header: true, checked: getExtensionState(extension.id), onClick: () => onExtensionClicked(extension.id) }),
1252
1279
  extension.toolsets.map((toolset, index) => (React.createElement(React.Fragment, null,
1253
1280
  React.createElement(CheckBoxItem, { label: `${toolset.name} (${toolset.id})`, title: toolset.description, indent: 1, checked: getExtensionToolsetState(extension.id, toolset.id), onClick: () => onExtensionToolsetClicked(extension.id, toolset.id) }),
@@ -1343,8 +1370,8 @@ function InlinePromptComponent(props) {
1343
1370
  chatId: UUID.uuid4(),
1344
1371
  type: RunChatCompletionType.GenerateCode,
1345
1372
  content: prompt,
1346
- language: undefined,
1347
- filename: undefined,
1373
+ language: props.language || 'python',
1374
+ filename: props.filename || 'Untitled.ipynb',
1348
1375
  prefix: props.prefix,
1349
1376
  suffix: props.suffix,
1350
1377
  existingCode: props.existingCode,
@@ -1501,245 +1528,31 @@ function GitHubCopilotLoginDialogBodyComponent(props) {
1501
1528
  React.createElement("button", { className: "jp-Dialog-button jp-mod-reject jp-mod-styled", onClick: handleLogoutClick },
1502
1529
  React.createElement("div", { className: "jp-Dialog-buttonLabel" }, "Cancel activation"))))));
1503
1530
  }
1504
- function ConfigurationDialogBodyComponent(props) {
1505
- var _a;
1506
- const nbiConfig = NBIAPI.config;
1507
- const llmProviders = nbiConfig.llmProviders;
1508
- const [chatModels, setChatModels] = useState([]);
1509
- const [inlineCompletionModels, setInlineCompletionModels] = useState([]);
1510
- const [mcpServerNames, setMcpServerNames] = useState(((_a = nbiConfig.toolConfig.mcpServers) === null || _a === void 0 ? void 0 : _a.map((server) => server.id)) || []);
1511
- const handleSaveClick = async () => {
1512
- const config = {
1513
- default_chat_mode: defaultChatMode,
1514
- chat_model: {
1515
- provider: chatModelProvider,
1516
- model: chatModel,
1517
- properties: chatModelProperties
1518
- },
1519
- inline_completion_model: {
1520
- provider: inlineCompletionModelProvider,
1521
- model: inlineCompletionModel,
1522
- properties: inlineCompletionModelProperties
1523
- }
1524
- };
1525
- if (chatModelProvider === 'github-copilot' ||
1526
- inlineCompletionModelProvider === 'github-copilot') {
1527
- config.store_github_access_token = storeGitHubAccessToken;
1528
- }
1529
- await NBIAPI.setConfig(config);
1530
- props.onSave();
1531
- };
1532
- const handleRefreshOllamaModelListClick = async () => {
1533
- await NBIAPI.updateOllamaModelList();
1534
- updateModelOptionsForProvider(chatModelProvider, 'chat');
1535
- };
1536
- const [chatModelProvider, setChatModelProvider] = useState(nbiConfig.chatModel.provider || 'none');
1537
- const [inlineCompletionModelProvider, setInlineCompletionModelProvider] = useState(nbiConfig.inlineCompletionModel.provider || 'none');
1538
- const [defaultChatMode, setDefaultChatMode] = useState(nbiConfig.defaultChatMode);
1539
- const [chatModel, setChatModel] = useState(nbiConfig.chatModel.model);
1540
- const [chatModelProperties, setChatModelProperties] = useState([]);
1541
- const [inlineCompletionModelProperties, setInlineCompletionModelProperties] = useState([]);
1542
- const [inlineCompletionModel, setInlineCompletionModel] = useState(nbiConfig.inlineCompletionModel.model);
1543
- const [storeGitHubAccessToken, setStoreGitHubAccessToken] = useState(nbiConfig.storeGitHubAccessToken);
1544
- const updateModelOptionsForProvider = (providerId, modelType) => {
1545
- if (modelType === 'chat') {
1546
- setChatModelProvider(providerId);
1547
- }
1548
- else {
1549
- setInlineCompletionModelProvider(providerId);
1550
- }
1551
- const models = modelType === 'chat'
1552
- ? nbiConfig.chatModels
1553
- : nbiConfig.inlineCompletionModels;
1554
- const selectedModelId = modelType === 'chat'
1555
- ? nbiConfig.chatModel.model
1556
- : nbiConfig.inlineCompletionModel.model;
1557
- const providerModels = models.filter((model) => model.provider === providerId);
1558
- if (modelType === 'chat') {
1559
- setChatModels(providerModels);
1560
- }
1561
- else {
1562
- setInlineCompletionModels(providerModels);
1563
- }
1564
- let selectedModel = providerModels.find((model) => model.id === selectedModelId);
1565
- if (!selectedModel) {
1566
- selectedModel = providerModels === null || providerModels === void 0 ? void 0 : providerModels[0];
1567
- }
1568
- if (selectedModel) {
1569
- if (modelType === 'chat') {
1570
- setChatModel(selectedModel.id);
1571
- setChatModelProperties(selectedModel.properties);
1572
- }
1573
- else {
1574
- setInlineCompletionModel(selectedModel.id);
1575
- setInlineCompletionModelProperties(selectedModel.properties);
1576
- }
1577
- }
1578
- else {
1579
- if (modelType === 'chat') {
1580
- setChatModelProperties([]);
1581
- }
1582
- else {
1583
- setInlineCompletionModelProperties([]);
1584
- }
1585
- }
1586
- };
1587
- const onModelPropertyChange = (modelType, propertyId, value) => {
1588
- const modelProperties = modelType === 'chat'
1589
- ? chatModelProperties
1590
- : inlineCompletionModelProperties;
1591
- const updatedProperties = modelProperties.map((property) => {
1592
- if (property.id === propertyId) {
1593
- return { ...property, value };
1594
- }
1595
- return property;
1596
- });
1597
- if (modelType === 'chat') {
1598
- setChatModelProperties(updatedProperties);
1599
- }
1600
- else {
1601
- setInlineCompletionModelProperties(updatedProperties);
1602
- }
1603
- };
1604
- const handleReloadMCPServersClick = async () => {
1605
- var _a;
1606
- const data = await NBIAPI.reloadMCPServerList();
1607
- setMcpServerNames(((_a = data.mcpServers) === null || _a === void 0 ? void 0 : _a.map((server) => server.id)) || []);
1531
+ export class FormInputDialogBody extends ReactWidget {
1532
+ constructor(options) {
1533
+ super();
1534
+ this._fields = options.fields || [];
1535
+ this._onDone = options.onDone || (() => { });
1536
+ }
1537
+ render() {
1538
+ return (React.createElement(FormInputDialogBodyComponent, { fields: this._fields, onDone: this._onDone }));
1539
+ }
1540
+ }
1541
+ function FormInputDialogBodyComponent(props) {
1542
+ const [formData, setFormData] = useState({});
1543
+ const handleInputChange = (event) => {
1544
+ setFormData({ ...formData, [event.target.name]: event.target.value });
1608
1545
  };
1609
- useEffect(() => {
1610
- updateModelOptionsForProvider(chatModelProvider, 'chat');
1611
- updateModelOptionsForProvider(inlineCompletionModelProvider, 'inline-completion');
1612
- }, []);
1613
- return (React.createElement("div", { className: "config-dialog" },
1614
- React.createElement("div", { className: "config-dialog-body" },
1615
- React.createElement("div", { className: "model-config-section" },
1616
- React.createElement("div", { className: "model-config-section-header" }, "Default chat mode"),
1617
- React.createElement("div", { className: "model-config-section-body" },
1618
- React.createElement("div", { className: "model-config-section-row" },
1619
- React.createElement("div", { className: "model-config-section-column" },
1620
- React.createElement("div", null,
1621
- React.createElement("select", { className: "jp-mod-styled", value: defaultChatMode, onChange: event => setDefaultChatMode(event.target.value) },
1622
- React.createElement("option", { value: "ask" }, "Ask"),
1623
- React.createElement("option", { value: "agent" }, "Agent")))),
1624
- React.createElement("div", { className: "model-config-section-column" }, " ")))),
1625
- React.createElement("div", { className: "model-config-section" },
1626
- React.createElement("div", { className: "model-config-section-header" }, "Chat model"),
1627
- React.createElement("div", { className: "model-config-section-body" },
1628
- React.createElement("div", { className: "model-config-section-row" },
1629
- React.createElement("div", { className: "model-config-section-column" },
1630
- React.createElement("div", null, "Provider"),
1631
- React.createElement("div", null,
1632
- React.createElement("select", { className: "jp-mod-styled", onChange: event => updateModelOptionsForProvider(event.target.value, 'chat') },
1633
- llmProviders.map((provider, index) => (React.createElement("option", { key: index, value: provider.id, selected: provider.id === chatModelProvider }, provider.name))),
1634
- React.createElement("option", { key: -1, value: "none", selected: chatModelProvider === 'none' ||
1635
- !llmProviders.find(provider => provider.id === chatModelProvider) }, "None")))),
1636
- !['openai-compatible', 'litellm-compatible', 'none'].includes(chatModelProvider) &&
1637
- chatModels.length > 0 && (React.createElement("div", { className: "model-config-section-column" },
1638
- React.createElement("div", null, "Model"),
1639
- ![
1640
- OPENAI_COMPATIBLE_CHAT_MODEL_ID,
1641
- LITELLM_COMPATIBLE_CHAT_MODEL_ID
1642
- ].includes(chatModel) &&
1643
- chatModels.length > 0 && (React.createElement("div", null,
1644
- React.createElement("select", { className: "jp-mod-styled", onChange: event => setChatModel(event.target.value) }, chatModels.map((model, index) => (React.createElement("option", { key: index, value: model.id, selected: model.id === chatModel }, model.name))))))))),
1645
- React.createElement("div", { className: "model-config-section-row" },
1646
- React.createElement("div", { className: "model-config-section-column" }, chatModelProvider === 'ollama' && chatModels.length === 0 && (React.createElement("div", { className: "ollama-warning-message" },
1647
- "No Ollama models found! Make sure",
1648
- ' ',
1649
- React.createElement("a", { href: "https://ollama.com/", target: "_blank" }, "Ollama"),
1650
- ' ',
1651
- "is running and models are downloaded to your computer.",
1652
- ' ',
1653
- React.createElement("a", { href: "javascript:void(0)", onClick: handleRefreshOllamaModelListClick }, "Try again"),
1654
- ' ',
1655
- "once ready.")))),
1656
- React.createElement("div", { className: "model-config-section-row" },
1657
- React.createElement("div", { className: "model-config-section-column" }, chatModelProperties.map((property, index) => (React.createElement("div", { className: "form-field-row", key: index },
1658
- React.createElement("div", { className: "form-field-description" },
1659
- property.name,
1660
- " ",
1661
- property.optional ? '(optional)' : ''),
1662
- React.createElement("input", { name: "chat-model-id-input", placeholder: property.description, className: "jp-mod-styled", spellCheck: false, value: property.value, onChange: event => onModelPropertyChange('chat', property.id, event.target.value) })))))))),
1663
- React.createElement("div", { className: "model-config-section" },
1664
- React.createElement("div", { className: "model-config-section-header" }, "Auto-complete model"),
1665
- React.createElement("div", { className: "model-config-section-body" },
1666
- React.createElement("div", { className: "model-config-section-row" },
1667
- React.createElement("div", { className: "model-config-section-column" },
1668
- React.createElement("div", null, "Provider"),
1669
- React.createElement("div", null,
1670
- React.createElement("select", { className: "jp-mod-styled", onChange: event => updateModelOptionsForProvider(event.target.value, 'inline-completion') },
1671
- llmProviders.map((provider, index) => (React.createElement("option", { key: index, value: provider.id, selected: provider.id === inlineCompletionModelProvider }, provider.name))),
1672
- React.createElement("option", { key: -1, value: "none", selected: inlineCompletionModelProvider === 'none' ||
1673
- !llmProviders.find(provider => provider.id === inlineCompletionModelProvider) }, "None")))),
1674
- !['openai-compatible', 'litellm-compatible', 'none'].includes(inlineCompletionModelProvider) && (React.createElement("div", { className: "model-config-section-column" },
1675
- React.createElement("div", null, "Model"),
1676
- ![
1677
- OPENAI_COMPATIBLE_INLINE_COMPLETION_MODEL_ID,
1678
- LITELLM_COMPATIBLE_INLINE_COMPLETION_MODEL_ID
1679
- ].includes(inlineCompletionModel) && (React.createElement("div", null,
1680
- React.createElement("select", { className: "jp-mod-styled", onChange: event => setInlineCompletionModel(event.target.value) }, inlineCompletionModels.map((model, index) => (React.createElement("option", { key: index, value: model.id, selected: model.id === inlineCompletionModel }, model.name))))))))),
1681
- React.createElement("div", { className: "model-config-section-row" },
1682
- React.createElement("div", { className: "model-config-section-column" }, inlineCompletionModelProperties.map((property, index) => (React.createElement("div", { className: "form-field-row", key: index },
1683
- React.createElement("div", { className: "form-field-description" },
1684
- property.name,
1685
- " ",
1686
- property.optional ? '(optional)' : ''),
1687
- React.createElement("input", { name: "inline-completion-model-id-input", placeholder: property.description, className: "jp-mod-styled", spellCheck: false, value: property.value, onChange: event => onModelPropertyChange('inline-completion', property.id, event.target.value) })))))))),
1688
- (chatModelProvider === 'github-copilot' ||
1689
- inlineCompletionModelProvider === 'github-copilot') && (React.createElement("div", { className: "model-config-section" },
1690
- React.createElement("div", { className: "model-config-section-header access-token-config-header" },
1691
- "GitHub Copilot login",
1692
- ' ',
1693
- React.createElement("a", { href: "https://github.com/notebook-intelligence/notebook-intelligence/blob/main/README.md#remembering-github-copilot-login", target: "_blank" },
1694
- ' ',
1695
- React.createElement(VscWarning, { className: "access-token-warning", title: "Click to learn more about security implications" }))),
1696
- React.createElement("div", { className: "model-config-section-body" },
1697
- React.createElement("div", { className: "model-config-section-row" },
1698
- React.createElement("div", { className: "model-config-section-column" },
1699
- React.createElement("label", null,
1700
- React.createElement("input", { type: "checkbox", checked: storeGitHubAccessToken, onChange: event => {
1701
- setStoreGitHubAccessToken(event.target.checked);
1702
- } }),
1703
- "Remember my GitHub Copilot access token")))))),
1704
- React.createElement("div", { className: "model-config-section" },
1705
- React.createElement("div", { className: "model-config-section-header" },
1706
- "MCP Servers (",
1707
- mcpServerNames.length,
1708
- ") [",
1709
- React.createElement("a", { href: "javascript:void(0)", onClick: props.onEditMCPConfigClicked }, "edit"),
1710
- "]"),
1711
- React.createElement("div", { className: "model-config-section-body" },
1712
- React.createElement("div", { className: "model-config-section-row" },
1713
- React.createElement("div", { className: "model-config-section-column" },
1714
- mcpServerNames.length === 0 && (React.createElement("div", null, "No MCP servers found. Add MCP servers in the configuration file.")),
1715
- mcpServerNames.length > 0 && (React.createElement("div", null, mcpServerNames.sort().join(', ')))),
1716
- React.createElement("div", { className: "model-config-section-column", style: { flexGrow: 'initial' } },
1717
- React.createElement("button", { className: "jp-Dialog-button jp-mod-reject jp-mod-styled", onClick: handleReloadMCPServersClick },
1718
- React.createElement("div", { className: "jp-Dialog-buttonLabel" }, "Reload")))))),
1719
- React.createElement("div", { className: "model-config-section" },
1720
- React.createElement("div", { className: "model-config-section-header" }, "Config file path"),
1721
- React.createElement("div", { className: "model-config-section-body" },
1722
- React.createElement("div", { className: "model-config-section-row" },
1723
- React.createElement("div", { className: "model-config-section-column" },
1724
- React.createElement("span", { className: "user-code-span", onClick: () => {
1725
- navigator.clipboard.writeText(path.join(NBIAPI.config.userConfigDir, 'config.json'));
1726
- return true;
1727
- } },
1728
- path.join(NBIAPI.config.userConfigDir, 'config.json'),
1729
- ' ',
1730
- React.createElement("span", { className: "copy-icon", dangerouslySetInnerHTML: { __html: copySvgstr } }))))),
1731
- React.createElement("div", { className: "model-config-section-header" }, "MCP config file path"),
1732
- React.createElement("div", { className: "model-config-section-body" },
1733
- React.createElement("div", { className: "model-config-section-row" },
1734
- React.createElement("div", { className: "model-config-section-column" },
1735
- React.createElement("span", { className: "user-code-span", onClick: () => {
1736
- navigator.clipboard.writeText(path.join(NBIAPI.config.userConfigDir, 'mcp.json'));
1737
- return true;
1738
- } },
1739
- path.join(NBIAPI.config.userConfigDir, 'mcp.json'),
1740
- ' ',
1741
- React.createElement("span", { className: "copy-icon", dangerouslySetInnerHTML: { __html: copySvgstr } }))))))),
1742
- React.createElement("div", { className: "config-dialog-footer" },
1743
- React.createElement("button", { className: "jp-Dialog-button jp-mod-accept jp-mod-styled", onClick: handleSaveClick },
1744
- React.createElement("div", { className: "jp-Dialog-buttonLabel" }, "Save")))));
1546
+ return (React.createElement("div", { className: "form-input-dialog-body" },
1547
+ React.createElement("div", { className: "form-input-dialog-body-content" },
1548
+ React.createElement("div", { className: "form-input-dialog-body-content-title" }, props.title),
1549
+ React.createElement("div", { className: "form-input-dialog-body-content-fields" }, props.fields.map((field) => (React.createElement("div", { className: "form-input-dialog-body-content-field", key: field.name },
1550
+ React.createElement("label", { className: "form-input-dialog-body-content-field-label jp-mod-styled", htmlFor: field.name },
1551
+ field.name,
1552
+ field.required ? ' (required)' : ''),
1553
+ React.createElement("input", { className: "form-input-dialog-body-content-field-input jp-mod-styled", type: field.type, id: field.name, name: field.name, onChange: handleInputChange, value: formData[field.name] || '' }))))),
1554
+ React.createElement("div", null,
1555
+ React.createElement("div", { style: { marginTop: '10px' } },
1556
+ React.createElement("button", { className: "jp-Dialog-button jp-mod-accept jp-mod-styled", onClick: () => props.onDone(formData) },
1557
+ React.createElement("div", { className: "jp-Dialog-buttonLabel" }, "Done")))))));
1745
1558
  }