@jupyterlite/ai 0.9.1 → 0.11.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.
Files changed (71) hide show
  1. package/README.md +5 -214
  2. package/lib/agent.d.ts +58 -66
  3. package/lib/agent.js +291 -310
  4. package/lib/approval-buttons.d.ts +19 -82
  5. package/lib/approval-buttons.js +36 -289
  6. package/lib/chat-model-registry.d.ts +6 -0
  7. package/lib/chat-model-registry.js +4 -1
  8. package/lib/chat-model.d.ts +26 -54
  9. package/lib/chat-model.js +277 -303
  10. package/lib/components/clear-button.d.ts +6 -1
  11. package/lib/components/clear-button.js +10 -6
  12. package/lib/components/completion-status.d.ts +5 -0
  13. package/lib/components/completion-status.js +5 -4
  14. package/lib/components/model-select.d.ts +6 -1
  15. package/lib/components/model-select.js +13 -16
  16. package/lib/components/stop-button.d.ts +6 -1
  17. package/lib/components/stop-button.js +12 -8
  18. package/lib/components/token-usage-display.d.ts +5 -0
  19. package/lib/components/token-usage-display.js +2 -2
  20. package/lib/components/tool-select.d.ts +6 -1
  21. package/lib/components/tool-select.js +10 -9
  22. package/lib/index.d.ts +1 -0
  23. package/lib/index.js +61 -81
  24. package/lib/models/settings-model.d.ts +1 -1
  25. package/lib/models/settings-model.js +40 -26
  26. package/lib/providers/built-in-providers.js +38 -19
  27. package/lib/providers/models.d.ts +3 -3
  28. package/lib/providers/provider-registry.d.ts +3 -4
  29. package/lib/providers/provider-registry.js +1 -4
  30. package/lib/tokens.d.ts +5 -6
  31. package/lib/tools/commands.d.ts +2 -1
  32. package/lib/tools/commands.js +36 -49
  33. package/lib/widgets/ai-settings.d.ts +6 -0
  34. package/lib/widgets/ai-settings.js +72 -71
  35. package/lib/widgets/main-area-chat.d.ts +2 -0
  36. package/lib/widgets/main-area-chat.js +5 -2
  37. package/lib/widgets/provider-config-dialog.d.ts +2 -0
  38. package/lib/widgets/provider-config-dialog.js +34 -34
  39. package/package.json +13 -13
  40. package/schema/settings-model.json +3 -2
  41. package/src/agent.ts +360 -372
  42. package/src/approval-buttons.ts +43 -389
  43. package/src/chat-model-registry.ts +9 -1
  44. package/src/chat-model.ts +399 -370
  45. package/src/completion/completion-provider.ts +2 -3
  46. package/src/components/clear-button.tsx +18 -6
  47. package/src/components/completion-status.tsx +18 -4
  48. package/src/components/model-select.tsx +25 -16
  49. package/src/components/stop-button.tsx +22 -9
  50. package/src/components/token-usage-display.tsx +14 -2
  51. package/src/components/tool-select.tsx +27 -9
  52. package/src/index.ts +78 -134
  53. package/src/models/settings-model.ts +41 -27
  54. package/src/providers/built-in-providers.ts +38 -19
  55. package/src/providers/models.ts +3 -3
  56. package/src/providers/provider-registry.ts +4 -8
  57. package/src/tokens.ts +5 -6
  58. package/src/tools/commands.ts +40 -53
  59. package/src/widgets/ai-settings.tsx +153 -84
  60. package/src/widgets/main-area-chat.ts +8 -2
  61. package/src/widgets/provider-config-dialog.tsx +54 -41
  62. package/style/base.css +24 -73
  63. package/lib/mcp/browser.d.ts +0 -68
  64. package/lib/mcp/browser.js +0 -138
  65. package/lib/tools/file.d.ts +0 -36
  66. package/lib/tools/file.js +0 -351
  67. package/lib/tools/notebook.d.ts +0 -40
  68. package/lib/tools/notebook.js +0 -779
  69. package/src/mcp/browser.ts +0 -220
  70. package/src/tools/file.ts +0 -438
  71. package/src/tools/notebook.ts +0 -986
