@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/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';
|
|
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:
|
|
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:
|
|
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({
|
|
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
|
-
|
|
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
|
|
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
|
|
897
|
-
const
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
122
|
-
- Provide suggestions tailored to
|
|
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
|
|
126
|
-
|
|
127
|
-
- Execute operations directly in
|
|
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
|
-
##
|
|
133
|
-
|
|
134
|
-
- **
|
|
135
|
-
- **
|
|
136
|
-
|
|
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**:
|
|
140
|
-
- **Progress Updates**:
|
|
141
|
-
- **No Filler**:
|
|
142
|
-
- **Purposeful Communication**:
|
|
143
|
-
- **Active Narration**:
|
|
144
|
-
- **Checkpoint Updates**: After several operations,
|
|
145
|
-
- **Natural Flow**:
|
|
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
|
-
-
|
|
153
|
-
- When creating or modifying multiple files,
|
|
154
|
-
-
|
|
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"),
|
|
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
|
-
|
|
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.
|