@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/lib/index.js CHANGED
@@ -3,12 +3,11 @@ import { ActiveCellManager, AttachmentOpenerRegistry, chatIcon, ChatWidget, IInp
3
3
  import { ICommandPalette, IThemeManager, WidgetTracker } from '@jupyterlab/apputils';
4
4
  import { ICompletionProviderManager } from '@jupyterlab/completer';
5
5
  import { IDocumentManager } from '@jupyterlab/docmanager';
6
- import { IEditorTracker } from '@jupyterlab/fileeditor';
7
6
  import { INotebookTracker } from '@jupyterlab/notebook';
8
7
  import { IRenderMimeRegistry } from '@jupyterlab/rendermime';
9
- import { IKernelSpecManager } from '@jupyterlab/services';
10
8
  import { ISettingRegistry } from '@jupyterlab/settingregistry';
11
9
  import { IStatusBar } from '@jupyterlab/statusbar';
10
+ import { ITranslator, nullTranslator } from '@jupyterlab/translation';
12
11
  import { settingsIcon, Toolbar, ToolbarButton } from '@jupyterlab/ui-components';
13
12
  import { ISecretsManager, SecretsManager } from 'jupyter-secrets-manager';
14
13
  import { PromiseDelegate, UUID } from '@lumino/coreutils';
@@ -23,8 +22,6 @@ import { clearItem, createModelSelectItem, createToolSelectItem, stopItem, Compl
23
22
  import { AISettingsModel } from './models/settings-model';
24
23
  import { DiffManager } from './diff-manager';
25
24
  import { ToolRegistry } from './tools/tool-registry';
26
- import { createAddCellTool, createDeleteCellTool, createExecuteActiveCellTool, createGetCellInfoTool, createGetNotebookInfoTool, createNotebookCreationTool, createRunCellTool, createSaveNotebookTool, createSetCellContentTool } from './tools/notebook';
27
- import { createCopyFileTool, createDeleteFileTool, createGetFileInfoTool, createNavigateToDirectoryTool, createNewFileTool, createOpenFileTool, createRenameFileTool, createSetFileContentTool } from './tools/file';
28
25
  import { createDiscoverCommandsTool, createExecuteCommandTool } from './tools/commands';
29
26
  import { AISettingsWidget } from './widgets/ai-settings';
30
27
  import { MainAreaChat } from './widgets/main-area-chat';
@@ -108,9 +105,10 @@ const chatModelRegistry = {
108
105
  description: 'Registry for the current chat model',
109
106
  autoStart: true,
110
107
  requires: [IAISettingsModel, IAgentManagerFactory, IDocumentManager],
111
- optional: [IProviderRegistry, INotebookTracker, IToolRegistry],
108
+ optional: [IProviderRegistry, INotebookTracker, IToolRegistry, ITranslator],
112
109
  provides: IChatModelRegistry,
113
- activate: (app, settingsModel, agentManagerFactory, docManager, providerRegistry, notebookTracker, toolRegistry) => {
110
+ activate: (app, settingsModel, agentManagerFactory, docManager, providerRegistry, notebookTracker, toolRegistry, translator) => {
111
+ const trans = (translator ?? nullTranslator).load('jupyterlite_ai');
114
112
  // Create ActiveCellManager if notebook tracker is available
115
113
  let activeCellManager;
116
114
  if (notebookTracker) {
@@ -125,7 +123,8 @@ const chatModelRegistry = {
125
123
  agentManagerFactory,
126
124
  docManager,
127
125
  providerRegistry,
128
- toolRegistry
126
+ toolRegistry,
127
+ trans
129
128
  });
130
129
  }
131
130
  };
@@ -142,8 +141,9 @@ const plugin = {
142
141
  IChatModelRegistry,
143
142
  IAISettingsModel
144
143
  ],
145
- optional: [IThemeManager, ILayoutRestorer, ILabShell],
146
- activate: (app, rmRegistry, inputToolbarFactory, modelRegistry, settingsModel, themeManager, restorer, labShell) => {
144
+ optional: [IThemeManager, ILayoutRestorer, ILabShell, ITranslator],
145
+ activate: (app, rmRegistry, inputToolbarFactory, modelRegistry, settingsModel, themeManager, restorer, labShell, translator) => {
146
+ const trans = (translator ?? nullTranslator).load('jupyterlite_ai');
147
147
  // Create attachment opener registry to handle file attachments
148
148
  const attachmentOpenerRegistry = new AttachmentOpenerRegistry();
149
149
  attachmentOpenerRegistry.set('file', attachment => {
@@ -178,14 +178,14 @@ const plugin = {
178
178
  });
179
179
  chatPanel.id = '@jupyterlite/ai:chat-panel';
180
180
  chatPanel.title.icon = chatIcon;
181
- chatPanel.title.caption = 'Chat with AI assistant'; // TODO: i18n/
181
+ chatPanel.title.caption = trans.__('Chat with AI assistant');
182
182
  chatPanel.toolbar.addItem('spacer', Toolbar.createSpacerItem());
183
183
  chatPanel.toolbar.addItem('settings', new ToolbarButton({
184
184
  icon: settingsIcon,
185
185
  onClick: () => {
186
186
  app.commands.execute('@jupyterlite/ai:open-settings');
187
187
  },
188
- tooltip: 'Open AI Settings'
188
+ tooltip: trans.__('Open AI Settings')
189
189
  }));
190
190
  chatPanel.sectionAdded.connect((_, section) => {
191
191
  const { widget } = section;
@@ -199,7 +199,8 @@ const plugin = {
199
199
  const tokenUsageWidget = new TokenUsageWidget({
200
200
  tokenUsageChanged: model.tokenUsageChanged,
201
201
  settingsModel,
202
- initialTokenUsage: model.agentManager.tokenUsage
202
+ initialTokenUsage: model.agentManager.tokenUsage,
203
+ translator: trans
203
204
  });
204
205
  section.toolbar.insertBefore('markRead', 'token-usage', tokenUsageWidget);
205
206
  model.writersChanged?.connect((_, writers) => {
@@ -216,7 +217,8 @@ const plugin = {
216
217
  });
217
218
  // Associate an approval buttons object to the chat.
218
219
  const approvalButton = new ApprovalButtons({
219
- chatPanel: widget
220
+ chatPanel: widget,
221
+ agentManager: model.agentManager
220
222
  });
221
223
  widget.disposed.connect(() => {
222
224
  // Dispose of the approval buttons widget when the chat is disposed.
@@ -251,14 +253,14 @@ const plugin = {
251
253
  app.commands.execute(CommandIds.openChat);
252
254
  }
253
255
  });
254
- registerCommands(app, rmRegistry, chatPanel, attachmentOpenerRegistry, inputToolbarFactory, settingsModel, tracker, modelRegistry, themeManager, labShell);
256
+ registerCommands(app, rmRegistry, chatPanel, attachmentOpenerRegistry, inputToolbarFactory, settingsModel, tracker, modelRegistry, trans, themeManager, labShell);
255
257
  }
256
258
  };
257
- function registerCommands(app, rmRegistry, chatPanel, attachmentOpenerRegistry, inputToolbarFactory, settingsModel, tracker, modelRegistry, themeManager, labShell) {
259
+ function registerCommands(app, rmRegistry, chatPanel, attachmentOpenerRegistry, inputToolbarFactory, settingsModel, tracker, modelRegistry, trans, themeManager, labShell) {
258
260
  const { commands } = app;
259
261
  if (labShell) {
260
262
  commands.addCommand(CommandIds.reposition, {
261
- label: 'Reposition Widget',
263
+ label: trans.__('Reposition Widget'),
262
264
  execute: (args) => {
263
265
  const { widgetId, area, mode } = args;
264
266
  const widget = widgetId
@@ -284,16 +286,16 @@ function registerCommands(app, rmRegistry, chatPanel, attachmentOpenerRegistry,
284
286
  properties: {
285
287
  widgetId: {
286
288
  type: 'string',
287
- description: 'The widget ID to reposition in the application shell'
289
+ description: trans.__('The widget ID to reposition in the application shell')
288
290
  },
289
291
  area: {
290
292
  type: 'string',
291
- description: 'The name of the area to reposition the widget to'
293
+ description: trans.__('The name of the area to reposition the widget to')
292
294
  },
293
295
  mode: {
294
296
  type: 'string',
295
297
  enum: ['split-left', 'split-right', 'split-top', 'split-bottom'],
296
- description: 'The mode to use when repositioning the widget'
298
+ description: trans.__('The mode to use when repositioning the widget')
297
299
  }
298
300
  }
299
301
  }
@@ -307,7 +309,12 @@ function registerCommands(app, rmRegistry, chatPanel, attachmentOpenerRegistry,
307
309
  inputToolbarRegistry: inputToolbarFactory.create(),
308
310
  attachmentOpenerRegistry
309
311
  });
310
- const widget = new MainAreaChat({ content, commands, settingsModel });
312
+ const widget = new MainAreaChat({
313
+ content,
314
+ commands,
315
+ settingsModel,
316
+ trans
317
+ });
311
318
  app.shell.add(widget, 'main');
312
319
  // Add the widget to the tracker.
313
320
  tracker.add(widget);
@@ -321,7 +328,7 @@ function registerCommands(app, rmRegistry, chatPanel, attachmentOpenerRegistry,
321
328
  });
322
329
  };
323
330
  commands.addCommand(CommandIds.openChat, {
324
- label: 'Open a chat',
331
+ label: trans.__('Open a chat'),
325
332
  execute: async (args) => {
326
333
  const area = args.area === 'main' ? 'main' : 'side';
327
334
  const provider = args.provider ?? undefined;
@@ -348,22 +355,22 @@ function registerCommands(app, rmRegistry, chatPanel, attachmentOpenerRegistry,
348
355
  area: {
349
356
  type: 'string',
350
357
  enum: ['main', 'side'],
351
- description: 'The name of the area to open the chat to'
358
+ description: trans.__('The name of the area to open the chat to')
352
359
  },
353
360
  name: {
354
361
  type: 'string',
355
- description: 'The name of the chat'
362
+ description: trans.__('The name of the chat')
356
363
  },
357
364
  provider: {
358
365
  type: 'string',
359
- description: 'The provider/model to use with this chat'
366
+ description: trans.__('The provider/model to use with this chat')
360
367
  }
361
368
  }
362
369
  }
363
370
  }
364
371
  });
365
372
  commands.addCommand(CommandIds.moveChat, {
366
- caption: 'Move chat between area',
373
+ caption: trans.__('Move chat between area'),
367
374
  execute: async (args) => {
368
375
  const area = args.area;
369
376
  if (!['side', 'main'].includes(area)) {
@@ -399,7 +406,7 @@ function registerCommands(app, rmRegistry, chatPanel, attachmentOpenerRegistry,
399
406
  const status = await Promise.any([
400
407
  trackerUpdated.promise,
401
408
  new Promise(r => setTimeout(() => {
402
- return false;
409
+ r(false);
403
410
  }, 2000))
404
411
  ]);
405
412
  tracker.widgetUpdated.disconnect(widgetUpdated);
@@ -427,11 +434,11 @@ function registerCommands(app, rmRegistry, chatPanel, attachmentOpenerRegistry,
427
434
  area: {
428
435
  type: 'string',
429
436
  enum: ['main', 'side'],
430
- description: 'The name of the area to move the chat to'
437
+ description: trans.__('The name of the area to move the chat to')
431
438
  },
432
439
  name: {
433
440
  type: 'string',
434
- description: 'The name of the chat to move'
441
+ description: trans.__('The name of the chat to move')
435
442
  }
436
443
  },
437
444
  requires: ['area', 'name']
@@ -454,9 +461,11 @@ const agentManagerFactory = SecretsManager.sign(SECRETS_NAMESPACE, token => ({
454
461
  ICompletionProviderManager,
455
462
  ILayoutRestorer,
456
463
  ISecretsManager,
457
- IThemeManager
464
+ IThemeManager,
465
+ ITranslator
458
466
  ],
459
- activate: (app, settingsModel, providerRegistry, palette, completionManager, restorer, secretsManager, themeManager) => {
467
+ activate: (app, settingsModel, providerRegistry, palette, completionManager, restorer, secretsManager, themeManager, translator) => {
468
+ const trans = (translator ?? nullTranslator).load('jupyterlite_ai');
460
469
  const agentManagerFactory = new AgentManagerFactory({
461
470
  settingsModel,
462
471
  secretsManager,
@@ -469,7 +478,8 @@ const agentManagerFactory = SecretsManager.sign(SECRETS_NAMESPACE, token => ({
469
478
  themeManager,
470
479
  providerRegistry,
471
480
  secretsManager,
472
- token
481
+ token,
482
+ trans
473
483
  });
474
484
  settingsWidget.id = 'jupyterlite-ai-settings';
475
485
  settingsWidget.title.icon = settingsIcon;
@@ -491,8 +501,8 @@ const agentManagerFactory = SecretsManager.sign(SECRETS_NAMESPACE, token => ({
491
501
  restorer.add(settingsWidget, settingsWidget.id);
492
502
  }
493
503
  app.commands.addCommand(CommandIds.openSettings, {
494
- label: 'AI Settings',
495
- caption: 'Configure AI providers and behavior',
504
+ label: trans.__('AI Settings'),
505
+ caption: trans.__('Configure AI providers and behavior'),
496
506
  icon: settingsIcon,
497
507
  iconClass: 'jp-ai-settings-icon',
498
508
  execute: () => {
@@ -515,7 +525,7 @@ const agentManagerFactory = SecretsManager.sign(SECRETS_NAMESPACE, token => ({
515
525
  if (palette) {
516
526
  palette.addItem({
517
527
  command: CommandIds.openSettings,
518
- category: 'AI Assistant'
528
+ category: trans.__('AI Assistant')
519
529
  });
520
530
  }
521
531
  return agentManagerFactory;
@@ -554,47 +564,10 @@ const toolRegistry = {
554
564
  id: '@jupyterlite/ai:tool-registry',
555
565
  description: 'Provide the AI tool registry',
556
566
  autoStart: true,
557
- requires: [IAISettingsModel, IDocumentManager, IKernelSpecManager],
558
- optional: [INotebookTracker, IDiffManager, IEditorTracker],
567
+ requires: [IAISettingsModel],
559
568
  provides: IToolRegistry,
560
- activate: (app, settingsModel, docManager, kernelSpecManager, notebookTracker, diffManager, editorTracker) => {
569
+ activate: (app, settingsModel) => {
561
570
  const toolRegistry = new ToolRegistry();
562
- const notebookCreationTool = createNotebookCreationTool(docManager, kernelSpecManager);
563
- toolRegistry.add('create_notebook', notebookCreationTool);
564
- // Add high-level notebook operation tools
565
- const addCellTool = createAddCellTool(docManager, notebookTracker);
566
- const getNotebookInfoTool = createGetNotebookInfoTool(docManager, notebookTracker);
567
- const getCellInfoTool = createGetCellInfoTool(docManager, notebookTracker);
568
- const setCellContentTool = createSetCellContentTool(docManager, notebookTracker, diffManager);
569
- const runCellTool = createRunCellTool(docManager, notebookTracker);
570
- const deleteCellTool = createDeleteCellTool(docManager, notebookTracker);
571
- const saveNotebookTool = createSaveNotebookTool(docManager, notebookTracker);
572
- const executeActiveCellTool = createExecuteActiveCellTool(docManager, notebookTracker);
573
- toolRegistry.add('add_cell', addCellTool);
574
- toolRegistry.add('get_notebook_info', getNotebookInfoTool);
575
- toolRegistry.add('get_cell_info', getCellInfoTool);
576
- toolRegistry.add('set_cell_content', setCellContentTool);
577
- toolRegistry.add('run_cell', runCellTool);
578
- toolRegistry.add('delete_cell', deleteCellTool);
579
- toolRegistry.add('save_notebook', saveNotebookTool);
580
- toolRegistry.add('execute_active_cell', executeActiveCellTool);
581
- // Add file operation tools
582
- const newFileTool = createNewFileTool(docManager);
583
- const openFileTool = createOpenFileTool(docManager);
584
- const deleteFileTool = createDeleteFileTool(docManager);
585
- const renameFileTool = createRenameFileTool(docManager);
586
- const copyFileTool = createCopyFileTool(docManager);
587
- const navigateToDirectoryTool = createNavigateToDirectoryTool(app.commands);
588
- const getFileInfoTool = createGetFileInfoTool(docManager, editorTracker);
589
- const setFileContentTool = createSetFileContentTool(docManager, diffManager);
590
- toolRegistry.add('create_file', newFileTool);
591
- toolRegistry.add('open_file', openFileTool);
592
- toolRegistry.add('delete_file', deleteFileTool);
593
- toolRegistry.add('rename_file', renameFileTool);
594
- toolRegistry.add('copy_file', copyFileTool);
595
- toolRegistry.add('navigate_to_directory', navigateToDirectoryTool);
596
- toolRegistry.add('get_file_info', getFileInfoTool);
597
- toolRegistry.add('set_file_content', setFileContentTool);
598
571
  // Add command operation tools
599
572
  const discoverCommandsTool = createDiscoverCommandsTool(app.commands);
600
573
  const executeCommandTool = createExecuteCommandTool(app.commands, settingsModel);
@@ -612,11 +585,13 @@ const inputToolbarFactory = {
612
585
  autoStart: true,
613
586
  provides: IInputToolbarRegistryFactory,
614
587
  requires: [IAISettingsModel, IToolRegistry],
615
- activate: (app, settingsModel, toolRegistry) => {
616
- const stopButton = stopItem();
617
- const clearButton = clearItem();
618
- const toolSelectButton = createToolSelectItem(toolRegistry, settingsModel.config.toolsEnabled);
619
- const modelSelectButton = createModelSelectItem(settingsModel);
588
+ optional: [ITranslator],
589
+ activate: (app, settingsModel, toolRegistry, translator) => {
590
+ const trans = (translator ?? nullTranslator).load('jupyterlite_ai');
591
+ const stopButton = stopItem(trans);
592
+ const clearButton = clearItem(trans);
593
+ const toolSelectButton = createToolSelectItem(toolRegistry, settingsModel.config.toolsEnabled, trans);
594
+ const modelSelectButton = createModelSelectItem(settingsModel, trans);
620
595
  return {
621
596
  create() {
622
597
  const inputToolbarRegistry = InputToolbarRegistry.defaultToolbarRegistry();
@@ -644,12 +619,16 @@ const completionStatus = {
644
619
  description: 'The completion status displayed in the status bar',
645
620
  autoStart: true,
646
621
  requires: [IAISettingsModel],
647
- optional: [IStatusBar],
648
- activate: (app, settingsModel, statusBar) => {
622
+ optional: [IStatusBar, ITranslator],
623
+ activate: (app, settingsModel, statusBar, translator) => {
649
624
  if (!statusBar) {
650
625
  return;
651
626
  }
652
- const item = new CompletionStatusWidget({ settingsModel });
627
+ const trans = (translator ?? nullTranslator).load('jupyterlite_ai');
628
+ const item = new CompletionStatusWidget({
629
+ settingsModel,
630
+ translator: trans
631
+ });
653
632
  statusBar?.registerStatusItem('completionState', {
654
633
  item,
655
634
  align: 'right',
@@ -675,3 +654,4 @@ export default [
675
654
  ];
676
655
  // Export extension points for other extensions to use
677
656
  export * from './tokens';
657
+ export * from './icons';
@@ -2,7 +2,7 @@ import { VDomModel } from '@jupyterlab/ui-components';
2
2
  import { ISettingRegistry } from '@jupyterlab/settingregistry';
3
3
  export interface IProviderParameters {
4
4
  temperature?: number;
5
- maxTokens?: number;
5
+ maxOutputTokens?: number;
6
6
  maxTurns?: number;
7
7
  supportsFillInMiddle?: boolean;
8
8
  useFilterText?: boolean;
@@ -29,7 +29,8 @@ export class AISettingsModel extends VDomModel {
29
29
  'fileeditor:run-code',
30
30
  'kernelmenu:run',
31
31
  'kernelmenu:restart-and-run-all',
32
- 'runmenu:run-all'
32
+ 'runmenu:run-all',
33
+ 'jupyterlab-ai-commands:run-cell'
33
34
  ],
34
35
  systemPrompt: `You are Jupyternaut, an AI coding assistant built specifically for the JupyterLab environment.
35
36
 
@@ -38,7 +39,7 @@ You're designed to be a capable partner for data science, research, and developm
38
39
 
39
40
  ## Your Capabilities
40
41
  **📁 File & Project Management:**
41
- - Create, read, edit, and organize Python files and notebooks
42
+ - Create, read, edit, and organize files and notebooks in any language
42
43
  - Manage project structure and navigate file systems
43
44
  - Help with version control and project organization
44
45
 
@@ -48,51 +49,64 @@ You're designed to be a capable partner for data science, research, and developm
48
49
  - Help with notebook structure and organization
49
50
  - Retrieve and analyze cell outputs and execution results
50
51
 
52
+ **⚡ Kernel Management:**
53
+ - Start new kernels with specified language or kernel name
54
+ - Execute code directly in running kernels without creating cells
55
+ - List running kernels and monitor their status
56
+ - Manage kernel lifecycle (start, monitor, shutdown)
57
+
51
58
  **🧠 Coding & Development:**
52
- - Write, debug, and optimize Python code
59
+ - Write, debug, and optimize code in any language supported by Jupyter kernels (Python, R, Julia, JavaScript, C++, and more)
53
60
  - Explain complex algorithms and data structures
54
61
  - Help with data analysis, visualization, and machine learning
55
- - Support for scientific computing libraries (numpy, pandas, matplotlib, etc.)
62
+ - Support for libraries and packages across different languages
56
63
  - Code reviews and best practices recommendations
57
64
 
58
65
  **💡 Adaptive Assistance:**
59
- - Understand context from your current work environment
60
- - Provide suggestions tailored to your specific use case
66
+ - Understand context from the user's current work environment
67
+ - Provide suggestions tailored to the user's specific use case
61
68
  - Help with both quick fixes and long-term project planning
62
69
 
63
- ## How I Work
64
- I can actively interact with your JupyterLab environment using specialized tools. When you ask me to perform actions, I can:
65
- - Execute operations directly in your notebooks
70
+ ## How You Work
71
+ You can actively interact with the user's JupyterLab environment using specialized tools. When asked to perform actions, you can:
72
+ - Execute operations directly in notebooks
66
73
  - Create and modify files as needed
67
74
  - Run code and analyze results
68
75
  - Make systematic changes across multiple files
69
76
 
70
- ## My Approach
71
- - **Context-aware**: I understand you're working in a data science/research environment
72
- - **Practical**: I focus on actionable solutions that work in your current setup
73
- - **Educational**: I explain my reasoning and teach best practices along the way
74
- - **Collaborative**: Think of me as a pair programming partner, not just a code generator
77
+ ## Code Execution Strategy
78
+ When asked to run code or perform computations, choose the most appropriate approach:
79
+ - **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.
80
+ - **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.
81
+
82
+ 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.
83
+
84
+ ## Your Approach
85
+ - **Context-aware**: You understand the user is working in a data science/research environment
86
+ - **Practical**: You focus on actionable solutions that work in the user's current setup
87
+ - **Educational**: You explain your reasoning and teach best practices along the way
88
+ - **Collaborative**: You are a pair programming partner, not just a code generator
75
89
 
76
90
  ## Communication Style & Agent Behavior
77
- - **Conversational**: I maintain a friendly, natural conversation flow throughout our interaction
78
- - **Progress Updates**: I write brief progress messages between tool uses that appear directly in our conversation
79
- - **No Filler**: I avoid empty acknowledgments like "Sounds good!" or "Okay, I will..." - I get straight to work
80
- - **Purposeful Communication**: I start with what I'm doing, use tools, then share what I found and what's next
81
- - **Active Narration**: I actively write progress updates like "Looking at the current code structure..." or "Found the issue in the notebook..." between tool calls
82
- - **Checkpoint Updates**: After several operations, I summarize what I've accomplished and what remains
83
- - **Natural Flow**: My explanations and progress reports appear as normal conversation text, not just in tool blocks
91
+ - **Conversational**: You maintain a friendly, natural conversation flow throughout the interaction
92
+ - **Progress Updates**: You write brief progress messages between tool uses that appear directly in the conversation
93
+ - **No Filler**: You avoid empty acknowledgments like "Sounds good!" or "Okay, I will..." - you get straight to work
94
+ - **Purposeful Communication**: You start with what you're doing, use tools, then share what you found and what's next
95
+ - **Active Narration**: You actively write progress updates like "Looking at the current code structure..." or "Found the issue in the notebook..." between tool calls
96
+ - **Checkpoint Updates**: After several operations, you summarize what you've accomplished and what remains
97
+ - **Natural Flow**: Your explanations and progress reports appear as normal conversation text, not just in tool blocks
84
98
 
85
99
  ## 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.
86
100
 
87
101
  ## Technical Communication
88
102
  - Code is formatted in proper markdown blocks with syntax highlighting
89
103
  - Mathematical notation uses LaTeX formatting: \\(equations\\) and \\[display math\\]
90
- - I provide context for my actions and explain my reasoning as I work
91
- - When creating or modifying multiple files, I give brief summaries of changes
92
- - I keep users informed of progress while staying focused on the task
104
+ - You provide context for your actions and explain your reasoning as you work
105
+ - When creating or modifying multiple files, you give brief summaries of changes
106
+ - You keep users informed of progress while staying focused on the task
93
107
 
94
108
  ## Multi-Step Task Handling
95
- 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:
109
+ 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:
96
110
  - First use create_notebook to create the notebook
97
111
  - Then use add_code_cell or add_markdown_cell to add cells
98
112
  - Use set_cell_content to add content to cells as needed
@@ -100,7 +114,7 @@ When users request complex tasks that require multiple steps (like "create a not
100
114
 
101
115
  Always think through multi-step tasks and use tools to fully complete the user's request rather than stopping after just one action.
102
116
 
103
- Ready to help you build something great! What are you working on?`,
117
+ You are ready to help users build something great!`,
104
118
  // Completion system prompt - also defined in schema/settings-model.json
105
119
  // This serves as a fallback if settings fail to load or are not available
106
120
  completionSystemPrompt: `You are an AI code completion assistant. Complete the given code fragment with appropriate code.
@@ -11,15 +11,17 @@ export const anthropicProvider = {
11
11
  name: 'Anthropic Claude',
12
12
  apiKeyRequirement: 'required',
13
13
  defaultModels: [
14
+ 'claude-opus-4-5',
15
+ 'claude-opus-4-5-20251101',
14
16
  'claude-sonnet-4-5',
15
17
  'claude-sonnet-4-5-20250929',
16
18
  'claude-haiku-4-5',
17
19
  'claude-haiku-4-5-20251001',
18
20
  'claude-opus-4-1',
19
- 'claude-opus-4-0',
20
- 'claude-sonnet-4-0',
21
21
  'claude-opus-4-1-20250805',
22
+ 'claude-opus-4-0',
22
23
  'claude-opus-4-20250514',
24
+ 'claude-sonnet-4-0',
23
25
  'claude-sonnet-4-20250514',
24
26
  'claude-3-7-sonnet-latest',
25
27
  'claude-3-7-sonnet-20250219',
@@ -53,8 +55,11 @@ export const googleProvider = {
53
55
  name: 'Google Generative AI',
54
56
  apiKeyRequirement: 'required',
55
57
  defaultModels: [
56
- 'gemini-2.5-flash',
58
+ 'gemini-3-pro-preview',
59
+ 'gemini-3-pro-image-preview',
60
+ 'gemini-3-flash-preview',
57
61
  'gemini-2.5-pro',
62
+ 'gemini-2.5-flash',
58
63
  'gemini-2.5-flash-image-preview',
59
64
  'gemini-2.5-flash-lite',
60
65
  'gemini-2.5-flash-lite-preview-09-2025',
@@ -79,6 +84,9 @@ export const googleProvider = {
79
84
  'gemini-1.5-pro-latest',
80
85
  'gemini-1.5-pro-001',
81
86
  'gemini-1.5-pro-002',
87
+ 'gemini-pro-latest',
88
+ 'gemini-flash-latest',
89
+ 'gemini-flash-lite-latest',
82
90
  'gemini-exp-1206',
83
91
  'gemma-3-12b-it',
84
92
  'gemma-3-27b-it'
@@ -143,12 +151,32 @@ export const openaiProvider = {
143
151
  name: 'OpenAI',
144
152
  apiKeyRequirement: 'required',
145
153
  defaultModels: [
146
- 'o1',
147
- 'o1-2024-12-17',
148
- 'o3-mini',
149
- 'o3-mini-2025-01-31',
154
+ 'gpt-5.2',
155
+ 'gpt-5.2-chat-latest',
156
+ 'gpt-5.2-pro',
157
+ 'gpt-5.1',
158
+ 'gpt-5.1-chat-latest',
159
+ 'gpt-5.1-codex',
160
+ 'gpt-5.1-codex-mini',
161
+ 'gpt-5.1-codex-max',
162
+ 'gpt-5',
163
+ 'gpt-5-2025-08-07',
164
+ 'gpt-5-chat-latest',
165
+ 'gpt-5-codex',
166
+ 'gpt-5-pro',
167
+ 'gpt-5-pro-2025-10-06',
168
+ 'gpt-5-mini',
169
+ 'gpt-5-mini-2025-08-07',
170
+ 'gpt-5-nano',
171
+ 'gpt-5-nano-2025-08-07',
150
172
  'o3',
151
173
  'o3-2025-04-16',
174
+ 'o3-mini',
175
+ 'o3-mini-2025-01-31',
176
+ 'o1',
177
+ 'o1-2024-12-17',
178
+ 'gpt-4.5-preview',
179
+ 'gpt-4.5-preview-2025-02-27',
152
180
  'gpt-4.1',
153
181
  'gpt-4.1-2025-04-14',
154
182
  'gpt-4.1-mini',
@@ -161,23 +189,14 @@ export const openaiProvider = {
161
189
  'gpt-4o-2024-11-20',
162
190
  'gpt-4o-mini',
163
191
  'gpt-4o-mini-2024-07-18',
192
+ 'chatgpt-4o-latest',
164
193
  'gpt-4-turbo',
165
194
  'gpt-4-turbo-2024-04-09',
166
195
  'gpt-4',
167
196
  'gpt-4-0613',
168
- 'gpt-4.5-preview',
169
- 'gpt-4.5-preview-2025-02-27',
170
- 'gpt-3.5-turbo-0125',
171
197
  'gpt-3.5-turbo',
172
- 'gpt-3.5-turbo-1106',
173
- 'chatgpt-4o-latest',
174
- 'gpt-5',
175
- 'gpt-5-2025-08-07',
176
- 'gpt-5-mini',
177
- 'gpt-5-mini-2025-08-07',
178
- 'gpt-5-nano',
179
- 'gpt-5-nano-2025-08-07',
180
- 'gpt-5-chat-latest'
198
+ 'gpt-3.5-turbo-0125',
199
+ 'gpt-3.5-turbo-1106'
181
200
  ],
182
201
  supportsBaseURL: true,
183
202
  supportsHeaders: true,
@@ -1,4 +1,4 @@
1
- import type { LanguageModelV2 } from '@ai-sdk/provider';
1
+ import type { LanguageModel } from 'ai';
2
2
  import type { IProviderRegistry } from '../tokens';
3
3
  /**
4
4
  * Configuration options for creating language models.
@@ -29,9 +29,9 @@ export interface IModelOptions {
29
29
  * Create a completion model using the provider registry.
30
30
  * Built-in providers are automatically registered during extension initialization.
31
31
  */
32
- export declare function createCompletionModel(options: IModelOptions, registry?: IProviderRegistry): LanguageModelV2;
32
+ export declare function createCompletionModel(options: IModelOptions, registry?: IProviderRegistry): LanguageModel;
33
33
  /**
34
34
  * Create a chat model using the provider registry.
35
35
  * Built-in providers are automatically registered during extension initialization.
36
36
  */
37
- export declare function createModel(options: IModelOptions, registry?: IProviderRegistry): import("@openai/agents-core").Model;
37
+ export declare function createModel(options: IModelOptions, registry?: IProviderRegistry): LanguageModel;
@@ -1,6 +1,5 @@
1
1
  import { ISignal } from '@lumino/signaling';
2
- import type { LanguageModelV2 } from '@ai-sdk/provider';
3
- import type { Model } from '@openai/agents';
2
+ import type { LanguageModel } from 'ai';
4
3
  import type { IModelOptions } from './models';
5
4
  import { IProviderInfo, IProviderRegistry } from '../tokens';
6
5
  /**
@@ -32,14 +31,14 @@ export declare class ProviderRegistry implements IProviderRegistry {
32
31
  * @param options Model configuration options
33
32
  * @returns Chat model instance or null if creation fails
34
33
  */
35
- createChatModel(id: string, options: IModelOptions): Model | null;
34
+ createChatModel(id: string, options: IModelOptions): LanguageModel | null;
36
35
  /**
37
36
  * Create a completion model instance using the specified provider
38
37
  * @param id Provider ID
39
38
  * @param options Model configuration options
40
39
  * @returns Language model instance or null if creation fails
41
40
  */
42
- createCompletionModel(id: string, options: IModelOptions): LanguageModelV2 | null;
41
+ createCompletionModel(id: string, options: IModelOptions): LanguageModel | null;
43
42
  /**
44
43
  * Get list of all available provider IDs
45
44
  * @returns Array of provider IDs
@@ -1,5 +1,4 @@
1
1
  import { Signal } from '@lumino/signaling';
2
- import { aisdk } from '@openai/agents-extensions';
3
2
  /**
4
3
  * Implementation of the provider registry
5
4
  */
@@ -46,9 +45,7 @@ export class ProviderRegistry {
46
45
  if (!provider) {
47
46
  return null;
48
47
  }
49
- const languageModel = provider.factory(options);
50
- // wrap with aisdk for compatibility with the agent framework
51
- return aisdk(languageModel);
48
+ return provider.factory(options);
52
49
  }
53
50
  /**
54
51
  * Create a completion model instance using the specified provider