package/src/index.ts CHANGED
@@ -26,18 +26,20 @@ import { ICompletionProviderManager } from '@jupyterlab/completer';
26
26
 
27
27
  import { IDocumentManager } from '@jupyterlab/docmanager';
28
28
 
29
- import { IEditorTracker } from '@jupyterlab/fileeditor';
30
-
31
29
  import { INotebookTracker } from '@jupyterlab/notebook';
32
30
 
33
31
  import { IRenderMimeRegistry } from '@jupyterlab/rendermime';
34
32
 
35
- import { IKernelSpecManager, KernelSpec } from '@jupyterlab/services';
36
-
37
33
  import { ISettingRegistry } from '@jupyterlab/settingregistry';
38
34
 
39
35
  import { IStatusBar } from '@jupyterlab/statusbar';
40
36
 
37
+ import {
38
+ ITranslator,
39
+ nullTranslator,
40
+ TranslationBundle
41
+ } from '@jupyterlab/translation';
42
+
41
43
  import {
42
44
  settingsIcon,
43
45
  Toolbar,
@@ -94,29 +96,6 @@ import { DiffManager } from './diff-manager';
94
96
 
95
97
  import { ToolRegistry } from './tools/tool-registry';
96
98
 
97
- import {
98
- createAddCellTool,
99
- createDeleteCellTool,
100
- createExecuteActiveCellTool,
101
- createGetCellInfoTool,
102
- createGetNotebookInfoTool,
103
- createNotebookCreationTool,
104
- createRunCellTool,
105
- createSaveNotebookTool,
106
- createSetCellContentTool
107
- } from './tools/notebook';
108
-
109
- import {
110
- createCopyFileTool,
111
- createDeleteFileTool,
112
- createGetFileInfoTool,
113
- createNavigateToDirectoryTool,
114
- createNewFileTool,
115
- createOpenFileTool,
116
- createRenameFileTool,
117
- createSetFileContentTool
118
- } from './tools/file';
119
-
120
99
  import {
121
100
  createDiscoverCommandsTool,
122
101
  createExecuteCommandTool
@@ -212,7 +191,7 @@ const chatModelRegistry: JupyterFrontEndPlugin<IChatModelRegistry> = {
212
191
  description: 'Registry for the current chat model',
213
192
  autoStart: true,
214
193
  requires: [IAISettingsModel, IAgentManagerFactory, IDocumentManager],
215
- optional: [IProviderRegistry, INotebookTracker, IToolRegistry],
194
+ optional: [IProviderRegistry, INotebookTracker, IToolRegistry, ITranslator],
216
195
  provides: IChatModelRegistry,
217
196
  activate: (
218
197
  app: JupyterFrontEnd,
@@ -221,8 +200,11 @@ const chatModelRegistry: JupyterFrontEndPlugin<IChatModelRegistry> = {
221
200
  docManager: IDocumentManager,
222
201
  providerRegistry?: IProviderRegistry,
223
202
  notebookTracker?: INotebookTracker,
224
- toolRegistry?: IToolRegistry
203
+ toolRegistry?: IToolRegistry,
204
+ translator?: ITranslator
225
205
  ): IChatModelRegistry => {
206
+ const trans = (translator ?? nullTranslator).load('jupyterlite_ai');
207
+
226
208
  // Create ActiveCellManager if notebook tracker is available
227
209
  let activeCellManager: ActiveCellManager | undefined;
228
210
  if (notebookTracker) {
@@ -237,7 +219,8 @@ const chatModelRegistry: JupyterFrontEndPlugin<IChatModelRegistry> = {
237
219
  agentManagerFactory,
238
220
  docManager,
239
221
  providerRegistry,
240
- toolRegistry
222
+ toolRegistry,
223
+ trans
241
224
  });
242
225
  }
243
226
  };
@@ -255,7 +238,7 @@ const plugin: JupyterFrontEndPlugin<void> = {
255
238
  IChatModelRegistry,
256
239
  IAISettingsModel
257
240
  ],
258
- optional: [IThemeManager, ILayoutRestorer, ILabShell],
241
+ optional: [IThemeManager, ILayoutRestorer, ILabShell, ITranslator],
259
242
  activate: (
260
243
  app: JupyterFrontEnd,
261
244
  rmRegistry: IRenderMimeRegistry,
@@ -264,8 +247,10 @@ const plugin: JupyterFrontEndPlugin<void> = {
264
247
  settingsModel: AISettingsModel,
265
248
  themeManager?: IThemeManager,
266
249
  restorer?: ILayoutRestorer,
267
- labShell?: ILabShell
250
+ labShell?: ILabShell,
251
+ translator?: ITranslator
268
252
  ): void => {
253
+ const trans = (translator ?? nullTranslator).load('jupyterlite_ai');
269
254
  // Create attachment opener registry to handle file attachments
270
255
  const attachmentOpenerRegistry = new AttachmentOpenerRegistry();
271
256
  attachmentOpenerRegistry.set('file', attachment => {
@@ -304,7 +289,7 @@ const plugin: JupyterFrontEndPlugin<void> = {
304
289
 
305
290
  chatPanel.id = '@jupyterlite/ai:chat-panel';
306
291
  chatPanel.title.icon = chatIcon;
307
- chatPanel.title.caption = 'Chat with AI assistant'; // TODO: i18n/
292
+ chatPanel.title.caption = trans.__('Chat with AI assistant');
308
293
 
309
294
  chatPanel.toolbar.addItem('spacer', Toolbar.createSpacerItem());
310
295
  chatPanel.toolbar.addItem(
@@ -314,7 +299,7 @@ const plugin: JupyterFrontEndPlugin<void> = {
314
299
  onClick: () => {
315
300
  app.commands.execute('@jupyterlite/ai:open-settings');
316
301
  },
317
- tooltip: 'Open AI Settings'
302
+ tooltip: trans.__('Open AI Settings')
318
303
  })
319
304
  );
320
305
 
@@ -335,7 +320,8 @@ const plugin: JupyterFrontEndPlugin<void> = {
335
320
  const tokenUsageWidget = new TokenUsageWidget({
336
321
  tokenUsageChanged: model.tokenUsageChanged,
337
322
  settingsModel,
338
- initialTokenUsage: model.agentManager.tokenUsage
323
+ initialTokenUsage: model.agentManager.tokenUsage,
324
+ translator: trans
339
325
  });
340
326
  section.toolbar.insertBefore('markRead', 'token-usage', tokenUsageWidget);
341
327
  model.writersChanged?.connect((_, writers) => {
@@ -355,7 +341,8 @@ const plugin: JupyterFrontEndPlugin<void> = {
355
341
 
356
342
  // Associate an approval buttons object to the chat.
357
343
  const approvalButton = new ApprovalButtons({
358
- chatPanel: widget
344
+ chatPanel: widget,
345
+ agentManager: model.agentManager
359
346
  });
360
347
 
361
348
  widget.disposed.connect(() => {
@@ -407,6 +394,7 @@ const plugin: JupyterFrontEndPlugin<void> = {
407
394
  settingsModel,
408
395
  tracker,
409
396
  modelRegistry,
397
+ trans,
410
398
  themeManager,
411
399
  labShell
412
400
  );
@@ -422,6 +410,7 @@ function registerCommands(
422
410
  settingsModel: AISettingsModel,
423
411
  tracker: WidgetTracker<MainAreaChat | ChatWidget>,
424
412
  modelRegistry: IChatModelRegistry,
413
+ trans: TranslationBundle,
425
414
  themeManager?: IThemeManager,
426
415
  labShell?: ILabShell
427
416
  ) {
@@ -429,7 +418,7 @@ function registerCommands(
429
418
 
430
419
  if (labShell) {
431
420
  commands.addCommand(CommandIds.reposition, {
432
- label: 'Reposition Widget',
421
+ label: trans.__('Reposition Widget'),
433
422
  execute: (args: any) => {
434
423
  const { widgetId, area, mode } = args;
435
424
  const widget = widgetId
@@ -456,17 +445,22 @@ function registerCommands(
456
445
  properties: {
457
446
  widgetId: {
458
447
  type: 'string',
459
- description:
448
+ description: trans.__(
460
449
  'The widget ID to reposition in the application shell'
450
+ )
461
451
  },
462
452
  area: {
463
453
  type: 'string',
464
- description: 'The name of the area to reposition the widget to'
454
+ description: trans.__(
455
+ 'The name of the area to reposition the widget to'
456
+ )
465
457
  },
466
458
  mode: {
467
459
  type: 'string',
468
460
  enum: ['split-left', 'split-right', 'split-top', 'split-bottom'],
469
- description: 'The mode to use when repositioning the widget'
461
+ description: trans.__(
462
+ 'The mode to use when repositioning the widget'
463
+ )
470
464
  }
471
465
  }
472
466
  }
@@ -481,7 +475,12 @@ function registerCommands(
481
475
  inputToolbarRegistry: inputToolbarFactory.create(),
482
476
  attachmentOpenerRegistry
483
477
  });
484
- const widget = new MainAreaChat({ content, commands, settingsModel });
478
+ const widget = new MainAreaChat({
479
+ content,
480
+ commands,
481
+ settingsModel,
482
+ trans
483
+ });
485
484
  app.shell.add(widget, 'main');
486
485
 
487
486
  // Add the widget to the tracker.
@@ -501,7 +500,7 @@ function registerCommands(
501
500
  };
502
501
 
503
502
  commands.addCommand(CommandIds.openChat, {
504
- label: 'Open a chat',
503
+ label: trans.__('Open a chat'),
505
504
  execute: async (args): Promise<boolean> => {
506
505
  const area = (args.area as string) === 'main' ? 'main' : 'side';
507
506
  const provider = (args.provider as string) ?? undefined;
@@ -532,15 +531,15 @@ function registerCommands(
532
531
  area: {
533
532
  type: 'string',
534
533
  enum: ['main', 'side'],
535
- description: 'The name of the area to open the chat to'
534
+ description: trans.__('The name of the area to open the chat to')
536
535
  },
537
536
  name: {
538
537
  type: 'string',
539
- description: 'The name of the chat'
538
+ description: trans.__('The name of the chat')
540
539
  },
541
540
  provider: {
542
541
  type: 'string',
543
- description: 'The provider/model to use with this chat'
542
+ description: trans.__('The provider/model to use with this chat')
544
543
  }
545
544
  }
546
545
  }
@@ -548,7 +547,7 @@ function registerCommands(
548
547
  });
549
548
 
550
549
  commands.addCommand(CommandIds.moveChat, {
551
- caption: 'Move chat between area',
550
+ caption: trans.__('Move chat between area'),
552
551
  execute: async (args): Promise<boolean> => {
553
552
  const area = args.area as string;
554
553
  if (!['side', 'main'].includes(area)) {
@@ -601,7 +600,7 @@ function registerCommands(
601
600
  trackerUpdated.promise,
602
601
  new Promise<boolean>(r =>
603
602
  setTimeout(() => {
604
- return false;
603
+ r(false);
605
604
  }, 2000)
606
605
  )
607
606
  ]);
@@ -634,11 +633,11 @@ function registerCommands(
634
633
  area: {
635
634
  type: 'string',
636
635
  enum: ['main', 'side'],
637
- description: 'The name of the area to move the chat to'
636
+ description: trans.__('The name of the area to move the chat to')
638
637
  },
639
638
  name: {
640
639
  type: 'string',
641
- description: 'The name of the chat to move'
640
+ description: trans.__('The name of the chat to move')
642
641
  }
643
642
  },
644
643
  requires: ['area', 'name']
@@ -663,7 +662,8 @@ const agentManagerFactory: JupyterFrontEndPlugin<AgentManagerFactory> =
663
662
  ICompletionProviderManager,
664
663
  ILayoutRestorer,
665
664
  ISecretsManager,
666
- IThemeManager
665
+ IThemeManager,
666
+ ITranslator
667
667
  ],
668
668
  activate: (
669
669
  app: JupyterFrontEnd,
@@ -673,8 +673,10 @@ const agentManagerFactory: JupyterFrontEndPlugin<AgentManagerFactory> =
673
673
  completionManager?: ICompletionProviderManager,
674
674
  restorer?: ILayoutRestorer,
675
675
  secretsManager?: ISecretsManager,
676
- themeManager?: IThemeManager
676
+ themeManager?: IThemeManager,
677
+ translator?: ITranslator
677
678
  ): AgentManagerFactory => {
679
+ const trans = (translator ?? nullTranslator).load('jupyterlite_ai');
678
680
  const agentManagerFactory = new AgentManagerFactory({
679
681
  settingsModel,
680
682
  secretsManager,
@@ -688,7 +690,8 @@ const agentManagerFactory: JupyterFrontEndPlugin<AgentManagerFactory> =
688
690
  themeManager,
689
691
  providerRegistry,
690
692
  secretsManager,
691
- token
693
+ token,
694
+ trans
692
695
  });
693
696
  settingsWidget.id = 'jupyterlite-ai-settings';
694
697
  settingsWidget.title.icon = settingsIcon;
@@ -715,8 +718,8 @@ const agentManagerFactory: JupyterFrontEndPlugin<AgentManagerFactory> =
715
718
  }
716
719
 
717
720
  app.commands.addCommand(CommandIds.openSettings, {
718
- label: 'AI Settings',
719
- caption: 'Configure AI providers and behavior',
721
+ label: trans.__('AI Settings'),
722
+ caption: trans.__('Configure AI providers and behavior'),
720
723
  icon: settingsIcon,
721
724
  iconClass: 'jp-ai-settings-icon',
722
725
  execute: () => {
@@ -744,7 +747,7 @@ const agentManagerFactory: JupyterFrontEndPlugin<AgentManagerFactory> =
744
747
  if (palette) {
745
748
  palette.addItem({
746
749
  command: CommandIds.openSettings,
747
- category: 'AI Assistant'
750
+ category: trans.__('AI Assistant')
748
751
  });
749
752
  }
750
753
 
@@ -790,80 +793,11 @@ const toolRegistry: JupyterFrontEndPlugin<IToolRegistry> = {
790
793
  id: '@jupyterlite/ai:tool-registry',
791
794
  description: 'Provide the AI tool registry',
792
795
  autoStart: true,
793
- requires: [IAISettingsModel, IDocumentManager, IKernelSpecManager],
794
- optional: [INotebookTracker, IDiffManager, IEditorTracker],
796
+ requires: [IAISettingsModel],
795
797
  provides: IToolRegistry,
796
- activate: (
797
- app: JupyterFrontEnd,
798
- settingsModel: AISettingsModel,
799
- docManager: IDocumentManager,
800
- kernelSpecManager: KernelSpec.IManager,
801
- notebookTracker?: INotebookTracker,
802
- diffManager?: IDiffManager,
803
- editorTracker?: IEditorTracker
804
- ) => {
798
+ activate: (app: JupyterFrontEnd, settingsModel: AISettingsModel) => {
805
799
  const toolRegistry = new ToolRegistry();
806
800
 
807
- const notebookCreationTool = createNotebookCreationTool(
808
- docManager,
809
- kernelSpecManager
810
- );
811
- toolRegistry.add('create_notebook', notebookCreationTool);
812
-
813
- // Add high-level notebook operation tools
814
- const addCellTool = createAddCellTool(docManager, notebookTracker);
815
- const getNotebookInfoTool = createGetNotebookInfoTool(
816
- docManager,
817
- notebookTracker
818
- );
819
- const getCellInfoTool = createGetCellInfoTool(docManager, notebookTracker);
820
- const setCellContentTool = createSetCellContentTool(
821
- docManager,
822
- notebookTracker,
823
- diffManager
824
- );
825
- const runCellTool = createRunCellTool(docManager, notebookTracker);
826
- const deleteCellTool = createDeleteCellTool(docManager, notebookTracker);
827
- const saveNotebookTool = createSaveNotebookTool(
828
- docManager,
829
- notebookTracker
830
- );
831
- const executeActiveCellTool = createExecuteActiveCellTool(
832
- docManager,
833
- notebookTracker
834
- );
835
-
836
- toolRegistry.add('add_cell', addCellTool);
837
- toolRegistry.add('get_notebook_info', getNotebookInfoTool);
838
- toolRegistry.add('get_cell_info', getCellInfoTool);
839
- toolRegistry.add('set_cell_content', setCellContentTool);
840
- toolRegistry.add('run_cell', runCellTool);
841
- toolRegistry.add('delete_cell', deleteCellTool);
842
- toolRegistry.add('save_notebook', saveNotebookTool);
843
- toolRegistry.add('execute_active_cell', executeActiveCellTool);
844
-
845
- // Add file operation tools
846
- const newFileTool = createNewFileTool(docManager);
847
- const openFileTool = createOpenFileTool(docManager);
848
- const deleteFileTool = createDeleteFileTool(docManager);
849
- const renameFileTool = createRenameFileTool(docManager);
850
- const copyFileTool = createCopyFileTool(docManager);
851
- const navigateToDirectoryTool = createNavigateToDirectoryTool(app.commands);
852
- const getFileInfoTool = createGetFileInfoTool(docManager, editorTracker);
853
- const setFileContentTool = createSetFileContentTool(
854
- docManager,
855
- diffManager
856
- );
857
-
858
- toolRegistry.add('create_file', newFileTool);
859
- toolRegistry.add('open_file', openFileTool);
860
- toolRegistry.add('delete_file', deleteFileTool);
861
- toolRegistry.add('rename_file', renameFileTool);
862
- toolRegistry.add('copy_file', copyFileTool);
863
- toolRegistry.add('navigate_to_directory', navigateToDirectoryTool);
864
- toolRegistry.add('get_file_info', getFileInfoTool);
865
- toolRegistry.add('set_file_content', setFileContentTool);
866
-
867
801
  // Add command operation tools
868
802
  const discoverCommandsTool = createDiscoverCommandsTool(app.commands);
869
803
  const executeCommandTool = createExecuteCommandTool(
@@ -888,18 +822,22 @@ const inputToolbarFactory: JupyterFrontEndPlugin<IInputToolbarRegistryFactory> =
888
822
  autoStart: true,
889
823
  provides: IInputToolbarRegistryFactory,
890
824
  requires: [IAISettingsModel, IToolRegistry],
825
+ optional: [ITranslator],
891
826
  activate: (
892
827
  app: JupyterFrontEnd,
893
828
  settingsModel: AISettingsModel,
894
- toolRegistry: IToolRegistry
829
+ toolRegistry: IToolRegistry,
830
+ translator?: ITranslator
895
831
  ): IInputToolbarRegistryFactory => {
896
- const stopButton = stopItem();
897
- const clearButton = clearItem();
832
+ const trans = (translator ?? nullTranslator).load('jupyterlite_ai');
833
+ const stopButton = stopItem(trans);
834
+ const clearButton = clearItem(trans);
898
835
  const toolSelectButton = createToolSelectItem(
899
836
  toolRegistry,
900
- settingsModel.config.toolsEnabled
837
+ settingsModel.config.toolsEnabled,
838
+ trans
901
839
  );
902
- const modelSelectButton = createModelSelectItem(settingsModel);
840
+ const modelSelectButton = createModelSelectItem(settingsModel, trans);
903
841
 
904
842
  return {
905
843
  create() {
@@ -931,16 +869,21 @@ const completionStatus: JupyterFrontEndPlugin<void> = {
931
869
  description: 'The completion status displayed in the status bar',
932
870
  autoStart: true,
933
871
  requires: [IAISettingsModel],
934
- optional: [IStatusBar],
872
+ optional: [IStatusBar, ITranslator],
935
873
  activate: (
936
874
  app: JupyterFrontEnd,
937
875
  settingsModel: AISettingsModel,
938
- statusBar: IStatusBar | null
876
+ statusBar: IStatusBar | null,
877
+ translator?: ITranslator
939
878
  ) => {
940
879
  if (!statusBar) {
941
880
  return;
942
881
  }
943
- const item = new CompletionStatusWidget({ settingsModel });
882
+ const trans = (translator ?? nullTranslator).load('jupyterlite_ai');
883
+ const item = new CompletionStatusWidget({
884
+ settingsModel,
885
+ translator: trans
886
+ });
944
887
  statusBar?.registerStatusItem('completionState', {
945
888
  item,
946
889
  align: 'right',
@@ -968,3 +911,4 @@ export default [
968
911
 
969
912
  // Export extension points for other extensions to use
970
913
  export * from './tokens';
914
+ export * from './icons';
@@ -5,7 +5,7 @@ const PLUGIN_ID = '@jupyterlite/ai:settings-model';
5
5
 
6
6
  export interface IProviderParameters {
7
7
  temperature?: number;
8
- maxTokens?: number;
8
+ maxOutputTokens?: number;
9
9
  maxTurns?: number;
10
10
  supportsFillInMiddle?: boolean;
11
11
  useFilterText?: boolean;
@@ -91,7 +91,8 @@ export class AISettingsModel extends VDomModel {
91
91
  'fileeditor:run-code',
92
92
  'kernelmenu:run',
93
93
  'kernelmenu:restart-and-run-all',
94
- 'runmenu:run-all'
94
+ 'runmenu:run-all',
95
+ 'jupyterlab-ai-commands:run-cell'
95
96
  ],
96
97
  systemPrompt: `You are Jupyternaut, an AI coding assistant built specifically for the JupyterLab environment.
97
98
 
@@ -100,7 +101,7 @@ You're designed to be a capable partner for data science, research, and developm
100
101
 
101
102
  ## Your Capabilities
102
103
  **📁 File & Project Management:**
103
- - Create, read, edit, and organize Python files and notebooks
104
+ - Create, read, edit, and organize files and notebooks in any language
104
105
  - Manage project structure and navigate file systems
105
106
  - Help with version control and project organization
106
107
 
@@ -110,51 +111,64 @@ You're designed to be a capable partner for data science, research, and developm
110
111
  - Help with notebook structure and organization
111
112
  - Retrieve and analyze cell outputs and execution results
112
113
 
114
+ **⚡ Kernel Management:**
115
+ - Start new kernels with specified language or kernel name
116
+ - Execute code directly in running kernels without creating cells
117
+ - List running kernels and monitor their status
118
+ - Manage kernel lifecycle (start, monitor, shutdown)
119
+
113
120
  **🧠 Coding & Development:**
114
- - Write, debug, and optimize Python code
121
+ - Write, debug, and optimize code in any language supported by Jupyter kernels (Python, R, Julia, JavaScript, C++, and more)
115
122
  - Explain complex algorithms and data structures
116
123
  - Help with data analysis, visualization, and machine learning
117
- - Support for scientific computing libraries (numpy, pandas, matplotlib, etc.)
124
+ - Support for libraries and packages across different languages
118
125
  - Code reviews and best practices recommendations
119
126
 
120
127
  **💡 Adaptive Assistance:**
121
- - Understand context from your current work environment
122
- - Provide suggestions tailored to your specific use case
128
+ - Understand context from the user's current work environment
129
+ - Provide suggestions tailored to the user's specific use case
123
130
  - Help with both quick fixes and long-term project planning
124
131
 
125
- ## How I Work
126
- I can actively interact with your JupyterLab environment using specialized tools. When you ask me to perform actions, I can:
127
- - Execute operations directly in your notebooks
132
+ ## How You Work
133
+ You can actively interact with the user's JupyterLab environment using specialized tools. When asked to perform actions, you can:
134
+ - Execute operations directly in notebooks
128
135
  - Create and modify files as needed
129
136
  - Run code and analyze results
130
137
  - Make systematic changes across multiple files
131
138
 
132
- ## My Approach
133
- - **Context-aware**: I understand you're working in a data science/research environment
134
- - **Practical**: I focus on actionable solutions that work in your current setup
135
- - **Educational**: I explain my reasoning and teach best practices along the way
136
- - **Collaborative**: Think of me as a pair programming partner, not just a code generator
139
+ ## Code Execution Strategy
140
+ When asked to run code or perform computations, choose the most appropriate approach:
141
+ - **For quick computations or one-off code execution**: Use kernel commands to start a kernel and execute code directly, without creating notebook files. This is ideal for calculations, data lookups, or testing code snippets.
142
+ - **For work that should be saved**: Create or use notebooks when the user needs a persistent record of their work, wants to iterate on code, or is building something they'll return to later.
143
+
144
+ This means if the user asks you to "calculate the factorial of 100" or "check what library version is installed", run that directly in a kernel rather than creating a new notebook file.
145
+
146
+ ## Your Approach
147
+ - **Context-aware**: You understand the user is working in a data science/research environment
148
+ - **Practical**: You focus on actionable solutions that work in the user's current setup
149
+ - **Educational**: You explain your reasoning and teach best practices along the way
150
+ - **Collaborative**: You are a pair programming partner, not just a code generator
137
151
 
138
152
  ## Communication Style & Agent Behavior
139
- - **Conversational**: I maintain a friendly, natural conversation flow throughout our interaction
140
- - **Progress Updates**: I write brief progress messages between tool uses that appear directly in our conversation
141
- - **No Filler**: I avoid empty acknowledgments like "Sounds good!" or "Okay, I will..." - I get straight to work
142
- - **Purposeful Communication**: I start with what I'm doing, use tools, then share what I found and what's next
143
- - **Active Narration**: I actively write progress updates like "Looking at the current code structure..." or "Found the issue in the notebook..." between tool calls
144
- - **Checkpoint Updates**: After several operations, I summarize what I've accomplished and what remains
145
- - **Natural Flow**: My explanations and progress reports appear as normal conversation text, not just in tool blocks
153
+ - **Conversational**: You maintain a friendly, natural conversation flow throughout the interaction
154
+ - **Progress Updates**: You write brief progress messages between tool uses that appear directly in the conversation
155
+ - **No Filler**: You avoid empty acknowledgments like "Sounds good!" or "Okay, I will..." - you get straight to work
156
+ - **Purposeful Communication**: You start with what you're doing, use tools, then share what you found and what's next
157
+ - **Active Narration**: You actively write progress updates like "Looking at the current code structure..." or "Found the issue in the notebook..." between tool calls
158
+ - **Checkpoint Updates**: After several operations, you summarize what you've accomplished and what remains
159
+ - **Natural Flow**: Your explanations and progress reports appear as normal conversation text, not just in tool blocks
146
160
 
147
161
  ## IMPORTANT: Always write progress messages between tools that explain what you're doing and what you found. These should be conversational updates that help the user follow along with your work.
148
162
 
149
163
  ## Technical Communication
150
164
  - Code is formatted in proper markdown blocks with syntax highlighting
151
165
  - Mathematical notation uses LaTeX formatting: \\(equations\\) and \\[display math\\]
152
- - I provide context for my actions and explain my reasoning as I work
153
- - When creating or modifying multiple files, I give brief summaries of changes
154
- - I keep users informed of progress while staying focused on the task
166
+ - You provide context for your actions and explain your reasoning as you work
167
+ - When creating or modifying multiple files, you give brief summaries of changes
168
+ - You keep users informed of progress while staying focused on the task
155
169
 
156
170
  ## Multi-Step Task Handling
157
- When users request complex tasks that require multiple steps (like "create a notebook with example cells"), I use tools in sequence to accomplish the complete task. For example:
171
+ When users request complex tasks that require multiple steps (like "create a notebook with example cells"), you use tools in sequence to accomplish the complete task. For example:
158
172
  - First use create_notebook to create the notebook
159
173
  - Then use add_code_cell or add_markdown_cell to add cells
160
174
  - Use set_cell_content to add content to cells as needed
@@ -162,7 +176,7 @@ When users request complex tasks that require multiple steps (like "create a not
162
176
 
163
177
  Always think through multi-step tasks and use tools to fully complete the user's request rather than stopping after just one action.
164
178
 
165
- Ready to help you build something great! What are you working on?`,
179
+ You are ready to help users build something great!`,
166
180
  // Completion system prompt - also defined in schema/settings-model.json
167
181
  // This serves as a fallback if settings fail to load or are not available
168
182
  completionSystemPrompt: `You are an AI code completion assistant. Complete the given code fragment with appropriate code.