@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.
- package/README.md +5 -214
- package/lib/agent.d.ts +58 -66
- package/lib/agent.js +291 -310
- package/lib/approval-buttons.d.ts +19 -82
- package/lib/approval-buttons.js +36 -289
- package/lib/chat-model-registry.d.ts +6 -0
- package/lib/chat-model-registry.js +4 -1
- package/lib/chat-model.d.ts +26 -54
- package/lib/chat-model.js +277 -303
- package/lib/components/clear-button.d.ts +6 -1
- package/lib/components/clear-button.js +10 -6
- package/lib/components/completion-status.d.ts +5 -0
- package/lib/components/completion-status.js +5 -4
- package/lib/components/model-select.d.ts +6 -1
- package/lib/components/model-select.js +13 -16
- package/lib/components/stop-button.d.ts +6 -1
- package/lib/components/stop-button.js +12 -8
- package/lib/components/token-usage-display.d.ts +5 -0
- package/lib/components/token-usage-display.js +2 -2
- package/lib/components/tool-select.d.ts +6 -1
- package/lib/components/tool-select.js +10 -9
- package/lib/index.d.ts +1 -0
- package/lib/index.js +61 -81
- package/lib/models/settings-model.d.ts +1 -1
- package/lib/models/settings-model.js +40 -26
- package/lib/providers/built-in-providers.js +38 -19
- package/lib/providers/models.d.ts +3 -3
- package/lib/providers/provider-registry.d.ts +3 -4
- package/lib/providers/provider-registry.js +1 -4
- package/lib/tokens.d.ts +5 -6
- package/lib/tools/commands.d.ts +2 -1
- package/lib/tools/commands.js +36 -49
- package/lib/widgets/ai-settings.d.ts +6 -0
- package/lib/widgets/ai-settings.js +72 -71
- package/lib/widgets/main-area-chat.d.ts +2 -0
- package/lib/widgets/main-area-chat.js +5 -2
- package/lib/widgets/provider-config-dialog.d.ts +2 -0
- package/lib/widgets/provider-config-dialog.js +34 -34
- package/package.json +13 -13
- package/schema/settings-model.json +3 -2
- package/src/agent.ts +360 -372
- package/src/approval-buttons.ts +43 -389
- package/src/chat-model-registry.ts +9 -1
- package/src/chat-model.ts +399 -370
- package/src/completion/completion-provider.ts +2 -3
- package/src/components/clear-button.tsx +18 -6
- package/src/components/completion-status.tsx +18 -4
- package/src/components/model-select.tsx +25 -16
- package/src/components/stop-button.tsx +22 -9
- package/src/components/token-usage-display.tsx +14 -2
- package/src/components/tool-select.tsx +27 -9
- package/src/index.ts +78 -134
- package/src/models/settings-model.ts +41 -27
- package/src/providers/built-in-providers.ts +38 -19
- package/src/providers/models.ts +3 -3
- package/src/providers/provider-registry.ts +4 -8
- package/src/tokens.ts +5 -6
- package/src/tools/commands.ts +40 -53
- package/src/widgets/ai-settings.tsx +153 -84
- package/src/widgets/main-area-chat.ts +8 -2
- package/src/widgets/provider-config-dialog.tsx +54 -41
- package/style/base.css +24 -73
- package/lib/mcp/browser.d.ts +0 -68
- package/lib/mcp/browser.js +0 -138
- package/lib/tools/file.d.ts +0 -36
- package/lib/tools/file.js +0 -351
- package/lib/tools/notebook.d.ts +0 -40
- package/lib/tools/notebook.js +0 -779
- package/src/mcp/browser.ts +0 -220
- package/src/tools/file.ts +0 -438
- 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';
|
|
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({
|
|
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
|
-
|
|
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
|
|
558
|
-
optional: [INotebookTracker, IDiffManager, IEditorTracker],
|
|
567
|
+
requires: [IAISettingsModel],
|
|
559
568
|
provides: IToolRegistry,
|
|
560
|
-
activate: (app, settingsModel
|
|
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
|
-
|
|
616
|
-
|
|
617
|
-
const
|
|
618
|
-
const
|
|
619
|
-
const
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
60
|
-
- Provide suggestions tailored to
|
|
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
|
|
64
|
-
|
|
65
|
-
- Execute operations directly in
|
|
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
|
-
##
|
|
71
|
-
|
|
72
|
-
- **
|
|
73
|
-
- **
|
|
74
|
-
|
|
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**:
|
|
78
|
-
- **Progress Updates**:
|
|
79
|
-
- **No Filler**:
|
|
80
|
-
- **Purposeful Communication**:
|
|
81
|
-
- **Active Narration**:
|
|
82
|
-
- **Checkpoint Updates**: After several operations,
|
|
83
|
-
- **Natural Flow**:
|
|
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
|
-
-
|
|
91
|
-
- When creating or modifying multiple files,
|
|
92
|
-
-
|
|
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"),
|
|
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
|
-
|
|
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-
|
|
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
|
-
'
|
|
147
|
-
'
|
|
148
|
-
'
|
|
149
|
-
'
|
|
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-
|
|
173
|
-
'
|
|
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 {
|
|
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):
|
|
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):
|
|
37
|
+
export declare function createModel(options: IModelOptions, registry?: IProviderRegistry): LanguageModel;
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { ISignal } from '@lumino/signaling';
|
|
2
|
-
import type {
|
|
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):
|
|
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):
|
|
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
|
-
|
|
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
|