@jupyterlite/ai 0.8.1 → 0.9.0-a1
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 +243 -0
- package/lib/agent.js +627 -0
- package/lib/chat-model.d.ts +195 -0
- package/lib/chat-model.js +591 -0
- package/lib/completion/completion-provider.d.ts +93 -0
- package/lib/completion/completion-provider.js +235 -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 +5 -5
- package/lib/index.js +341 -169
- package/lib/mcp/browser.d.ts +68 -0
- package/lib/mcp/browser.js +132 -0
- package/lib/models/settings-model.d.ts +70 -0
- package/lib/models/settings-model.js +296 -0
- package/lib/providers/built-in-providers.d.ts +9 -0
- package/lib/providers/built-in-providers.js +266 -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 +167 -86
- package/lib/tokens.js +25 -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 +41 -0
- package/lib/tools/notebook.js +779 -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 +49 -0
- package/lib/widgets/ai-settings.js +580 -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 +14 -0
- package/lib/widgets/provider-config-dialog.js +112 -0
- package/package.json +151 -40
- package/schema/settings-model.json +159 -0
- package/src/agent.ts +836 -0
- package/src/chat-model.ts +771 -0
- package/src/completion/completion-provider.ts +346 -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 +485 -232
- package/src/mcp/browser.ts +213 -0
- package/src/models/settings-model.ts +413 -0
- package/src/providers/built-in-providers.ts +294 -0
- package/src/providers/models.ts +79 -0
- package/src/providers/provider-registry.ts +189 -0
- package/src/tokens.ts +217 -90
- package/src/tools/commands.ts +151 -0
- package/src/tools/file.ts +307 -0
- package/src/tools/notebook.ts +987 -0
- package/src/tools/tool-registry.ts +63 -0
- package/src/types.d.ts +4 -0
- package/src/widgets/ai-settings.tsx +1233 -0
- package/src/widgets/chat-wrapper.tsx +543 -0
- package/src/widgets/provider-config-dialog.tsx +272 -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,134 @@
|
|
|
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 {
|
|
10
|
+
import { settingsIcon } from '@jupyterlab/ui-components';
|
|
9
11
|
import { ISecretsManager, SecretsManager } from 'jupyter-secrets-manager';
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
12
|
+
import { AgentManager } from './agent';
|
|
13
|
+
import { AIChatModel } from './chat-model';
|
|
14
|
+
import { ChatProviderRegistry, CompletionProviderRegistry } from './providers/provider-registry';
|
|
15
|
+
import { IAgentManager, IChatProviderRegistry, ICompletionProviderRegistry, IToolRegistry, SECRETS_NAMESPACE, IAISettingsModel } from './tokens';
|
|
16
|
+
import { registerBuiltInChatProviders, registerBuiltInCompletionProviders } from './providers/built-in-providers';
|
|
17
|
+
import { AICompletionProvider } from './completion';
|
|
18
|
+
import { clearItem } from './components/clear-button';
|
|
19
|
+
import { createModelSelectItem } from './components/model-select';
|
|
16
20
|
import { stopItem } from './components/stop-button';
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
21
|
+
import { createToolSelectItem } from './components/tool-select';
|
|
22
|
+
import { AISettingsModel } from './models/settings-model';
|
|
23
|
+
import { ToolRegistry } from './tools/tool-registry';
|
|
24
|
+
import { createAddCellTool, createDeleteCellTool, createExecuteActiveCellTool, createGetCellInfoTool, createGetNotebookInfoTool, createNotebookCreationTool, createRunCellTool, createSaveNotebookTool, createSetCellContentTool } from './tools/notebook';
|
|
25
|
+
import { createCopyFileTool, createDeleteFileTool, createNavigateToDirectoryTool, createNewFileTool, createOpenFileTool, createRenameFileTool } from './tools/file';
|
|
26
|
+
import { createDiscoverCommandsTool, createExecuteCommandTool } from './tools/commands';
|
|
27
|
+
import { AISettingsWidget } from './widgets/ai-settings';
|
|
28
|
+
import { ChatWrapperWidget } from './widgets/chat-wrapper';
|
|
29
|
+
/**
|
|
30
|
+
* Command IDs namespace
|
|
31
|
+
*/
|
|
32
|
+
var CommandIds;
|
|
33
|
+
(function (CommandIds) {
|
|
34
|
+
CommandIds.openSettings = '@jupyterlite/ai:open-settings';
|
|
35
|
+
CommandIds.reposition = '@jupyterlite/ai:reposition';
|
|
36
|
+
})(CommandIds || (CommandIds = {}));
|
|
37
|
+
/**
|
|
38
|
+
* Chat provider registry plugin
|
|
39
|
+
*/
|
|
40
|
+
const chatProviderRegistryPlugin = {
|
|
41
|
+
id: '@jupyterlite/ai:chat-provider-registry',
|
|
42
|
+
description: 'Chat AI provider registry',
|
|
20
43
|
autoStart: true,
|
|
21
|
-
provides:
|
|
44
|
+
provides: IChatProviderRegistry,
|
|
22
45
|
activate: () => {
|
|
23
|
-
|
|
24
|
-
registry.addProvider(new ChatHandler.ClearCommandProvider());
|
|
25
|
-
return registry;
|
|
46
|
+
return new ChatProviderRegistry();
|
|
26
47
|
}
|
|
27
48
|
};
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
49
|
+
/**
|
|
50
|
+
* Completion provider registry plugin
|
|
51
|
+
*/
|
|
52
|
+
const completionProviderRegistryPlugin = {
|
|
53
|
+
id: '@jupyterlite/ai:completion-provider-registry',
|
|
54
|
+
description: 'Completion provider registry',
|
|
31
55
|
autoStart: true,
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
56
|
+
provides: ICompletionProviderRegistry,
|
|
57
|
+
activate: () => {
|
|
58
|
+
return new CompletionProviderRegistry();
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
/**
|
|
62
|
+
* Built-in chat providers plugin
|
|
63
|
+
*/
|
|
64
|
+
const builtInChatProvidersPlugin = {
|
|
65
|
+
id: '@jupyterlite/ai:built-in-chat-providers',
|
|
66
|
+
description: 'Register built-in chat AI providers',
|
|
67
|
+
autoStart: true,
|
|
68
|
+
requires: [IChatProviderRegistry],
|
|
69
|
+
activate: (app, chatRegistry) => {
|
|
70
|
+
registerBuiltInChatProviders(chatRegistry);
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
/**
|
|
74
|
+
* Built-in completion providers plugin
|
|
75
|
+
*/
|
|
76
|
+
const builtInCompletionProvidersPlugin = {
|
|
77
|
+
id: '@jupyterlite/ai:built-in-completion-providers',
|
|
78
|
+
description: 'Register built-in completion providers',
|
|
79
|
+
autoStart: true,
|
|
80
|
+
requires: [ICompletionProviderRegistry],
|
|
81
|
+
activate: (app, completionRegistry) => {
|
|
82
|
+
registerBuiltInCompletionProviders(completionRegistry);
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
/**
|
|
86
|
+
* Initialization data for the extension.
|
|
87
|
+
*/
|
|
88
|
+
const plugin = {
|
|
89
|
+
id: '@jupyterlite/ai:plugin',
|
|
90
|
+
description: 'AI in JupyterLab',
|
|
91
|
+
autoStart: true,
|
|
92
|
+
requires: [
|
|
93
|
+
IAISettingsModel,
|
|
94
|
+
IAgentManager,
|
|
95
|
+
IToolRegistry,
|
|
96
|
+
IRenderMimeRegistry,
|
|
97
|
+
IDocumentManager
|
|
38
98
|
],
|
|
39
|
-
|
|
40
|
-
|
|
99
|
+
optional: [IThemeManager, INotebookTracker, ILayoutRestorer, ILabShell],
|
|
100
|
+
activate: (app, settingsModel, agentManager, toolRegistry, rmRegistry, docManager, themeManager, notebookTracker, restorer, labShell) => {
|
|
101
|
+
// Create ActiveCellManager if notebook tracker is available
|
|
102
|
+
let activeCellManager;
|
|
41
103
|
if (notebookTracker) {
|
|
42
104
|
activeCellManager = new ActiveCellManager({
|
|
43
105
|
tracker: notebookTracker,
|
|
44
106
|
shell: app.shell
|
|
45
107
|
});
|
|
46
108
|
}
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
function loadSetting(setting) {
|
|
55
|
-
sendWithShiftEnter = setting.get('sendWithShiftEnter')
|
|
56
|
-
.composite;
|
|
57
|
-
enableCodeToolbar = setting.get('enableCodeToolbar').composite;
|
|
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}`);
|
|
109
|
+
// Create AI chat model
|
|
110
|
+
const chatModel = new AIChatModel({
|
|
111
|
+
user: { username: 'user', display_name: 'User' },
|
|
112
|
+
settingsModel,
|
|
113
|
+
agentManager,
|
|
114
|
+
activeCellManager,
|
|
115
|
+
documentManager: docManager
|
|
74
116
|
});
|
|
75
|
-
|
|
117
|
+
// Create input toolbar registry with all buttons
|
|
76
118
|
const inputToolbarRegistry = InputToolbarRegistry.defaultToolbarRegistry();
|
|
77
|
-
const stopButton = stopItem(
|
|
119
|
+
const stopButton = stopItem();
|
|
120
|
+
const clearButton = clearItem();
|
|
121
|
+
const toolSelectButton = createToolSelectItem(toolRegistry, settingsModel.config.toolsEnabled);
|
|
122
|
+
const modelSelectButton = createModelSelectItem(settingsModel);
|
|
78
123
|
inputToolbarRegistry.addItem('stop', stopButton);
|
|
79
|
-
|
|
80
|
-
|
|
124
|
+
inputToolbarRegistry.addItem('clear', clearButton);
|
|
125
|
+
inputToolbarRegistry.addItem('model', modelSelectButton);
|
|
126
|
+
inputToolbarRegistry.addItem('tools', toolSelectButton);
|
|
127
|
+
// Listen to writers changes to show/hide stop button
|
|
128
|
+
chatModel.writersChanged.connect((_, writers) => {
|
|
129
|
+
// Check if AI is currently writing (streaming)
|
|
130
|
+
const aiWriting = writers.some(writer => writer.user.username === 'ai-assistant');
|
|
131
|
+
if (aiWriting) {
|
|
81
132
|
inputToolbarRegistry.hide('send');
|
|
82
133
|
inputToolbarRegistry.show('stop');
|
|
83
134
|
}
|
|
@@ -86,131 +137,252 @@ const chatPlugin = {
|
|
|
86
137
|
inputToolbarRegistry.show('send');
|
|
87
138
|
}
|
|
88
139
|
});
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
140
|
+
// Listen for settings changes to update tool availability
|
|
141
|
+
settingsModel.stateChanged.connect(() => {
|
|
142
|
+
const config = settingsModel.config;
|
|
143
|
+
if (!config.toolsEnabled) {
|
|
144
|
+
inputToolbarRegistry.hide('tools');
|
|
145
|
+
}
|
|
146
|
+
else {
|
|
147
|
+
inputToolbarRegistry.show('tools');
|
|
148
|
+
}
|
|
149
|
+
});
|
|
150
|
+
// Create attachment opener registry to handle file attachments
|
|
151
|
+
const attachmentOpenerRegistry = new AttachmentOpenerRegistry();
|
|
152
|
+
attachmentOpenerRegistry.set('file', attachment => {
|
|
153
|
+
app.commands.execute('docmanager:open', { path: attachment.value });
|
|
154
|
+
});
|
|
155
|
+
attachmentOpenerRegistry.set('notebook', attachment => {
|
|
156
|
+
app.commands.execute('docmanager:open', { path: attachment.value });
|
|
157
|
+
});
|
|
158
|
+
// Create chat panel with drag/drop functionality
|
|
159
|
+
const chatPanel = new ChatWidget({
|
|
160
|
+
model: chatModel,
|
|
161
|
+
rmRegistry,
|
|
162
|
+
themeManager,
|
|
163
|
+
inputToolbarRegistry,
|
|
164
|
+
attachmentOpenerRegistry
|
|
165
|
+
});
|
|
166
|
+
// Create wrapper widget with a toolbar
|
|
167
|
+
const chatWrapper = new ChatWrapperWidget({
|
|
168
|
+
chatPanel,
|
|
169
|
+
commands: app.commands,
|
|
170
|
+
chatModel,
|
|
171
|
+
settingsModel
|
|
172
|
+
});
|
|
173
|
+
app.shell.add(chatWrapper, 'left', { rank: 1000 });
|
|
105
174
|
if (restorer) {
|
|
106
|
-
restorer.add(
|
|
175
|
+
restorer.add(chatWrapper, chatWrapper.id);
|
|
107
176
|
}
|
|
177
|
+
registerCommands(app, labShell);
|
|
108
178
|
}
|
|
109
179
|
};
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
id: PLUGIN_IDS.providerRegistry,
|
|
124
|
-
autoStart: true,
|
|
125
|
-
requires: [IFormRendererRegistry, ISettingRegistry],
|
|
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'];
|
|
144
|
-
}
|
|
145
|
-
const updateProvider = () => {
|
|
146
|
-
// Get the Ai provider settings.
|
|
147
|
-
const providerSettings = settings.get('AIproviders')
|
|
148
|
-
.composite;
|
|
149
|
-
// Update completer provider.
|
|
150
|
-
if (Object.keys(providerSettings).includes('completer')) {
|
|
151
|
-
providerRegistry.setCompleterProvider(providerSettings['completer']);
|
|
180
|
+
function registerCommands(app, labShell) {
|
|
181
|
+
const { commands } = app;
|
|
182
|
+
if (labShell) {
|
|
183
|
+
commands.addCommand(CommandIds.reposition, {
|
|
184
|
+
label: 'Reposition Widget',
|
|
185
|
+
execute: (args) => {
|
|
186
|
+
const { widgetId, area, mode } = args;
|
|
187
|
+
const widget = widgetId
|
|
188
|
+
? Array.from(labShell.widgets('main')).find(w => w.id === widgetId) ||
|
|
189
|
+
labShell.currentWidget
|
|
190
|
+
: labShell.currentWidget;
|
|
191
|
+
if (!widget) {
|
|
192
|
+
return;
|
|
152
193
|
}
|
|
153
|
-
|
|
154
|
-
|
|
194
|
+
if (area && area !== 'main') {
|
|
195
|
+
// Move to different area
|
|
196
|
+
labShell.move(widget, area);
|
|
197
|
+
labShell.activateById(widget.id);
|
|
155
198
|
}
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
199
|
+
else if (mode) {
|
|
200
|
+
// Reposition within main area using split mode
|
|
201
|
+
labShell.add(widget, 'main', { mode, activate: true });
|
|
159
202
|
}
|
|
160
|
-
|
|
161
|
-
|
|
203
|
+
},
|
|
204
|
+
describedBy: {
|
|
205
|
+
args: {
|
|
206
|
+
type: 'object',
|
|
207
|
+
properties: {
|
|
208
|
+
widgetId: {
|
|
209
|
+
type: 'string',
|
|
210
|
+
description: 'The widget ID to reposition in the application shell'
|
|
211
|
+
},
|
|
212
|
+
area: {
|
|
213
|
+
type: 'string',
|
|
214
|
+
description: 'The name of the area to reposition the widget to'
|
|
215
|
+
},
|
|
216
|
+
mode: {
|
|
217
|
+
type: 'string',
|
|
218
|
+
enum: ['split-left', 'split-right', 'split-top', 'split-bottom'],
|
|
219
|
+
description: 'The mode to use when repositioning the widget'
|
|
220
|
+
}
|
|
221
|
+
}
|
|
162
222
|
}
|
|
163
|
-
}
|
|
164
|
-
settings.changed.connect(() => updateProvider());
|
|
165
|
-
updateProvider();
|
|
166
|
-
})
|
|
167
|
-
.catch(reason => {
|
|
168
|
-
console.error(`Failed to load settings for ${providerRegistryPlugin.id}`, reason);
|
|
223
|
+
}
|
|
169
224
|
});
|
|
170
|
-
return providerRegistry;
|
|
171
225
|
}
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* A plugin to provide the settings model.
|
|
229
|
+
*/
|
|
230
|
+
const agentManager = SecretsManager.sign(SECRETS_NAMESPACE, token => ({
|
|
231
|
+
id: SECRETS_NAMESPACE,
|
|
232
|
+
description: 'Provide the AI agent manager',
|
|
175
233
|
autoStart: true,
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
234
|
+
provides: IAgentManager,
|
|
235
|
+
requires: [IAISettingsModel, IChatProviderRegistry],
|
|
236
|
+
optional: [
|
|
237
|
+
ICommandPalette,
|
|
238
|
+
ICompletionProviderManager,
|
|
239
|
+
ICompletionProviderRegistry,
|
|
240
|
+
ILayoutRestorer,
|
|
241
|
+
ISecretsManager,
|
|
242
|
+
IThemeManager,
|
|
243
|
+
IToolRegistry
|
|
244
|
+
],
|
|
245
|
+
activate: (app, settingsModel, chatProviderRegistry, palette, completionManager, completionProviderRegistry, restorer, secretsManager, themeManager, toolRegistry) => {
|
|
246
|
+
// Build the agent manager
|
|
247
|
+
const agentManager = new AgentManager({
|
|
248
|
+
settingsModel,
|
|
249
|
+
toolRegistry,
|
|
250
|
+
chatProviderRegistry,
|
|
251
|
+
secretsManager,
|
|
252
|
+
token
|
|
253
|
+
});
|
|
254
|
+
// Build the settings panel
|
|
255
|
+
const settingsWidget = new AISettingsWidget({
|
|
256
|
+
settingsModel,
|
|
257
|
+
agentManager,
|
|
258
|
+
themeManager,
|
|
259
|
+
chatProviderRegistry,
|
|
260
|
+
secretsManager,
|
|
261
|
+
token
|
|
262
|
+
});
|
|
263
|
+
settingsWidget.id = 'jupyterlite-ai-settings';
|
|
264
|
+
settingsWidget.title.icon = settingsIcon;
|
|
265
|
+
// Build the completion provider
|
|
266
|
+
if (completionManager && completionProviderRegistry) {
|
|
267
|
+
const completionProvider = new AICompletionProvider({
|
|
268
|
+
settingsModel,
|
|
269
|
+
completionProviderRegistry: completionProviderRegistry,
|
|
270
|
+
secretsManager,
|
|
271
|
+
token
|
|
272
|
+
});
|
|
273
|
+
completionManager.registerInlineProvider(completionProvider);
|
|
274
|
+
}
|
|
275
|
+
else {
|
|
276
|
+
console.info('Completion provider manager not available, skipping AI completion setup');
|
|
277
|
+
}
|
|
278
|
+
if (restorer) {
|
|
279
|
+
restorer.add(settingsWidget, settingsWidget.id);
|
|
189
280
|
}
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
281
|
+
app.commands.addCommand(CommandIds.openSettings, {
|
|
282
|
+
label: 'AI Settings',
|
|
283
|
+
caption: 'Configure AI providers and behavior',
|
|
284
|
+
icon: settingsIcon,
|
|
285
|
+
execute: () => {
|
|
286
|
+
// Check if the widget already exists in shell
|
|
287
|
+
let widget = Array.from(app.shell.widgets('main')).find(w => w.id === 'jupyterlite-ai-settings');
|
|
288
|
+
if (!widget && settingsWidget) {
|
|
289
|
+
// Use the pre-created widget
|
|
290
|
+
widget = settingsWidget;
|
|
291
|
+
app.shell.add(widget, 'main');
|
|
292
|
+
}
|
|
293
|
+
if (widget) {
|
|
294
|
+
app.shell.activateById(widget.id);
|
|
295
|
+
}
|
|
296
|
+
},
|
|
297
|
+
describedBy: {
|
|
298
|
+
args: {}
|
|
198
299
|
}
|
|
199
|
-
loadSetting(settings);
|
|
200
|
-
settings.changed.connect(loadSetting);
|
|
201
|
-
})
|
|
202
|
-
.catch(reason => {
|
|
203
|
-
console.error(`Something went wrong when reading the settings.\n${reason}`);
|
|
204
300
|
});
|
|
301
|
+
// Add to command palette if available
|
|
302
|
+
if (palette) {
|
|
303
|
+
palette.addItem({
|
|
304
|
+
command: CommandIds.openSettings,
|
|
305
|
+
category: 'AI Assistant'
|
|
306
|
+
});
|
|
307
|
+
}
|
|
308
|
+
return agentManager;
|
|
309
|
+
}
|
|
310
|
+
}));
|
|
311
|
+
/**
|
|
312
|
+
* A plugin to provide the settings model.
|
|
313
|
+
*/
|
|
314
|
+
const settingsModel = {
|
|
315
|
+
id: '@jupyterlite/ai:settings-model',
|
|
316
|
+
description: 'Provide the AI settings model',
|
|
317
|
+
autoStart: true,
|
|
318
|
+
provides: IAISettingsModel,
|
|
319
|
+
requires: [ISettingRegistry],
|
|
320
|
+
activate: (app, settingRegistry) => {
|
|
321
|
+
return new AISettingsModel({ settingRegistry });
|
|
322
|
+
}
|
|
323
|
+
};
|
|
324
|
+
/**
|
|
325
|
+
* A plugin to provide the tool registry.
|
|
326
|
+
*/
|
|
327
|
+
const toolRegistry = {
|
|
328
|
+
id: '@jupyterlite/ai:tool-registry',
|
|
329
|
+
description: 'Provide the AI tool registry',
|
|
330
|
+
autoStart: true,
|
|
331
|
+
requires: [IAISettingsModel, IDocumentManager, IKernelSpecManager],
|
|
332
|
+
optional: [INotebookTracker],
|
|
333
|
+
provides: IToolRegistry,
|
|
334
|
+
activate: (app, settingsModel, docManager, kernelSpecManager, notebookTracker) => {
|
|
335
|
+
const { commands } = app;
|
|
336
|
+
const toolRegistry = new ToolRegistry();
|
|
337
|
+
const notebookCreationTool = createNotebookCreationTool(docManager, kernelSpecManager);
|
|
338
|
+
toolRegistry.add('create_notebook', notebookCreationTool);
|
|
339
|
+
// Add high-level notebook operation tools
|
|
340
|
+
const addCellTool = createAddCellTool(docManager, notebookTracker);
|
|
341
|
+
const getNotebookInfoTool = createGetNotebookInfoTool(docManager, notebookTracker);
|
|
342
|
+
const getCellInfoTool = createGetCellInfoTool(docManager, notebookTracker);
|
|
343
|
+
const setCellContentTool = createSetCellContentTool(docManager, commands, notebookTracker);
|
|
344
|
+
const runCellTool = createRunCellTool(docManager, notebookTracker);
|
|
345
|
+
const deleteCellTool = createDeleteCellTool(docManager, notebookTracker);
|
|
346
|
+
const saveNotebookTool = createSaveNotebookTool(docManager, notebookTracker);
|
|
347
|
+
const executeActiveCellTool = createExecuteActiveCellTool(docManager, notebookTracker);
|
|
348
|
+
toolRegistry.add('add_cell', addCellTool);
|
|
349
|
+
toolRegistry.add('get_notebook_info', getNotebookInfoTool);
|
|
350
|
+
toolRegistry.add('get_cell_info', getCellInfoTool);
|
|
351
|
+
toolRegistry.add('set_cell_content', setCellContentTool);
|
|
352
|
+
toolRegistry.add('run_cell', runCellTool);
|
|
353
|
+
toolRegistry.add('delete_cell', deleteCellTool);
|
|
354
|
+
toolRegistry.add('save_notebook', saveNotebookTool);
|
|
355
|
+
toolRegistry.add('execute_active_cell', executeActiveCellTool);
|
|
356
|
+
// Add file operation tools
|
|
357
|
+
const newFileTool = createNewFileTool(docManager);
|
|
358
|
+
const openFileTool = createOpenFileTool(docManager);
|
|
359
|
+
const deleteFileTool = createDeleteFileTool(docManager);
|
|
360
|
+
const renameFileTool = createRenameFileTool(docManager);
|
|
361
|
+
const copyFileTool = createCopyFileTool(docManager);
|
|
362
|
+
const navigateToDirectoryTool = createNavigateToDirectoryTool(app.commands);
|
|
363
|
+
toolRegistry.add('create_file', newFileTool);
|
|
364
|
+
toolRegistry.add('open_file', openFileTool);
|
|
365
|
+
toolRegistry.add('delete_file', deleteFileTool);
|
|
366
|
+
toolRegistry.add('rename_file', renameFileTool);
|
|
367
|
+
toolRegistry.add('copy_file', copyFileTool);
|
|
368
|
+
toolRegistry.add('navigate_to_directory', navigateToDirectoryTool);
|
|
369
|
+
// Add command operation tools
|
|
370
|
+
const discoverCommandsTool = createDiscoverCommandsTool(app.commands);
|
|
371
|
+
const executeCommandTool = createExecuteCommandTool(app.commands, settingsModel);
|
|
372
|
+
toolRegistry.add('discover_commands', discoverCommandsTool);
|
|
373
|
+
toolRegistry.add('execute_command', executeCommandTool);
|
|
374
|
+
return toolRegistry;
|
|
205
375
|
}
|
|
206
376
|
};
|
|
207
377
|
export default [
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
378
|
+
chatProviderRegistryPlugin,
|
|
379
|
+
completionProviderRegistryPlugin,
|
|
380
|
+
builtInChatProvidersPlugin,
|
|
381
|
+
builtInCompletionProvidersPlugin,
|
|
382
|
+
plugin,
|
|
383
|
+
settingsModel,
|
|
384
|
+
agentManager,
|
|
385
|
+
toolRegistry
|
|
214
386
|
];
|
|
215
|
-
|
|
216
|
-
export * from './
|
|
387
|
+
// Export extension points for other extensions to use
|
|
388
|
+
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 {};
|