@jupyterlite/ai 0.8.1 → 0.9.0-a0
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/lib/agent.d.ts +233 -0
- package/lib/agent.js +604 -0
- package/lib/chat-model.d.ts +195 -0
- package/lib/chat-model.js +590 -0
- package/lib/completion/completion-provider.d.ts +83 -0
- package/lib/completion/completion-provider.js +209 -0
- package/lib/completion/index.d.ts +1 -0
- package/lib/completion/index.js +1 -0
- package/lib/components/clear-button.d.ts +18 -0
- package/lib/components/clear-button.js +31 -0
- package/lib/components/index.d.ts +3 -0
- package/lib/components/index.js +3 -0
- package/lib/components/model-select.d.ts +19 -0
- package/lib/components/model-select.js +154 -0
- package/lib/components/stop-button.d.ts +3 -3
- package/lib/components/stop-button.js +8 -9
- package/lib/components/token-usage-display.d.ts +45 -0
- package/lib/components/token-usage-display.js +74 -0
- package/lib/components/tool-select.d.ts +27 -0
- package/lib/components/tool-select.js +130 -0
- package/lib/icons.d.ts +3 -1
- package/lib/icons.js +10 -13
- package/lib/index.d.ts +4 -5
- package/lib/index.js +322 -167
- package/lib/mcp/browser.d.ts +68 -0
- package/lib/mcp/browser.js +132 -0
- package/lib/models/settings-model.d.ts +69 -0
- package/lib/models/settings-model.js +295 -0
- package/lib/providers/built-in-providers.d.ts +9 -0
- package/lib/providers/built-in-providers.js +192 -0
- package/lib/providers/models.d.ts +37 -0
- package/lib/providers/models.js +28 -0
- package/lib/providers/provider-registry.d.ts +94 -0
- package/lib/providers/provider-registry.js +155 -0
- package/lib/tokens.d.ts +157 -86
- package/lib/tokens.js +16 -12
- package/lib/tools/commands.d.ts +11 -0
- package/lib/tools/commands.js +126 -0
- package/lib/tools/file.d.ts +27 -0
- package/lib/tools/file.js +262 -0
- package/lib/tools/notebook.d.ts +40 -0
- package/lib/tools/notebook.js +762 -0
- package/lib/tools/tool-registry.d.ts +35 -0
- package/lib/tools/tool-registry.js +55 -0
- package/lib/widgets/ai-settings.d.ts +39 -0
- package/lib/widgets/ai-settings.js +506 -0
- package/lib/widgets/chat-wrapper.d.ts +144 -0
- package/lib/widgets/chat-wrapper.js +390 -0
- package/lib/widgets/provider-config-dialog.d.ts +13 -0
- package/lib/widgets/provider-config-dialog.js +104 -0
- package/package.json +150 -41
- package/schema/settings-model.json +153 -0
- package/src/agent.ts +800 -0
- package/src/chat-model.ts +770 -0
- package/src/completion/completion-provider.ts +308 -0
- package/src/completion/index.ts +1 -0
- package/src/components/clear-button.tsx +56 -0
- package/src/components/index.ts +3 -0
- package/src/components/model-select.tsx +245 -0
- package/src/components/stop-button.tsx +11 -11
- package/src/components/token-usage-display.tsx +130 -0
- package/src/components/tool-select.tsx +218 -0
- package/src/icons.ts +12 -14
- package/src/index.ts +468 -238
- package/src/mcp/browser.ts +213 -0
- package/src/models/settings-model.ts +409 -0
- package/src/providers/built-in-providers.ts +216 -0
- package/src/providers/models.ts +79 -0
- package/src/providers/provider-registry.ts +189 -0
- package/src/tokens.ts +203 -90
- package/src/tools/commands.ts +151 -0
- package/src/tools/file.ts +307 -0
- package/src/tools/notebook.ts +964 -0
- package/src/tools/tool-registry.ts +63 -0
- package/src/types.d.ts +4 -0
- package/src/widgets/ai-settings.tsx +1100 -0
- package/src/widgets/chat-wrapper.tsx +543 -0
- package/src/widgets/provider-config-dialog.tsx +256 -0
- package/style/base.css +335 -14
- package/style/icons/jupyternaut-lite.svg +1 -1
- package/lib/base-completer.d.ts +0 -49
- package/lib/base-completer.js +0 -14
- package/lib/chat-handler.d.ts +0 -56
- package/lib/chat-handler.js +0 -201
- package/lib/completion-provider.d.ts +0 -34
- package/lib/completion-provider.js +0 -32
- package/lib/default-prompts.d.ts +0 -2
- package/lib/default-prompts.js +0 -31
- package/lib/default-providers/Anthropic/completer.d.ts +0 -12
- package/lib/default-providers/Anthropic/completer.js +0 -46
- package/lib/default-providers/Anthropic/settings-schema.json +0 -70
- package/lib/default-providers/ChromeAI/completer.d.ts +0 -12
- package/lib/default-providers/ChromeAI/completer.js +0 -56
- package/lib/default-providers/ChromeAI/instructions.d.ts +0 -6
- package/lib/default-providers/ChromeAI/instructions.js +0 -42
- package/lib/default-providers/ChromeAI/settings-schema.json +0 -18
- package/lib/default-providers/Gemini/completer.d.ts +0 -12
- package/lib/default-providers/Gemini/completer.js +0 -48
- package/lib/default-providers/Gemini/instructions.d.ts +0 -2
- package/lib/default-providers/Gemini/instructions.js +0 -9
- package/lib/default-providers/Gemini/settings-schema.json +0 -64
- package/lib/default-providers/MistralAI/completer.d.ts +0 -13
- package/lib/default-providers/MistralAI/completer.js +0 -52
- package/lib/default-providers/MistralAI/instructions.d.ts +0 -2
- package/lib/default-providers/MistralAI/instructions.js +0 -18
- package/lib/default-providers/MistralAI/settings-schema.json +0 -75
- package/lib/default-providers/Ollama/completer.d.ts +0 -12
- package/lib/default-providers/Ollama/completer.js +0 -43
- package/lib/default-providers/Ollama/instructions.d.ts +0 -2
- package/lib/default-providers/Ollama/instructions.js +0 -70
- package/lib/default-providers/Ollama/settings-schema.json +0 -143
- package/lib/default-providers/OpenAI/completer.d.ts +0 -12
- package/lib/default-providers/OpenAI/completer.js +0 -43
- package/lib/default-providers/OpenAI/settings-schema.json +0 -628
- package/lib/default-providers/WebLLM/completer.d.ts +0 -21
- package/lib/default-providers/WebLLM/completer.js +0 -127
- package/lib/default-providers/WebLLM/instructions.d.ts +0 -6
- package/lib/default-providers/WebLLM/instructions.js +0 -32
- package/lib/default-providers/WebLLM/settings-schema.json +0 -19
- package/lib/default-providers/index.d.ts +0 -2
- package/lib/default-providers/index.js +0 -179
- package/lib/provider.d.ts +0 -144
- package/lib/provider.js +0 -412
- package/lib/settings/base.json +0 -7
- package/lib/settings/index.d.ts +0 -3
- package/lib/settings/index.js +0 -3
- package/lib/settings/panel.d.ts +0 -226
- package/lib/settings/panel.js +0 -510
- package/lib/settings/textarea.d.ts +0 -2
- package/lib/settings/textarea.js +0 -18
- package/lib/settings/utils.d.ts +0 -2
- package/lib/settings/utils.js +0 -4
- package/lib/types/ai-model.d.ts +0 -24
- package/lib/types/ai-model.js +0 -5
- package/schema/chat.json +0 -28
- package/schema/provider-registry.json +0 -29
- package/schema/system-prompts.json +0 -22
- package/src/base-completer.ts +0 -75
- package/src/chat-handler.ts +0 -262
- package/src/completion-provider.ts +0 -64
- package/src/default-prompts.ts +0 -33
- package/src/default-providers/Anthropic/completer.ts +0 -59
- package/src/default-providers/ChromeAI/completer.ts +0 -73
- package/src/default-providers/ChromeAI/instructions.ts +0 -45
- package/src/default-providers/Gemini/completer.ts +0 -61
- package/src/default-providers/Gemini/instructions.ts +0 -9
- package/src/default-providers/MistralAI/completer.ts +0 -69
- package/src/default-providers/MistralAI/instructions.ts +0 -18
- package/src/default-providers/Ollama/completer.ts +0 -54
- package/src/default-providers/Ollama/instructions.ts +0 -70
- package/src/default-providers/OpenAI/completer.ts +0 -54
- package/src/default-providers/WebLLM/completer.ts +0 -151
- package/src/default-providers/WebLLM/instructions.ts +0 -33
- package/src/default-providers/index.ts +0 -211
- package/src/global.d.ts +0 -9
- package/src/provider.ts +0 -514
- package/src/settings/index.ts +0 -3
- package/src/settings/panel.tsx +0 -773
- package/src/settings/textarea.tsx +0 -33
- package/src/settings/utils.ts +0 -5
- package/src/types/ai-model.ts +0 -37
- package/src/types/service-worker.d.ts +0 -6
package/lib/index.js
CHANGED
|
@@ -1,83 +1,145 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { IThemeManager } from '@jupyterlab/apputils';
|
|
1
|
+
import { ILabShell, ILayoutRestorer } from '@jupyterlab/application';
|
|
2
|
+
import { ActiveCellManager, AttachmentOpenerRegistry, ChatWidget, InputToolbarRegistry } from '@jupyter/chat';
|
|
3
|
+
import { ICommandPalette, IThemeManager } from '@jupyterlab/apputils';
|
|
4
4
|
import { ICompletionProviderManager } from '@jupyterlab/completer';
|
|
5
|
+
import { IDocumentManager } from '@jupyterlab/docmanager';
|
|
5
6
|
import { INotebookTracker } from '@jupyterlab/notebook';
|
|
6
7
|
import { IRenderMimeRegistry } from '@jupyterlab/rendermime';
|
|
8
|
+
import { IKernelSpecManager } from '@jupyterlab/services';
|
|
7
9
|
import { ISettingRegistry } from '@jupyterlab/settingregistry';
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
10
|
+
import { settingsIcon } from '@jupyterlab/ui-components';
|
|
11
|
+
import { AgentManager } from './agent';
|
|
12
|
+
import { AIChatModel } from './chat-model';
|
|
13
|
+
import { ChatProviderRegistry, CompletionProviderRegistry } from './providers/provider-registry';
|
|
14
|
+
import { IChatProviderRegistry, ICompletionProviderRegistry, IAISettingsModel, IToolRegistry } from './tokens';
|
|
15
|
+
import { registerBuiltInChatProviders, registerBuiltInCompletionProviders } from './providers/built-in-providers';
|
|
16
|
+
import { AICompletionProvider } from './completion';
|
|
17
|
+
import { clearItem } from './components/clear-button';
|
|
18
|
+
import { createModelSelectItem } from './components/model-select';
|
|
16
19
|
import { stopItem } from './components/stop-button';
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
+
import { createToolSelectItem } from './components/tool-select';
|
|
21
|
+
import { AISettingsModel } from './models/settings-model';
|
|
22
|
+
import { ToolRegistry } from './tools/tool-registry';
|
|
23
|
+
import { createAddCellTool, createDeleteCellTool, createExecuteActiveCellTool, createGetCellInfoTool, createGetNotebookInfoTool, createNotebookCreationTool, createRunCellTool, createSaveNotebookTool, createSetCellContentTool } from './tools/notebook';
|
|
24
|
+
import { createCopyFileTool, createDeleteFileTool, createNavigateToDirectoryTool, createNewFileTool, createOpenFileTool, createRenameFileTool } from './tools/file';
|
|
25
|
+
import { createDiscoverCommandsTool, createExecuteCommandTool } from './tools/commands';
|
|
26
|
+
import { AISettingsWidget } from './widgets/ai-settings';
|
|
27
|
+
import { ChatWrapperWidget } from './widgets/chat-wrapper';
|
|
28
|
+
/**
|
|
29
|
+
* Command IDs namespace
|
|
30
|
+
*/
|
|
31
|
+
var CommandIds;
|
|
32
|
+
(function (CommandIds) {
|
|
33
|
+
CommandIds.openSettings = '@jupyterlite/ai:open-settings';
|
|
34
|
+
CommandIds.reposition = '@jupyterlite/ai:reposition';
|
|
35
|
+
})(CommandIds || (CommandIds = {}));
|
|
36
|
+
/**
|
|
37
|
+
* Chat provider registry plugin
|
|
38
|
+
*/
|
|
39
|
+
const chatProviderRegistryPlugin = {
|
|
40
|
+
id: '@jupyterlite/ai:chat-provider-registry',
|
|
41
|
+
description: 'Chat AI provider registry',
|
|
20
42
|
autoStart: true,
|
|
21
|
-
provides:
|
|
43
|
+
provides: IChatProviderRegistry,
|
|
22
44
|
activate: () => {
|
|
23
|
-
|
|
24
|
-
registry.addProvider(new ChatHandler.ClearCommandProvider());
|
|
25
|
-
return registry;
|
|
45
|
+
return new ChatProviderRegistry();
|
|
26
46
|
}
|
|
27
47
|
};
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
48
|
+
/**
|
|
49
|
+
* Completion provider registry plugin
|
|
50
|
+
*/
|
|
51
|
+
const completionProviderRegistryPlugin = {
|
|
52
|
+
id: '@jupyterlite/ai:completion-provider-registry',
|
|
53
|
+
description: 'Completion provider registry',
|
|
31
54
|
autoStart: true,
|
|
32
|
-
|
|
55
|
+
provides: ICompletionProviderRegistry,
|
|
56
|
+
activate: () => {
|
|
57
|
+
return new CompletionProviderRegistry();
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
/**
|
|
61
|
+
* Built-in chat providers plugin
|
|
62
|
+
*/
|
|
63
|
+
const builtInChatProvidersPlugin = {
|
|
64
|
+
id: '@jupyterlite/ai:built-in-chat-providers',
|
|
65
|
+
description: 'Register built-in chat AI providers',
|
|
66
|
+
autoStart: true,
|
|
67
|
+
requires: [IChatProviderRegistry],
|
|
68
|
+
activate: (app, chatRegistry) => {
|
|
69
|
+
registerBuiltInChatProviders(chatRegistry);
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
/**
|
|
73
|
+
* Built-in completion providers plugin
|
|
74
|
+
*/
|
|
75
|
+
const builtInCompletionProvidersPlugin = {
|
|
76
|
+
id: '@jupyterlite/ai:built-in-completion-providers',
|
|
77
|
+
description: 'Register built-in completion providers',
|
|
78
|
+
autoStart: true,
|
|
79
|
+
requires: [ICompletionProviderRegistry],
|
|
80
|
+
activate: (app, completionRegistry) => {
|
|
81
|
+
registerBuiltInCompletionProviders(completionRegistry);
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
/**
|
|
85
|
+
* Initialization data for the extension.
|
|
86
|
+
*/
|
|
87
|
+
const plugin = {
|
|
88
|
+
id: '@jupyterlite/ai:plugin',
|
|
89
|
+
description: 'AI in JupyterLab',
|
|
90
|
+
autoStart: true,
|
|
91
|
+
requires: [
|
|
92
|
+
IAISettingsModel,
|
|
93
|
+
IToolRegistry,
|
|
94
|
+
IRenderMimeRegistry,
|
|
95
|
+
IDocumentManager,
|
|
96
|
+
IChatProviderRegistry
|
|
97
|
+
],
|
|
33
98
|
optional: [
|
|
34
|
-
INotebookTracker,
|
|
35
|
-
ISettingRegistry,
|
|
36
99
|
IThemeManager,
|
|
37
|
-
|
|
100
|
+
ICommandPalette,
|
|
101
|
+
INotebookTracker,
|
|
102
|
+
ILayoutRestorer,
|
|
103
|
+
ILabShell
|
|
38
104
|
],
|
|
39
|
-
activate:
|
|
40
|
-
|
|
105
|
+
activate: (app, settingsModel, toolRegistry, rmRegistry, docManager, chatProviderRegistry, themeManager, palette, notebookTracker, restorer, labShell) => {
|
|
106
|
+
// Create ActiveCellManager if notebook tracker is available
|
|
107
|
+
let activeCellManager;
|
|
41
108
|
if (notebookTracker) {
|
|
42
109
|
activeCellManager = new ActiveCellManager({
|
|
43
110
|
tracker: notebookTracker,
|
|
44
111
|
shell: app.shell
|
|
45
112
|
});
|
|
46
113
|
}
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
114
|
+
// Create Agent Manager first so it can be shared
|
|
115
|
+
const agentManager = new AgentManager({
|
|
116
|
+
settingsModel,
|
|
117
|
+
toolRegistry,
|
|
118
|
+
chatProviderRegistry: chatProviderRegistry
|
|
50
119
|
});
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
personaName = setting.get('personaName').composite;
|
|
59
|
-
// set the properties
|
|
60
|
-
chatHandler.config = { sendWithShiftEnter, enableCodeToolbar };
|
|
61
|
-
chatHandler.personaName = personaName;
|
|
62
|
-
}
|
|
63
|
-
Promise.all([app.restored, settingsRegistry?.load(chatPlugin.id)])
|
|
64
|
-
.then(([, settings]) => {
|
|
65
|
-
if (!settings) {
|
|
66
|
-
console.warn('The SettingsRegistry is not loaded for the chat extension');
|
|
67
|
-
return;
|
|
68
|
-
}
|
|
69
|
-
loadSetting(settings);
|
|
70
|
-
settings.changed.connect(loadSetting);
|
|
71
|
-
})
|
|
72
|
-
.catch(reason => {
|
|
73
|
-
console.error(`Something went wrong when reading the settings.\n${reason}`);
|
|
120
|
+
// Create AI chat model
|
|
121
|
+
const chatModel = new AIChatModel({
|
|
122
|
+
user: { username: 'user', display_name: 'User' },
|
|
123
|
+
settingsModel,
|
|
124
|
+
agentManager,
|
|
125
|
+
activeCellManager,
|
|
126
|
+
documentManager: docManager
|
|
74
127
|
});
|
|
75
|
-
|
|
128
|
+
// Create input toolbar registry with all buttons
|
|
76
129
|
const inputToolbarRegistry = InputToolbarRegistry.defaultToolbarRegistry();
|
|
77
|
-
const stopButton = stopItem(
|
|
130
|
+
const stopButton = stopItem();
|
|
131
|
+
const clearButton = clearItem();
|
|
132
|
+
const toolSelectButton = createToolSelectItem(toolRegistry, settingsModel.config.toolsEnabled);
|
|
133
|
+
const modelSelectButton = createModelSelectItem(settingsModel);
|
|
78
134
|
inputToolbarRegistry.addItem('stop', stopButton);
|
|
79
|
-
|
|
80
|
-
|
|
135
|
+
inputToolbarRegistry.addItem('clear', clearButton);
|
|
136
|
+
inputToolbarRegistry.addItem('model', modelSelectButton);
|
|
137
|
+
inputToolbarRegistry.addItem('tools', toolSelectButton);
|
|
138
|
+
// Listen to writers changes to show/hide stop button
|
|
139
|
+
chatModel.writersChanged.connect((_, writers) => {
|
|
140
|
+
// Check if AI is currently writing (streaming)
|
|
141
|
+
const aiWriting = writers.some(writer => writer.user.username === 'ai-assistant');
|
|
142
|
+
if (aiWriting) {
|
|
81
143
|
inputToolbarRegistry.hide('send');
|
|
82
144
|
inputToolbarRegistry.show('stop');
|
|
83
145
|
}
|
|
@@ -86,131 +148,224 @@ const chatPlugin = {
|
|
|
86
148
|
inputToolbarRegistry.show('send');
|
|
87
149
|
}
|
|
88
150
|
});
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
151
|
+
// Listen for settings changes to update tool availability
|
|
152
|
+
settingsModel.stateChanged.connect(() => {
|
|
153
|
+
const config = settingsModel.config;
|
|
154
|
+
if (!config.toolsEnabled) {
|
|
155
|
+
inputToolbarRegistry.hide('tools');
|
|
156
|
+
}
|
|
157
|
+
else {
|
|
158
|
+
inputToolbarRegistry.show('tools');
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
// Create attachment opener registry to handle file attachments
|
|
162
|
+
const attachmentOpenerRegistry = new AttachmentOpenerRegistry();
|
|
163
|
+
attachmentOpenerRegistry.set('file', attachment => {
|
|
164
|
+
app.commands.execute('docmanager:open', { path: attachment.value });
|
|
165
|
+
});
|
|
166
|
+
attachmentOpenerRegistry.set('notebook', attachment => {
|
|
167
|
+
app.commands.execute('docmanager:open', { path: attachment.value });
|
|
168
|
+
});
|
|
169
|
+
// Create chat panel with drag/drop functionality
|
|
170
|
+
const chatPanel = new ChatWidget({
|
|
171
|
+
model: chatModel,
|
|
172
|
+
rmRegistry,
|
|
173
|
+
themeManager,
|
|
174
|
+
inputToolbarRegistry,
|
|
175
|
+
attachmentOpenerRegistry
|
|
176
|
+
});
|
|
177
|
+
// Create wrapper widget with a toolbar
|
|
178
|
+
const chatWrapper = new ChatWrapperWidget({
|
|
179
|
+
chatPanel,
|
|
180
|
+
commands: app.commands,
|
|
181
|
+
chatModel,
|
|
182
|
+
settingsModel
|
|
183
|
+
});
|
|
184
|
+
app.shell.add(chatWrapper, 'left', { rank: 1000 });
|
|
185
|
+
const settingsWidget = new AISettingsWidget({
|
|
186
|
+
settingsModel,
|
|
187
|
+
agentManager,
|
|
188
|
+
themeManager,
|
|
189
|
+
chatProviderRegistry
|
|
190
|
+
});
|
|
191
|
+
settingsWidget.id = 'jupyterlite-ai-settings';
|
|
192
|
+
settingsWidget.title.icon = settingsIcon;
|
|
105
193
|
if (restorer) {
|
|
106
|
-
restorer.add(
|
|
194
|
+
restorer.add(chatWrapper, chatWrapper.id);
|
|
195
|
+
restorer.add(settingsWidget, settingsWidget.id);
|
|
107
196
|
}
|
|
197
|
+
registerCommands(app, palette, settingsWidget, labShell);
|
|
108
198
|
}
|
|
109
199
|
};
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
optional: [IRenderMimeRegistry, ISecretsManager],
|
|
127
|
-
provides: IAIProviderRegistry,
|
|
128
|
-
activate: (app, editorRegistry, settingRegistry, rmRegistry, secretsManager) => {
|
|
129
|
-
const providerRegistry = new AIProviderRegistry({
|
|
130
|
-
token,
|
|
131
|
-
secretsManager
|
|
132
|
-
});
|
|
133
|
-
editorRegistry.addRenderer(`${PLUGIN_IDS.providerRegistry}.AIproviders`, aiSettingsRenderer({
|
|
134
|
-
providerRegistry,
|
|
135
|
-
secretsToken: token,
|
|
136
|
-
rmRegistry,
|
|
137
|
-
secretsManager
|
|
138
|
-
}));
|
|
139
|
-
settingRegistry
|
|
140
|
-
.load(providerRegistryPlugin.id)
|
|
141
|
-
.then(settings => {
|
|
142
|
-
if (!secretsManager) {
|
|
143
|
-
delete settings.schema.properties?.['UseSecretsManager'];
|
|
200
|
+
function registerCommands(app, palette, settingsWidget, labShell) {
|
|
201
|
+
const { commands } = app;
|
|
202
|
+
commands.addCommand(CommandIds.openSettings, {
|
|
203
|
+
label: 'AI Settings',
|
|
204
|
+
caption: 'Configure AI providers and behavior',
|
|
205
|
+
icon: settingsIcon,
|
|
206
|
+
execute: () => {
|
|
207
|
+
// Check if the widget already exists in shell
|
|
208
|
+
let widget = Array.from(app.shell.widgets('main')).find(w => w.id === 'jupyterlite-ai-settings');
|
|
209
|
+
if (!widget && settingsWidget) {
|
|
210
|
+
// Use the pre-created widget
|
|
211
|
+
widget = settingsWidget;
|
|
212
|
+
app.shell.add(widget, 'main');
|
|
213
|
+
}
|
|
214
|
+
if (widget) {
|
|
215
|
+
app.shell.activateById(widget.id);
|
|
144
216
|
}
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
217
|
+
},
|
|
218
|
+
describedBy: {
|
|
219
|
+
args: {}
|
|
220
|
+
}
|
|
221
|
+
});
|
|
222
|
+
if (labShell) {
|
|
223
|
+
commands.addCommand(CommandIds.reposition, {
|
|
224
|
+
label: 'Reposition Widget',
|
|
225
|
+
execute: (args) => {
|
|
226
|
+
const { widgetId, area, mode } = args;
|
|
227
|
+
const widget = widgetId
|
|
228
|
+
? Array.from(labShell.widgets('main')).find(w => w.id === widgetId) ||
|
|
229
|
+
labShell.currentWidget
|
|
230
|
+
: labShell.currentWidget;
|
|
231
|
+
if (!widget) {
|
|
232
|
+
return;
|
|
152
233
|
}
|
|
153
|
-
|
|
154
|
-
|
|
234
|
+
if (area && area !== 'main') {
|
|
235
|
+
// Move to different area
|
|
236
|
+
labShell.move(widget, area);
|
|
237
|
+
labShell.activateById(widget.id);
|
|
155
238
|
}
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
239
|
+
else if (mode) {
|
|
240
|
+
// Reposition within main area using split mode
|
|
241
|
+
labShell.add(widget, 'main', { mode, activate: true });
|
|
159
242
|
}
|
|
160
|
-
|
|
161
|
-
|
|
243
|
+
},
|
|
244
|
+
describedBy: {
|
|
245
|
+
args: {
|
|
246
|
+
type: 'object',
|
|
247
|
+
properties: {
|
|
248
|
+
widgetId: {
|
|
249
|
+
type: 'string',
|
|
250
|
+
description: 'The widget ID to reposition in the application shell'
|
|
251
|
+
},
|
|
252
|
+
area: {
|
|
253
|
+
type: 'string',
|
|
254
|
+
description: 'The name of the area to reposition the widget to'
|
|
255
|
+
},
|
|
256
|
+
mode: {
|
|
257
|
+
type: 'string',
|
|
258
|
+
enum: ['split-left', 'split-right', 'split-top', 'split-bottom'],
|
|
259
|
+
description: 'The mode to use when repositioning the widget'
|
|
260
|
+
}
|
|
261
|
+
}
|
|
162
262
|
}
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
263
|
+
}
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
// Add to command palette if available
|
|
267
|
+
if (palette) {
|
|
268
|
+
palette.addItem({
|
|
269
|
+
command: CommandIds.openSettings,
|
|
270
|
+
category: 'AI Assistant'
|
|
169
271
|
});
|
|
170
|
-
return providerRegistry;
|
|
171
272
|
}
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* A plugin to provide AI-powered code completion.
|
|
276
|
+
*/
|
|
277
|
+
const completionPlugin = {
|
|
278
|
+
id: '@jupyterlite/ai:completion',
|
|
279
|
+
description: 'AI-powered code completion',
|
|
175
280
|
autoStart: true,
|
|
176
|
-
requires: [
|
|
177
|
-
optional: [
|
|
178
|
-
activate: (app,
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
/**
|
|
183
|
-
* Update the prompts in the provider registry.
|
|
184
|
-
*/
|
|
185
|
-
function loadSetting(setting) {
|
|
186
|
-
providerRegistry.chatSystemPrompt = setting.get('chatSystemPrompt')
|
|
187
|
-
.composite;
|
|
188
|
-
providerRegistry.completerSystemPrompt = setting.get('completionSystemPrompt').composite;
|
|
281
|
+
requires: [IAISettingsModel, ICompletionProviderRegistry],
|
|
282
|
+
optional: [ICompletionProviderManager],
|
|
283
|
+
activate: (app, settingsModel, completionProviderRegistry, manager) => {
|
|
284
|
+
if (!manager) {
|
|
285
|
+
console.info('Completion provider manager not available, skipping AI completion setup');
|
|
286
|
+
return;
|
|
189
287
|
}
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
])
|
|
194
|
-
.then(([, settings]) => {
|
|
195
|
-
if (!settings) {
|
|
196
|
-
console.warn('The SettingsRegistry is not loaded for the chat extension');
|
|
197
|
-
return;
|
|
198
|
-
}
|
|
199
|
-
loadSetting(settings);
|
|
200
|
-
settings.changed.connect(loadSetting);
|
|
201
|
-
})
|
|
202
|
-
.catch(reason => {
|
|
203
|
-
console.error(`Something went wrong when reading the settings.\n${reason}`);
|
|
288
|
+
const completionProvider = new AICompletionProvider({
|
|
289
|
+
settingsModel,
|
|
290
|
+
completionProviderRegistry: completionProviderRegistry
|
|
204
291
|
});
|
|
292
|
+
manager.registerInlineProvider(completionProvider);
|
|
293
|
+
}
|
|
294
|
+
};
|
|
295
|
+
/**
|
|
296
|
+
* A plugin to provide the settings model.
|
|
297
|
+
*/
|
|
298
|
+
const settingsModel = {
|
|
299
|
+
id: '@jupyterlite/ai:settings-model',
|
|
300
|
+
description: 'Provide the AI settings model',
|
|
301
|
+
autoStart: true,
|
|
302
|
+
provides: IAISettingsModel,
|
|
303
|
+
requires: [ISettingRegistry],
|
|
304
|
+
activate: (app, settingRegistry) => {
|
|
305
|
+
return new AISettingsModel({ settingRegistry });
|
|
306
|
+
}
|
|
307
|
+
};
|
|
308
|
+
/**
|
|
309
|
+
* A plugin to provide the tool registry.
|
|
310
|
+
*/
|
|
311
|
+
const toolRegistry = {
|
|
312
|
+
id: '@jupyterlite/ai:tool-registry',
|
|
313
|
+
description: 'Provide the AI tool registry',
|
|
314
|
+
autoStart: true,
|
|
315
|
+
requires: [IAISettingsModel, IDocumentManager, IKernelSpecManager],
|
|
316
|
+
optional: [INotebookTracker],
|
|
317
|
+
provides: IToolRegistry,
|
|
318
|
+
activate: (app, settingsModel, docManager, kernelSpecManager, notebookTracker) => {
|
|
319
|
+
const toolRegistry = new ToolRegistry();
|
|
320
|
+
const notebookCreationTool = createNotebookCreationTool(docManager, kernelSpecManager);
|
|
321
|
+
toolRegistry.add('create_notebook', notebookCreationTool);
|
|
322
|
+
// Add high-level notebook operation tools
|
|
323
|
+
const addCellTool = createAddCellTool(docManager, notebookTracker);
|
|
324
|
+
const getNotebookInfoTool = createGetNotebookInfoTool(docManager, notebookTracker);
|
|
325
|
+
const getCellInfoTool = createGetCellInfoTool(docManager, notebookTracker);
|
|
326
|
+
const setCellContentTool = createSetCellContentTool(docManager, notebookTracker);
|
|
327
|
+
const runCellTool = createRunCellTool(docManager, notebookTracker);
|
|
328
|
+
const deleteCellTool = createDeleteCellTool(docManager, notebookTracker);
|
|
329
|
+
const saveNotebookTool = createSaveNotebookTool(docManager, notebookTracker);
|
|
330
|
+
const executeActiveCellTool = createExecuteActiveCellTool(docManager, notebookTracker);
|
|
331
|
+
toolRegistry.add('add_cell', addCellTool);
|
|
332
|
+
toolRegistry.add('get_notebook_info', getNotebookInfoTool);
|
|
333
|
+
toolRegistry.add('get_cell_info', getCellInfoTool);
|
|
334
|
+
toolRegistry.add('set_cell_content', setCellContentTool);
|
|
335
|
+
toolRegistry.add('run_cell', runCellTool);
|
|
336
|
+
toolRegistry.add('delete_cell', deleteCellTool);
|
|
337
|
+
toolRegistry.add('save_notebook', saveNotebookTool);
|
|
338
|
+
toolRegistry.add('execute_active_cell', executeActiveCellTool);
|
|
339
|
+
// Add file operation tools
|
|
340
|
+
const newFileTool = createNewFileTool(docManager);
|
|
341
|
+
const openFileTool = createOpenFileTool(docManager);
|
|
342
|
+
const deleteFileTool = createDeleteFileTool(docManager);
|
|
343
|
+
const renameFileTool = createRenameFileTool(docManager);
|
|
344
|
+
const copyFileTool = createCopyFileTool(docManager);
|
|
345
|
+
const navigateToDirectoryTool = createNavigateToDirectoryTool(app.commands);
|
|
346
|
+
toolRegistry.add('create_file', newFileTool);
|
|
347
|
+
toolRegistry.add('open_file', openFileTool);
|
|
348
|
+
toolRegistry.add('delete_file', deleteFileTool);
|
|
349
|
+
toolRegistry.add('rename_file', renameFileTool);
|
|
350
|
+
toolRegistry.add('copy_file', copyFileTool);
|
|
351
|
+
toolRegistry.add('navigate_to_directory', navigateToDirectoryTool);
|
|
352
|
+
// Add command operation tools
|
|
353
|
+
const discoverCommandsTool = createDiscoverCommandsTool(app.commands);
|
|
354
|
+
const executeCommandTool = createExecuteCommandTool(app.commands, settingsModel);
|
|
355
|
+
toolRegistry.add('discover_commands', discoverCommandsTool);
|
|
356
|
+
toolRegistry.add('execute_command', executeCommandTool);
|
|
357
|
+
return toolRegistry;
|
|
205
358
|
}
|
|
206
359
|
};
|
|
207
360
|
export default [
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
361
|
+
chatProviderRegistryPlugin,
|
|
362
|
+
completionProviderRegistryPlugin,
|
|
363
|
+
builtInChatProvidersPlugin,
|
|
364
|
+
builtInCompletionProvidersPlugin,
|
|
365
|
+
plugin,
|
|
366
|
+
completionPlugin,
|
|
367
|
+
settingsModel,
|
|
368
|
+
toolRegistry
|
|
214
369
|
];
|
|
215
|
-
|
|
216
|
-
export * from './
|
|
370
|
+
// Export extension points for other extensions to use
|
|
371
|
+
export * from './tokens';
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Browser-compatible MCP Server implementation
|
|
3
|
+
*
|
|
4
|
+
* This is a custom implementation that works around the limitation in
|
|
5
|
+
* @openai/agents where MCPServerStreamableHttp doesn't work in browsers
|
|
6
|
+
*/
|
|
7
|
+
interface MCPServer {
|
|
8
|
+
cacheToolsList: boolean;
|
|
9
|
+
toolFilter?: any;
|
|
10
|
+
connect(): Promise<void>;
|
|
11
|
+
readonly name: string;
|
|
12
|
+
close(): Promise<void>;
|
|
13
|
+
listTools(): Promise<MCPTool[]>;
|
|
14
|
+
callTool(toolName: string, args: Record<string, unknown> | null): Promise<CallToolResultContent>;
|
|
15
|
+
invalidateToolsCache(): Promise<void>;
|
|
16
|
+
}
|
|
17
|
+
interface MCPTool {
|
|
18
|
+
name: string;
|
|
19
|
+
description?: string;
|
|
20
|
+
inputSchema: {
|
|
21
|
+
type: 'object';
|
|
22
|
+
properties: Record<string, any>;
|
|
23
|
+
required: string[];
|
|
24
|
+
additionalProperties: boolean;
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
type CallToolResultContent = Array<{
|
|
28
|
+
type: string;
|
|
29
|
+
text: string;
|
|
30
|
+
}>;
|
|
31
|
+
interface MCPServerStreamableHttpOptions {
|
|
32
|
+
url: string;
|
|
33
|
+
cacheToolsList?: boolean;
|
|
34
|
+
clientSessionTimeoutSeconds?: number;
|
|
35
|
+
name?: string;
|
|
36
|
+
logger?: any;
|
|
37
|
+
toolFilter?: any;
|
|
38
|
+
timeout?: number;
|
|
39
|
+
authProvider?: any;
|
|
40
|
+
requestInit?: any;
|
|
41
|
+
fetch?: any;
|
|
42
|
+
reconnectionOptions?: any;
|
|
43
|
+
sessionId?: string;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Browser-compatible MCP Server implementation that works around limitations
|
|
47
|
+
* in @openai/agents where MCPServerStreamableHttp doesn't work in browsers.
|
|
48
|
+
*
|
|
49
|
+
* This class provides a streamable HTTP client transport for MCP (Model Context Protocol)
|
|
50
|
+
* servers that can be used in browser environments.
|
|
51
|
+
*/
|
|
52
|
+
export declare class BrowserMCPServerStreamableHttp implements MCPServer {
|
|
53
|
+
readonly name: string;
|
|
54
|
+
readonly cacheToolsList: boolean;
|
|
55
|
+
readonly toolFilter: any;
|
|
56
|
+
constructor(options: MCPServerStreamableHttpOptions);
|
|
57
|
+
connect(): Promise<void>;
|
|
58
|
+
close(): Promise<void>;
|
|
59
|
+
listTools(): Promise<MCPTool[]>;
|
|
60
|
+
callTool(toolName: string, args: Record<string, unknown> | null): Promise<CallToolResultContent>;
|
|
61
|
+
invalidateToolsCache(): Promise<void>;
|
|
62
|
+
private _session;
|
|
63
|
+
private _toolsList;
|
|
64
|
+
private _cacheDirty;
|
|
65
|
+
private _transport;
|
|
66
|
+
private _options;
|
|
67
|
+
}
|
|
68
|
+
export {};
|