@jupyterlite/ai 0.9.1 → 0.10.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 +274 -300
- 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 +19 -54
- package/lib/chat-model.js +243 -303
- package/lib/components/clear-button.d.ts +6 -1
- package/lib/components/clear-button.js +8 -3
- 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 +9 -8
- package/lib/components/stop-button.d.ts +6 -1
- package/lib/components/stop-button.js +8 -3
- 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 +6 -5
- package/lib/index.js +58 -38
- package/lib/models/settings-model.d.ts +1 -1
- 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 +37 -46
- package/lib/tools/file.js +49 -73
- package/lib/tools/notebook.js +370 -445
- 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 +12 -12
- package/src/agent.ts +342 -361
- package/src/approval-buttons.ts +43 -389
- package/src/chat-model-registry.ts +9 -1
- package/src/chat-model.ts +355 -370
- package/src/completion/completion-provider.ts +2 -3
- package/src/components/clear-button.tsx +16 -3
- package/src/components/completion-status.tsx +18 -4
- package/src/components/model-select.tsx +21 -8
- package/src/components/stop-button.tsx +16 -3
- package/src/components/token-usage-display.tsx +14 -2
- package/src/components/tool-select.tsx +23 -5
- package/src/index.ts +75 -36
- package/src/models/settings-model.ts +1 -1
- 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 +39 -50
- package/src/tools/file.ts +49 -75
- package/src/tools/notebook.ts +451 -510
- 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 +13 -73
- package/lib/mcp/browser.d.ts +0 -68
- package/lib/mcp/browser.js +0 -138
- package/src/mcp/browser.ts +0 -220
package/src/index.ts
CHANGED
|
@@ -38,6 +38,12 @@ import { ISettingRegistry } from '@jupyterlab/settingregistry';
|
|
|
38
38
|
|
|
39
39
|
import { IStatusBar } from '@jupyterlab/statusbar';
|
|
40
40
|
|
|
41
|
+
import {
|
|
42
|
+
ITranslator,
|
|
43
|
+
nullTranslator,
|
|
44
|
+
TranslationBundle
|
|
45
|
+
} from '@jupyterlab/translation';
|
|
46
|
+
|
|
41
47
|
import {
|
|
42
48
|
settingsIcon,
|
|
43
49
|
Toolbar,
|
|
@@ -212,7 +218,7 @@ const chatModelRegistry: JupyterFrontEndPlugin<IChatModelRegistry> = {
|
|
|
212
218
|
description: 'Registry for the current chat model',
|
|
213
219
|
autoStart: true,
|
|
214
220
|
requires: [IAISettingsModel, IAgentManagerFactory, IDocumentManager],
|
|
215
|
-
optional: [IProviderRegistry, INotebookTracker, IToolRegistry],
|
|
221
|
+
optional: [IProviderRegistry, INotebookTracker, IToolRegistry, ITranslator],
|
|
216
222
|
provides: IChatModelRegistry,
|
|
217
223
|
activate: (
|
|
218
224
|
app: JupyterFrontEnd,
|
|
@@ -221,8 +227,11 @@ const chatModelRegistry: JupyterFrontEndPlugin<IChatModelRegistry> = {
|
|
|
221
227
|
docManager: IDocumentManager,
|
|
222
228
|
providerRegistry?: IProviderRegistry,
|
|
223
229
|
notebookTracker?: INotebookTracker,
|
|
224
|
-
toolRegistry?: IToolRegistry
|
|
230
|
+
toolRegistry?: IToolRegistry,
|
|
231
|
+
translator?: ITranslator
|
|
225
232
|
): IChatModelRegistry => {
|
|
233
|
+
const trans = (translator ?? nullTranslator).load('jupyterlite_ai');
|
|
234
|
+
|
|
226
235
|
// Create ActiveCellManager if notebook tracker is available
|
|
227
236
|
let activeCellManager: ActiveCellManager | undefined;
|
|
228
237
|
if (notebookTracker) {
|
|
@@ -237,7 +246,8 @@ const chatModelRegistry: JupyterFrontEndPlugin<IChatModelRegistry> = {
|
|
|
237
246
|
agentManagerFactory,
|
|
238
247
|
docManager,
|
|
239
248
|
providerRegistry,
|
|
240
|
-
toolRegistry
|
|
249
|
+
toolRegistry,
|
|
250
|
+
trans
|
|
241
251
|
});
|
|
242
252
|
}
|
|
243
253
|
};
|
|
@@ -255,7 +265,7 @@ const plugin: JupyterFrontEndPlugin<void> = {
|
|
|
255
265
|
IChatModelRegistry,
|
|
256
266
|
IAISettingsModel
|
|
257
267
|
],
|
|
258
|
-
optional: [IThemeManager, ILayoutRestorer, ILabShell],
|
|
268
|
+
optional: [IThemeManager, ILayoutRestorer, ILabShell, ITranslator],
|
|
259
269
|
activate: (
|
|
260
270
|
app: JupyterFrontEnd,
|
|
261
271
|
rmRegistry: IRenderMimeRegistry,
|
|
@@ -264,8 +274,10 @@ const plugin: JupyterFrontEndPlugin<void> = {
|
|
|
264
274
|
settingsModel: AISettingsModel,
|
|
265
275
|
themeManager?: IThemeManager,
|
|
266
276
|
restorer?: ILayoutRestorer,
|
|
267
|
-
labShell?: ILabShell
|
|
277
|
+
labShell?: ILabShell,
|
|
278
|
+
translator?: ITranslator
|
|
268
279
|
): void => {
|
|
280
|
+
const trans = (translator ?? nullTranslator).load('jupyterlite_ai');
|
|
269
281
|
// Create attachment opener registry to handle file attachments
|
|
270
282
|
const attachmentOpenerRegistry = new AttachmentOpenerRegistry();
|
|
271
283
|
attachmentOpenerRegistry.set('file', attachment => {
|
|
@@ -304,7 +316,7 @@ const plugin: JupyterFrontEndPlugin<void> = {
|
|
|
304
316
|
|
|
305
317
|
chatPanel.id = '@jupyterlite/ai:chat-panel';
|
|
306
318
|
chatPanel.title.icon = chatIcon;
|
|
307
|
-
chatPanel.title.caption = 'Chat with AI assistant';
|
|
319
|
+
chatPanel.title.caption = trans.__('Chat with AI assistant');
|
|
308
320
|
|
|
309
321
|
chatPanel.toolbar.addItem('spacer', Toolbar.createSpacerItem());
|
|
310
322
|
chatPanel.toolbar.addItem(
|
|
@@ -314,7 +326,7 @@ const plugin: JupyterFrontEndPlugin<void> = {
|
|
|
314
326
|
onClick: () => {
|
|
315
327
|
app.commands.execute('@jupyterlite/ai:open-settings');
|
|
316
328
|
},
|
|
317
|
-
tooltip: 'Open AI Settings'
|
|
329
|
+
tooltip: trans.__('Open AI Settings')
|
|
318
330
|
})
|
|
319
331
|
);
|
|
320
332
|
|
|
@@ -335,7 +347,8 @@ const plugin: JupyterFrontEndPlugin<void> = {
|
|
|
335
347
|
const tokenUsageWidget = new TokenUsageWidget({
|
|
336
348
|
tokenUsageChanged: model.tokenUsageChanged,
|
|
337
349
|
settingsModel,
|
|
338
|
-
initialTokenUsage: model.agentManager.tokenUsage
|
|
350
|
+
initialTokenUsage: model.agentManager.tokenUsage,
|
|
351
|
+
translator: trans
|
|
339
352
|
});
|
|
340
353
|
section.toolbar.insertBefore('markRead', 'token-usage', tokenUsageWidget);
|
|
341
354
|
model.writersChanged?.connect((_, writers) => {
|
|
@@ -355,7 +368,8 @@ const plugin: JupyterFrontEndPlugin<void> = {
|
|
|
355
368
|
|
|
356
369
|
// Associate an approval buttons object to the chat.
|
|
357
370
|
const approvalButton = new ApprovalButtons({
|
|
358
|
-
chatPanel: widget
|
|
371
|
+
chatPanel: widget,
|
|
372
|
+
agentManager: model.agentManager
|
|
359
373
|
});
|
|
360
374
|
|
|
361
375
|
widget.disposed.connect(() => {
|
|
@@ -407,6 +421,7 @@ const plugin: JupyterFrontEndPlugin<void> = {
|
|
|
407
421
|
settingsModel,
|
|
408
422
|
tracker,
|
|
409
423
|
modelRegistry,
|
|
424
|
+
trans,
|
|
410
425
|
themeManager,
|
|
411
426
|
labShell
|
|
412
427
|
);
|
|
@@ -422,6 +437,7 @@ function registerCommands(
|
|
|
422
437
|
settingsModel: AISettingsModel,
|
|
423
438
|
tracker: WidgetTracker<MainAreaChat | ChatWidget>,
|
|
424
439
|
modelRegistry: IChatModelRegistry,
|
|
440
|
+
trans: TranslationBundle,
|
|
425
441
|
themeManager?: IThemeManager,
|
|
426
442
|
labShell?: ILabShell
|
|
427
443
|
) {
|
|
@@ -429,7 +445,7 @@ function registerCommands(
|
|
|
429
445
|
|
|
430
446
|
if (labShell) {
|
|
431
447
|
commands.addCommand(CommandIds.reposition, {
|
|
432
|
-
label: 'Reposition Widget',
|
|
448
|
+
label: trans.__('Reposition Widget'),
|
|
433
449
|
execute: (args: any) => {
|
|
434
450
|
const { widgetId, area, mode } = args;
|
|
435
451
|
const widget = widgetId
|
|
@@ -456,17 +472,22 @@ function registerCommands(
|
|
|
456
472
|
properties: {
|
|
457
473
|
widgetId: {
|
|
458
474
|
type: 'string',
|
|
459
|
-
description:
|
|
475
|
+
description: trans.__(
|
|
460
476
|
'The widget ID to reposition in the application shell'
|
|
477
|
+
)
|
|
461
478
|
},
|
|
462
479
|
area: {
|
|
463
480
|
type: 'string',
|
|
464
|
-
description:
|
|
481
|
+
description: trans.__(
|
|
482
|
+
'The name of the area to reposition the widget to'
|
|
483
|
+
)
|
|
465
484
|
},
|
|
466
485
|
mode: {
|
|
467
486
|
type: 'string',
|
|
468
487
|
enum: ['split-left', 'split-right', 'split-top', 'split-bottom'],
|
|
469
|
-
description:
|
|
488
|
+
description: trans.__(
|
|
489
|
+
'The mode to use when repositioning the widget'
|
|
490
|
+
)
|
|
470
491
|
}
|
|
471
492
|
}
|
|
472
493
|
}
|
|
@@ -481,7 +502,12 @@ function registerCommands(
|
|
|
481
502
|
inputToolbarRegistry: inputToolbarFactory.create(),
|
|
482
503
|
attachmentOpenerRegistry
|
|
483
504
|
});
|
|
484
|
-
const widget = new MainAreaChat({
|
|
505
|
+
const widget = new MainAreaChat({
|
|
506
|
+
content,
|
|
507
|
+
commands,
|
|
508
|
+
settingsModel,
|
|
509
|
+
trans
|
|
510
|
+
});
|
|
485
511
|
app.shell.add(widget, 'main');
|
|
486
512
|
|
|
487
513
|
// Add the widget to the tracker.
|
|
@@ -501,7 +527,7 @@ function registerCommands(
|
|
|
501
527
|
};
|
|
502
528
|
|
|
503
529
|
commands.addCommand(CommandIds.openChat, {
|
|
504
|
-
label: 'Open a chat',
|
|
530
|
+
label: trans.__('Open a chat'),
|
|
505
531
|
execute: async (args): Promise<boolean> => {
|
|
506
532
|
const area = (args.area as string) === 'main' ? 'main' : 'side';
|
|
507
533
|
const provider = (args.provider as string) ?? undefined;
|
|
@@ -532,15 +558,15 @@ function registerCommands(
|
|
|
532
558
|
area: {
|
|
533
559
|
type: 'string',
|
|
534
560
|
enum: ['main', 'side'],
|
|
535
|
-
description: 'The name of the area to open the chat to'
|
|
561
|
+
description: trans.__('The name of the area to open the chat to')
|
|
536
562
|
},
|
|
537
563
|
name: {
|
|
538
564
|
type: 'string',
|
|
539
|
-
description: 'The name of the chat'
|
|
565
|
+
description: trans.__('The name of the chat')
|
|
540
566
|
},
|
|
541
567
|
provider: {
|
|
542
568
|
type: 'string',
|
|
543
|
-
description: 'The provider/model to use with this chat'
|
|
569
|
+
description: trans.__('The provider/model to use with this chat')
|
|
544
570
|
}
|
|
545
571
|
}
|
|
546
572
|
}
|
|
@@ -548,7 +574,7 @@ function registerCommands(
|
|
|
548
574
|
});
|
|
549
575
|
|
|
550
576
|
commands.addCommand(CommandIds.moveChat, {
|
|
551
|
-
caption: 'Move chat between area',
|
|
577
|
+
caption: trans.__('Move chat between area'),
|
|
552
578
|
execute: async (args): Promise<boolean> => {
|
|
553
579
|
const area = args.area as string;
|
|
554
580
|
if (!['side', 'main'].includes(area)) {
|
|
@@ -601,7 +627,7 @@ function registerCommands(
|
|
|
601
627
|
trackerUpdated.promise,
|
|
602
628
|
new Promise<boolean>(r =>
|
|
603
629
|
setTimeout(() => {
|
|
604
|
-
|
|
630
|
+
r(false);
|
|
605
631
|
}, 2000)
|
|
606
632
|
)
|
|
607
633
|
]);
|
|
@@ -634,11 +660,11 @@ function registerCommands(
|
|
|
634
660
|
area: {
|
|
635
661
|
type: 'string',
|
|
636
662
|
enum: ['main', 'side'],
|
|
637
|
-
description: 'The name of the area to move the chat to'
|
|
663
|
+
description: trans.__('The name of the area to move the chat to')
|
|
638
664
|
},
|
|
639
665
|
name: {
|
|
640
666
|
type: 'string',
|
|
641
|
-
description: 'The name of the chat to move'
|
|
667
|
+
description: trans.__('The name of the chat to move')
|
|
642
668
|
}
|
|
643
669
|
},
|
|
644
670
|
requires: ['area', 'name']
|
|
@@ -663,7 +689,8 @@ const agentManagerFactory: JupyterFrontEndPlugin<AgentManagerFactory> =
|
|
|
663
689
|
ICompletionProviderManager,
|
|
664
690
|
ILayoutRestorer,
|
|
665
691
|
ISecretsManager,
|
|
666
|
-
IThemeManager
|
|
692
|
+
IThemeManager,
|
|
693
|
+
ITranslator
|
|
667
694
|
],
|
|
668
695
|
activate: (
|
|
669
696
|
app: JupyterFrontEnd,
|
|
@@ -673,8 +700,10 @@ const agentManagerFactory: JupyterFrontEndPlugin<AgentManagerFactory> =
|
|
|
673
700
|
completionManager?: ICompletionProviderManager,
|
|
674
701
|
restorer?: ILayoutRestorer,
|
|
675
702
|
secretsManager?: ISecretsManager,
|
|
676
|
-
themeManager?: IThemeManager
|
|
703
|
+
themeManager?: IThemeManager,
|
|
704
|
+
translator?: ITranslator
|
|
677
705
|
): AgentManagerFactory => {
|
|
706
|
+
const trans = (translator ?? nullTranslator).load('jupyterlite_ai');
|
|
678
707
|
const agentManagerFactory = new AgentManagerFactory({
|
|
679
708
|
settingsModel,
|
|
680
709
|
secretsManager,
|
|
@@ -688,7 +717,8 @@ const agentManagerFactory: JupyterFrontEndPlugin<AgentManagerFactory> =
|
|
|
688
717
|
themeManager,
|
|
689
718
|
providerRegistry,
|
|
690
719
|
secretsManager,
|
|
691
|
-
token
|
|
720
|
+
token,
|
|
721
|
+
trans
|
|
692
722
|
});
|
|
693
723
|
settingsWidget.id = 'jupyterlite-ai-settings';
|
|
694
724
|
settingsWidget.title.icon = settingsIcon;
|
|
@@ -715,8 +745,8 @@ const agentManagerFactory: JupyterFrontEndPlugin<AgentManagerFactory> =
|
|
|
715
745
|
}
|
|
716
746
|
|
|
717
747
|
app.commands.addCommand(CommandIds.openSettings, {
|
|
718
|
-
label: 'AI Settings',
|
|
719
|
-
caption: 'Configure AI providers and behavior',
|
|
748
|
+
label: trans.__('AI Settings'),
|
|
749
|
+
caption: trans.__('Configure AI providers and behavior'),
|
|
720
750
|
icon: settingsIcon,
|
|
721
751
|
iconClass: 'jp-ai-settings-icon',
|
|
722
752
|
execute: () => {
|
|
@@ -744,7 +774,7 @@ const agentManagerFactory: JupyterFrontEndPlugin<AgentManagerFactory> =
|
|
|
744
774
|
if (palette) {
|
|
745
775
|
palette.addItem({
|
|
746
776
|
command: CommandIds.openSettings,
|
|
747
|
-
category: 'AI Assistant'
|
|
777
|
+
category: trans.__('AI Assistant')
|
|
748
778
|
});
|
|
749
779
|
}
|
|
750
780
|
|
|
@@ -888,18 +918,22 @@ const inputToolbarFactory: JupyterFrontEndPlugin<IInputToolbarRegistryFactory> =
|
|
|
888
918
|
autoStart: true,
|
|
889
919
|
provides: IInputToolbarRegistryFactory,
|
|
890
920
|
requires: [IAISettingsModel, IToolRegistry],
|
|
921
|
+
optional: [ITranslator],
|
|
891
922
|
activate: (
|
|
892
923
|
app: JupyterFrontEnd,
|
|
893
924
|
settingsModel: AISettingsModel,
|
|
894
|
-
toolRegistry: IToolRegistry
|
|
925
|
+
toolRegistry: IToolRegistry,
|
|
926
|
+
translator?: ITranslator
|
|
895
927
|
): IInputToolbarRegistryFactory => {
|
|
896
|
-
const
|
|
897
|
-
const
|
|
928
|
+
const trans = (translator ?? nullTranslator).load('jupyterlite_ai');
|
|
929
|
+
const stopButton = stopItem(trans);
|
|
930
|
+
const clearButton = clearItem(trans);
|
|
898
931
|
const toolSelectButton = createToolSelectItem(
|
|
899
932
|
toolRegistry,
|
|
900
|
-
settingsModel.config.toolsEnabled
|
|
933
|
+
settingsModel.config.toolsEnabled,
|
|
934
|
+
trans
|
|
901
935
|
);
|
|
902
|
-
const modelSelectButton = createModelSelectItem(settingsModel);
|
|
936
|
+
const modelSelectButton = createModelSelectItem(settingsModel, trans);
|
|
903
937
|
|
|
904
938
|
return {
|
|
905
939
|
create() {
|
|
@@ -931,16 +965,21 @@ const completionStatus: JupyterFrontEndPlugin<void> = {
|
|
|
931
965
|
description: 'The completion status displayed in the status bar',
|
|
932
966
|
autoStart: true,
|
|
933
967
|
requires: [IAISettingsModel],
|
|
934
|
-
optional: [IStatusBar],
|
|
968
|
+
optional: [IStatusBar, ITranslator],
|
|
935
969
|
activate: (
|
|
936
970
|
app: JupyterFrontEnd,
|
|
937
971
|
settingsModel: AISettingsModel,
|
|
938
|
-
statusBar: IStatusBar | null
|
|
972
|
+
statusBar: IStatusBar | null,
|
|
973
|
+
translator?: ITranslator
|
|
939
974
|
) => {
|
|
940
975
|
if (!statusBar) {
|
|
941
976
|
return;
|
|
942
977
|
}
|
|
943
|
-
const
|
|
978
|
+
const trans = (translator ?? nullTranslator).load('jupyterlite_ai');
|
|
979
|
+
const item = new CompletionStatusWidget({
|
|
980
|
+
settingsModel,
|
|
981
|
+
translator: trans
|
|
982
|
+
});
|
|
944
983
|
statusBar?.registerStatusItem('completionState', {
|
|
945
984
|
item,
|
|
946
985
|
align: 'right',
|
|
@@ -15,15 +15,17 @@ export const anthropicProvider: IProviderInfo = {
|
|
|
15
15
|
name: 'Anthropic Claude',
|
|
16
16
|
apiKeyRequirement: 'required',
|
|
17
17
|
defaultModels: [
|
|
18
|
+
'claude-opus-4-5',
|
|
19
|
+
'claude-opus-4-5-20251101',
|
|
18
20
|
'claude-sonnet-4-5',
|
|
19
21
|
'claude-sonnet-4-5-20250929',
|
|
20
22
|
'claude-haiku-4-5',
|
|
21
23
|
'claude-haiku-4-5-20251001',
|
|
22
24
|
'claude-opus-4-1',
|
|
23
|
-
'claude-opus-4-0',
|
|
24
|
-
'claude-sonnet-4-0',
|
|
25
25
|
'claude-opus-4-1-20250805',
|
|
26
|
+
'claude-opus-4-0',
|
|
26
27
|
'claude-opus-4-20250514',
|
|
28
|
+
'claude-sonnet-4-0',
|
|
27
29
|
'claude-sonnet-4-20250514',
|
|
28
30
|
'claude-3-7-sonnet-latest',
|
|
29
31
|
'claude-3-7-sonnet-20250219',
|
|
@@ -58,8 +60,11 @@ export const googleProvider: IProviderInfo = {
|
|
|
58
60
|
name: 'Google Generative AI',
|
|
59
61
|
apiKeyRequirement: 'required',
|
|
60
62
|
defaultModels: [
|
|
61
|
-
'gemini-
|
|
63
|
+
'gemini-3-pro-preview',
|
|
64
|
+
'gemini-3-pro-image-preview',
|
|
65
|
+
'gemini-3-flash-preview',
|
|
62
66
|
'gemini-2.5-pro',
|
|
67
|
+
'gemini-2.5-flash',
|
|
63
68
|
'gemini-2.5-flash-image-preview',
|
|
64
69
|
'gemini-2.5-flash-lite',
|
|
65
70
|
'gemini-2.5-flash-lite-preview-09-2025',
|
|
@@ -84,6 +89,9 @@ export const googleProvider: IProviderInfo = {
|
|
|
84
89
|
'gemini-1.5-pro-latest',
|
|
85
90
|
'gemini-1.5-pro-001',
|
|
86
91
|
'gemini-1.5-pro-002',
|
|
92
|
+
'gemini-pro-latest',
|
|
93
|
+
'gemini-flash-latest',
|
|
94
|
+
'gemini-flash-lite-latest',
|
|
87
95
|
'gemini-exp-1206',
|
|
88
96
|
'gemma-3-12b-it',
|
|
89
97
|
'gemma-3-27b-it'
|
|
@@ -150,12 +158,32 @@ export const openaiProvider: IProviderInfo = {
|
|
|
150
158
|
name: 'OpenAI',
|
|
151
159
|
apiKeyRequirement: 'required',
|
|
152
160
|
defaultModels: [
|
|
153
|
-
'
|
|
154
|
-
'
|
|
155
|
-
'
|
|
156
|
-
'
|
|
161
|
+
'gpt-5.2',
|
|
162
|
+
'gpt-5.2-chat-latest',
|
|
163
|
+
'gpt-5.2-pro',
|
|
164
|
+
'gpt-5.1',
|
|
165
|
+
'gpt-5.1-chat-latest',
|
|
166
|
+
'gpt-5.1-codex',
|
|
167
|
+
'gpt-5.1-codex-mini',
|
|
168
|
+
'gpt-5.1-codex-max',
|
|
169
|
+
'gpt-5',
|
|
170
|
+
'gpt-5-2025-08-07',
|
|
171
|
+
'gpt-5-chat-latest',
|
|
172
|
+
'gpt-5-codex',
|
|
173
|
+
'gpt-5-pro',
|
|
174
|
+
'gpt-5-pro-2025-10-06',
|
|
175
|
+
'gpt-5-mini',
|
|
176
|
+
'gpt-5-mini-2025-08-07',
|
|
177
|
+
'gpt-5-nano',
|
|
178
|
+
'gpt-5-nano-2025-08-07',
|
|
157
179
|
'o3',
|
|
158
180
|
'o3-2025-04-16',
|
|
181
|
+
'o3-mini',
|
|
182
|
+
'o3-mini-2025-01-31',
|
|
183
|
+
'o1',
|
|
184
|
+
'o1-2024-12-17',
|
|
185
|
+
'gpt-4.5-preview',
|
|
186
|
+
'gpt-4.5-preview-2025-02-27',
|
|
159
187
|
'gpt-4.1',
|
|
160
188
|
'gpt-4.1-2025-04-14',
|
|
161
189
|
'gpt-4.1-mini',
|
|
@@ -168,23 +196,14 @@ export const openaiProvider: IProviderInfo = {
|
|
|
168
196
|
'gpt-4o-2024-11-20',
|
|
169
197
|
'gpt-4o-mini',
|
|
170
198
|
'gpt-4o-mini-2024-07-18',
|
|
199
|
+
'chatgpt-4o-latest',
|
|
171
200
|
'gpt-4-turbo',
|
|
172
201
|
'gpt-4-turbo-2024-04-09',
|
|
173
202
|
'gpt-4',
|
|
174
203
|
'gpt-4-0613',
|
|
175
|
-
'gpt-4.5-preview',
|
|
176
|
-
'gpt-4.5-preview-2025-02-27',
|
|
177
|
-
'gpt-3.5-turbo-0125',
|
|
178
204
|
'gpt-3.5-turbo',
|
|
179
|
-
'gpt-3.5-turbo-
|
|
180
|
-
'
|
|
181
|
-
'gpt-5',
|
|
182
|
-
'gpt-5-2025-08-07',
|
|
183
|
-
'gpt-5-mini',
|
|
184
|
-
'gpt-5-mini-2025-08-07',
|
|
185
|
-
'gpt-5-nano',
|
|
186
|
-
'gpt-5-nano-2025-08-07',
|
|
187
|
-
'gpt-5-chat-latest'
|
|
205
|
+
'gpt-3.5-turbo-0125',
|
|
206
|
+
'gpt-3.5-turbo-1106'
|
|
188
207
|
],
|
|
189
208
|
supportsBaseURL: true,
|
|
190
209
|
supportsHeaders: true,
|
package/src/providers/models.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { LanguageModel } from 'ai';
|
|
2
2
|
import type { IProviderRegistry } from '../tokens';
|
|
3
3
|
|
|
4
4
|
/**
|
|
@@ -38,7 +38,7 @@ export interface IModelOptions {
|
|
|
38
38
|
export function createCompletionModel(
|
|
39
39
|
options: IModelOptions,
|
|
40
40
|
registry?: IProviderRegistry
|
|
41
|
-
):
|
|
41
|
+
): LanguageModel {
|
|
42
42
|
if (!registry) {
|
|
43
43
|
throw new Error('Provider registry not available');
|
|
44
44
|
}
|
|
@@ -60,7 +60,7 @@ export function createCompletionModel(
|
|
|
60
60
|
export function createModel(
|
|
61
61
|
options: IModelOptions,
|
|
62
62
|
registry?: IProviderRegistry
|
|
63
|
-
) {
|
|
63
|
+
): LanguageModel {
|
|
64
64
|
if (!registry) {
|
|
65
65
|
throw new Error('Provider registry not available');
|
|
66
66
|
}
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import { ISignal, Signal } from '@lumino/signaling';
|
|
2
|
-
import type {
|
|
3
|
-
import type { Model } from '@openai/agents';
|
|
4
|
-
import { aisdk } from '@openai/agents-extensions';
|
|
2
|
+
import type { LanguageModel } from 'ai';
|
|
5
3
|
import type { IModelOptions } from './models';
|
|
6
4
|
import { IProviderInfo, IProviderRegistry } from '../tokens';
|
|
7
5
|
|
|
@@ -50,15 +48,13 @@ export class ProviderRegistry implements IProviderRegistry {
|
|
|
50
48
|
* @param options Model configuration options
|
|
51
49
|
* @returns Chat model instance or null if creation fails
|
|
52
50
|
*/
|
|
53
|
-
createChatModel(id: string, options: IModelOptions):
|
|
51
|
+
createChatModel(id: string, options: IModelOptions): LanguageModel | null {
|
|
54
52
|
const provider = this._providers[id];
|
|
55
53
|
if (!provider) {
|
|
56
54
|
return null;
|
|
57
55
|
}
|
|
58
56
|
|
|
59
|
-
|
|
60
|
-
// wrap with aisdk for compatibility with the agent framework
|
|
61
|
-
return aisdk(languageModel);
|
|
57
|
+
return provider.factory(options);
|
|
62
58
|
}
|
|
63
59
|
|
|
64
60
|
/**
|
|
@@ -70,7 +66,7 @@ export class ProviderRegistry implements IProviderRegistry {
|
|
|
70
66
|
createCompletionModel(
|
|
71
67
|
id: string,
|
|
72
68
|
options: IModelOptions
|
|
73
|
-
):
|
|
69
|
+
): LanguageModel | null {
|
|
74
70
|
const provider = this._providers[id];
|
|
75
71
|
if (!provider) {
|
|
76
72
|
return null;
|
package/src/tokens.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { Token } from '@lumino/coreutils';
|
|
2
2
|
import { ISignal } from '@lumino/signaling';
|
|
3
|
-
import {
|
|
4
|
-
import { LanguageModelV2 } from '@ai-sdk/provider';
|
|
3
|
+
import type { Tool, LanguageModel } from 'ai';
|
|
5
4
|
import { AgentManager } from './agent';
|
|
6
5
|
import type { AISettingsModel } from './models/settings-model';
|
|
7
6
|
import type { IModelOptions } from './providers/models';
|
|
@@ -21,7 +20,7 @@ export namespace CommandIds {
|
|
|
21
20
|
/**
|
|
22
21
|
* Type definition for a tool
|
|
23
22
|
*/
|
|
24
|
-
export type ITool =
|
|
23
|
+
export type ITool = Tool;
|
|
25
24
|
|
|
26
25
|
/**
|
|
27
26
|
* Interface for token usage statistics from AI model interactions
|
|
@@ -109,7 +108,7 @@ export const IProviderRegistry = new Token<IProviderRegistry>(
|
|
|
109
108
|
* Interface for a provider factory function that creates language models
|
|
110
109
|
*/
|
|
111
110
|
export interface IProviderFactory {
|
|
112
|
-
(options: IModelOptions):
|
|
111
|
+
(options: IModelOptions): LanguageModel;
|
|
113
112
|
}
|
|
114
113
|
|
|
115
114
|
/**
|
|
@@ -197,7 +196,7 @@ export interface IProviderRegistry {
|
|
|
197
196
|
/**
|
|
198
197
|
* Create a chat model instance for the given provider.
|
|
199
198
|
*/
|
|
200
|
-
createChatModel(id: string, options: IModelOptions):
|
|
199
|
+
createChatModel(id: string, options: IModelOptions): LanguageModel | null;
|
|
201
200
|
|
|
202
201
|
/**
|
|
203
202
|
* Create a completion model instance for the given provider.
|
|
@@ -205,7 +204,7 @@ export interface IProviderRegistry {
|
|
|
205
204
|
createCompletionModel(
|
|
206
205
|
id: string,
|
|
207
206
|
options: IModelOptions
|
|
208
|
-
):
|
|
207
|
+
): LanguageModel | null;
|
|
209
208
|
|
|
210
209
|
/**
|
|
211
210
|
* Get all available provider IDs.
|
package/src/tools/commands.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { CommandRegistry } from '@lumino/commands';
|
|
2
|
-
import { tool } from '
|
|
2
|
+
import { tool } from 'ai';
|
|
3
3
|
import { z } from 'zod';
|
|
4
4
|
import { ITool } from '../tokens';
|
|
5
5
|
import { AISettingsModel } from '../models/settings-model';
|
|
@@ -9,11 +9,10 @@ import { AISettingsModel } from '../models/settings-model';
|
|
|
9
9
|
*/
|
|
10
10
|
export function createDiscoverCommandsTool(commands: CommandRegistry): ITool {
|
|
11
11
|
return tool({
|
|
12
|
-
|
|
12
|
+
title: 'Discover Commands',
|
|
13
13
|
description:
|
|
14
14
|
'Discover all available JupyterLab commands with their metadata, arguments, and descriptions',
|
|
15
|
-
|
|
16
|
-
// currently unused, but could be used to filter commands by a search term
|
|
15
|
+
inputSchema: z.object({
|
|
17
16
|
query: z
|
|
18
17
|
.string()
|
|
19
18
|
.optional()
|
|
@@ -75,31 +74,28 @@ export function createDiscoverCommandsTool(commands: CommandRegistry): ITool {
|
|
|
75
74
|
}
|
|
76
75
|
|
|
77
76
|
/**
|
|
78
|
-
* Create a tool to execute a specific JupyterLab command
|
|
77
|
+
* Create a tool to execute a specific JupyterLab command.
|
|
78
|
+
* Commands in the settings' commandsRequiringApproval list will need approval.
|
|
79
79
|
*/
|
|
80
80
|
export function createExecuteCommandTool(
|
|
81
81
|
commands: CommandRegistry,
|
|
82
82
|
settingsModel: AISettingsModel
|
|
83
83
|
): ITool {
|
|
84
84
|
return tool({
|
|
85
|
-
|
|
85
|
+
title: 'Execute Command',
|
|
86
86
|
description:
|
|
87
87
|
'Execute a specific JupyterLab command with optional arguments',
|
|
88
|
-
|
|
88
|
+
inputSchema: z.object({
|
|
89
89
|
commandId: z.string().describe('The ID of the command to execute'),
|
|
90
90
|
args: z
|
|
91
91
|
.any()
|
|
92
92
|
.optional()
|
|
93
93
|
.describe('Optional arguments to pass to the command')
|
|
94
94
|
}),
|
|
95
|
-
needsApproval:
|
|
96
|
-
// Use configurable list of commands requiring approval
|
|
95
|
+
needsApproval: (input: { commandId: string; args?: any }) => {
|
|
97
96
|
const commandsRequiringApproval =
|
|
98
|
-
settingsModel.config.commandsRequiringApproval;
|
|
99
|
-
|
|
100
|
-
return commandsRequiringApproval.some(
|
|
101
|
-
cmd => commandId.includes(cmd) || cmd.includes(commandId)
|
|
102
|
-
);
|
|
97
|
+
settingsModel.config.commandsRequiringApproval || [];
|
|
98
|
+
return commandsRequiringApproval.includes(input.commandId);
|
|
103
99
|
},
|
|
104
100
|
execute: async (input: { commandId: string; args?: any }) => {
|
|
105
101
|
const { commandId, args } = input;
|
|
@@ -112,45 +108,38 @@ export function createExecuteCommandTool(
|
|
|
112
108
|
};
|
|
113
109
|
}
|
|
114
110
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
const result = await commands.execute(commandId, args);
|
|
111
|
+
// Execute the command
|
|
112
|
+
const result = await commands.execute(commandId, args);
|
|
118
113
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
};
|
|
132
|
-
} else {
|
|
133
|
-
// For other objects, try JSON serialization with fallback
|
|
134
|
-
try {
|
|
135
|
-
serializedResult = JSON.parse(JSON.stringify(result));
|
|
136
|
-
} catch {
|
|
137
|
-
serializedResult = result
|
|
138
|
-
? '[Complex object - cannot serialize]'
|
|
139
|
-
: 'Command executed successfully';
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
return {
|
|
144
|
-
success: true,
|
|
145
|
-
commandId,
|
|
146
|
-
result: serializedResult
|
|
147
|
-
};
|
|
148
|
-
} catch (error) {
|
|
149
|
-
return {
|
|
150
|
-
success: false,
|
|
151
|
-
error: `Failed to execute command '${commandId}': ${error instanceof Error ? error.message : String(error)}`
|
|
114
|
+
// Handle Widget objects specially (including subclasses like DocumentWidget)
|
|
115
|
+
let serializedResult;
|
|
116
|
+
if (
|
|
117
|
+
result &&
|
|
118
|
+
typeof result === 'object' &&
|
|
119
|
+
(result.constructor?.name?.includes('Widget') || result.id)
|
|
120
|
+
) {
|
|
121
|
+
serializedResult = {
|
|
122
|
+
type: result.constructor?.name || 'Widget',
|
|
123
|
+
id: result.id,
|
|
124
|
+
title: result.title?.label || result.title,
|
|
125
|
+
className: result.className
|
|
152
126
|
};
|
|
127
|
+
} else {
|
|
128
|
+
// For other objects, try JSON serialization with fallback
|
|
129
|
+
try {
|
|
130
|
+
serializedResult = JSON.parse(JSON.stringify(result));
|
|
131
|
+
} catch {
|
|
132
|
+
serializedResult = result
|
|
133
|
+
? '[Complex object - cannot serialize]'
|
|
134
|
+
: 'Command executed successfully';
|
|
135
|
+
}
|
|
153
136
|
}
|
|
137
|
+
|
|
138
|
+
return {
|
|
139
|
+
success: true,
|
|
140
|
+
commandId,
|
|
141
|
+
result: serializedResult
|
|
142
|
+
};
|
|
154
143
|
}
|
|
155
144
|
});
|
|
156
145
|
}
|