@jupyterlite/ai 0.8.0 → 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.
Files changed (162) hide show
  1. package/lib/agent.d.ts +233 -0
  2. package/lib/agent.js +604 -0
  3. package/lib/chat-model.d.ts +195 -0
  4. package/lib/chat-model.js +590 -0
  5. package/lib/completion/completion-provider.d.ts +83 -0
  6. package/lib/completion/completion-provider.js +209 -0
  7. package/lib/completion/index.d.ts +1 -0
  8. package/lib/completion/index.js +1 -0
  9. package/lib/components/clear-button.d.ts +18 -0
  10. package/lib/components/clear-button.js +31 -0
  11. package/lib/components/index.d.ts +3 -0
  12. package/lib/components/index.js +3 -0
  13. package/lib/components/model-select.d.ts +19 -0
  14. package/lib/components/model-select.js +154 -0
  15. package/lib/components/stop-button.d.ts +3 -3
  16. package/lib/components/stop-button.js +8 -9
  17. package/lib/components/token-usage-display.d.ts +45 -0
  18. package/lib/components/token-usage-display.js +74 -0
  19. package/lib/components/tool-select.d.ts +27 -0
  20. package/lib/components/tool-select.js +130 -0
  21. package/lib/icons.d.ts +3 -1
  22. package/lib/icons.js +10 -13
  23. package/lib/index.d.ts +4 -5
  24. package/lib/index.js +322 -167
  25. package/lib/mcp/browser.d.ts +68 -0
  26. package/lib/mcp/browser.js +132 -0
  27. package/lib/models/settings-model.d.ts +69 -0
  28. package/lib/models/settings-model.js +295 -0
  29. package/lib/providers/built-in-providers.d.ts +9 -0
  30. package/lib/providers/built-in-providers.js +192 -0
  31. package/lib/providers/models.d.ts +37 -0
  32. package/lib/providers/models.js +28 -0
  33. package/lib/providers/provider-registry.d.ts +94 -0
  34. package/lib/providers/provider-registry.js +155 -0
  35. package/lib/tokens.d.ts +157 -86
  36. package/lib/tokens.js +16 -12
  37. package/lib/tools/commands.d.ts +11 -0
  38. package/lib/tools/commands.js +126 -0
  39. package/lib/tools/file.d.ts +27 -0
  40. package/lib/tools/file.js +262 -0
  41. package/lib/tools/notebook.d.ts +40 -0
  42. package/lib/tools/notebook.js +762 -0
  43. package/lib/tools/tool-registry.d.ts +35 -0
  44. package/lib/tools/tool-registry.js +55 -0
  45. package/lib/widgets/ai-settings.d.ts +39 -0
  46. package/lib/widgets/ai-settings.js +506 -0
  47. package/lib/widgets/chat-wrapper.d.ts +144 -0
  48. package/lib/widgets/chat-wrapper.js +390 -0
  49. package/lib/widgets/provider-config-dialog.d.ts +13 -0
  50. package/lib/widgets/provider-config-dialog.js +104 -0
  51. package/package.json +150 -41
  52. package/schema/settings-model.json +153 -0
  53. package/src/agent.ts +800 -0
  54. package/src/chat-model.ts +770 -0
  55. package/src/completion/completion-provider.ts +308 -0
  56. package/src/completion/index.ts +1 -0
  57. package/src/components/clear-button.tsx +56 -0
  58. package/src/components/index.ts +3 -0
  59. package/src/components/model-select.tsx +245 -0
  60. package/src/components/stop-button.tsx +11 -11
  61. package/src/components/token-usage-display.tsx +130 -0
  62. package/src/components/tool-select.tsx +218 -0
  63. package/src/icons.ts +12 -14
  64. package/src/index.ts +468 -238
  65. package/src/mcp/browser.ts +213 -0
  66. package/src/models/settings-model.ts +409 -0
  67. package/src/providers/built-in-providers.ts +216 -0
  68. package/src/providers/models.ts +79 -0
  69. package/src/providers/provider-registry.ts +189 -0
  70. package/src/tokens.ts +203 -90
  71. package/src/tools/commands.ts +151 -0
  72. package/src/tools/file.ts +307 -0
  73. package/src/tools/notebook.ts +964 -0
  74. package/src/tools/tool-registry.ts +63 -0
  75. package/src/types.d.ts +4 -0
  76. package/src/widgets/ai-settings.tsx +1100 -0
  77. package/src/widgets/chat-wrapper.tsx +543 -0
  78. package/src/widgets/provider-config-dialog.tsx +256 -0
  79. package/style/base.css +335 -14
  80. package/style/icons/jupyternaut-lite.svg +1 -1
  81. package/lib/base-completer.d.ts +0 -49
  82. package/lib/base-completer.js +0 -14
  83. package/lib/chat-handler.d.ts +0 -56
  84. package/lib/chat-handler.js +0 -201
  85. package/lib/completion-provider.d.ts +0 -34
  86. package/lib/completion-provider.js +0 -32
  87. package/lib/default-prompts.d.ts +0 -2
  88. package/lib/default-prompts.js +0 -31
  89. package/lib/default-providers/Anthropic/completer.d.ts +0 -12
  90. package/lib/default-providers/Anthropic/completer.js +0 -46
  91. package/lib/default-providers/Anthropic/settings-schema.json +0 -70
  92. package/lib/default-providers/ChromeAI/completer.d.ts +0 -12
  93. package/lib/default-providers/ChromeAI/completer.js +0 -56
  94. package/lib/default-providers/ChromeAI/instructions.d.ts +0 -6
  95. package/lib/default-providers/ChromeAI/instructions.js +0 -42
  96. package/lib/default-providers/ChromeAI/settings-schema.json +0 -18
  97. package/lib/default-providers/Gemini/completer.d.ts +0 -12
  98. package/lib/default-providers/Gemini/completer.js +0 -48
  99. package/lib/default-providers/Gemini/instructions.d.ts +0 -2
  100. package/lib/default-providers/Gemini/instructions.js +0 -9
  101. package/lib/default-providers/Gemini/settings-schema.json +0 -64
  102. package/lib/default-providers/MistralAI/completer.d.ts +0 -13
  103. package/lib/default-providers/MistralAI/completer.js +0 -52
  104. package/lib/default-providers/MistralAI/instructions.d.ts +0 -2
  105. package/lib/default-providers/MistralAI/instructions.js +0 -18
  106. package/lib/default-providers/MistralAI/settings-schema.json +0 -75
  107. package/lib/default-providers/Ollama/completer.d.ts +0 -12
  108. package/lib/default-providers/Ollama/completer.js +0 -43
  109. package/lib/default-providers/Ollama/instructions.d.ts +0 -2
  110. package/lib/default-providers/Ollama/instructions.js +0 -70
  111. package/lib/default-providers/Ollama/settings-schema.json +0 -143
  112. package/lib/default-providers/OpenAI/completer.d.ts +0 -12
  113. package/lib/default-providers/OpenAI/completer.js +0 -43
  114. package/lib/default-providers/OpenAI/settings-schema.json +0 -628
  115. package/lib/default-providers/WebLLM/completer.d.ts +0 -21
  116. package/lib/default-providers/WebLLM/completer.js +0 -127
  117. package/lib/default-providers/WebLLM/instructions.d.ts +0 -6
  118. package/lib/default-providers/WebLLM/instructions.js +0 -32
  119. package/lib/default-providers/WebLLM/settings-schema.json +0 -19
  120. package/lib/default-providers/index.d.ts +0 -2
  121. package/lib/default-providers/index.js +0 -179
  122. package/lib/provider.d.ts +0 -144
  123. package/lib/provider.js +0 -412
  124. package/lib/settings/base.json +0 -7
  125. package/lib/settings/index.d.ts +0 -3
  126. package/lib/settings/index.js +0 -3
  127. package/lib/settings/panel.d.ts +0 -226
  128. package/lib/settings/panel.js +0 -510
  129. package/lib/settings/textarea.d.ts +0 -2
  130. package/lib/settings/textarea.js +0 -18
  131. package/lib/settings/utils.d.ts +0 -2
  132. package/lib/settings/utils.js +0 -4
  133. package/lib/types/ai-model.d.ts +0 -24
  134. package/lib/types/ai-model.js +0 -5
  135. package/schema/chat.json +0 -28
  136. package/schema/provider-registry.json +0 -29
  137. package/schema/system-prompts.json +0 -22
  138. package/src/base-completer.ts +0 -75
  139. package/src/chat-handler.ts +0 -262
  140. package/src/completion-provider.ts +0 -64
  141. package/src/default-prompts.ts +0 -33
  142. package/src/default-providers/Anthropic/completer.ts +0 -59
  143. package/src/default-providers/ChromeAI/completer.ts +0 -73
  144. package/src/default-providers/ChromeAI/instructions.ts +0 -45
  145. package/src/default-providers/Gemini/completer.ts +0 -61
  146. package/src/default-providers/Gemini/instructions.ts +0 -9
  147. package/src/default-providers/MistralAI/completer.ts +0 -69
  148. package/src/default-providers/MistralAI/instructions.ts +0 -18
  149. package/src/default-providers/Ollama/completer.ts +0 -54
  150. package/src/default-providers/Ollama/instructions.ts +0 -70
  151. package/src/default-providers/OpenAI/completer.ts +0 -54
  152. package/src/default-providers/WebLLM/completer.ts +0 -151
  153. package/src/default-providers/WebLLM/instructions.ts +0 -33
  154. package/src/default-providers/index.ts +0 -211
  155. package/src/global.d.ts +0 -9
  156. package/src/provider.ts +0 -514
  157. package/src/settings/index.ts +0 -3
  158. package/src/settings/panel.tsx +0 -773
  159. package/src/settings/textarea.tsx +0 -33
  160. package/src/settings/utils.ts +0 -5
  161. package/src/types/ai-model.ts +0 -37
  162. package/src/types/service-worker.d.ts +0 -6
@@ -1,510 +0,0 @@
1
- import { Button, FormComponent } from '@jupyterlab/ui-components';
2
- import { JSONExt } from '@lumino/coreutils';
3
- import validator from '@rjsf/validator-ajv8';
4
- import React from 'react';
5
- import { getSecretId, SECRETS_REPLACEMENT } from '.';
6
- import baseSettings from './base.json';
7
- import { PLUGIN_IDS } from '../tokens';
8
- const MD_MIME_TYPE = 'text/markdown';
9
- const INSTRUCTION_CLASS = 'jp-AISettingsInstructions';
10
- const ERROR_CLASS = 'jp-AISettingsError';
11
- const SECRETS_NAMESPACE = PLUGIN_IDS.providerRegistry;
12
- const STORAGE_KEYS = {
13
- chat: '@jupyterlite/ai:chat-settings',
14
- completer: '@jupyterlite/ai:completer-settings'
15
- };
16
- export const aiSettingsRenderer = (options) => {
17
- const { secretsToken } = options;
18
- delete options.secretsToken;
19
- if (secretsToken) {
20
- Private.setToken(secretsToken);
21
- }
22
- return {
23
- fieldRenderer: (props) => {
24
- props.formContext = { ...props.formContext, ...options };
25
- return React.createElement(AiSettings, { ...props });
26
- }
27
- };
28
- };
29
- const WrappedFormComponent = (props) => {
30
- return React.createElement(FormComponent, { ...props, validator: validator });
31
- };
32
- export class AiSettings extends React.Component {
33
- constructor(props) {
34
- super(props);
35
- this._settings = props.formContext.settings;
36
- const uniqueProvider = this._settings.get('UniqueProvider').composite ?? true;
37
- this.state = { uniqueProvider };
38
- this._settings.changed.connect(this._settingsChanged);
39
- }
40
- _settingsChanged = () => {
41
- const uniqueProvider = this._settings.get('UniqueProvider').composite ?? true;
42
- if (this.state.uniqueProvider === uniqueProvider) {
43
- return;
44
- }
45
- if (uniqueProvider) {
46
- // Copy chat settings to the completer settings if there should be a unique
47
- // provider for both.
48
- this.setLocalStorageItem('completer', null, this.getLocalStorage('chat'));
49
- this.saveSettingsToRegistry('completer', this.getSettingsFromRegistry('chat'));
50
- }
51
- this.setState({ uniqueProvider });
52
- };
53
- /**
54
- * Get the local storage settings for a specific role (chat or completer).
55
- */
56
- getLocalStorage = (role) => {
57
- const storageKey = STORAGE_KEYS[role];
58
- return JSON.parse(localStorage.getItem(storageKey) ?? '{}');
59
- };
60
- /**
61
- * Set the local storage item for a specific role (chat or completer).
62
- * If the key is not provider (null) we assume the value should replace the whole
63
- * local storage for this role.
64
- */
65
- setLocalStorageItem = (role, key, value) => {
66
- const storageKey = STORAGE_KEYS[role];
67
- let settings;
68
- if (key !== null) {
69
- settings = JSON.parse(localStorage.getItem(storageKey) ?? '{}');
70
- settings[key] = value;
71
- }
72
- else {
73
- settings = value;
74
- }
75
- localStorage.setItem(storageKey, JSON.stringify(settings));
76
- // If both chat and completer use the same settings, only the chat settings should
77
- // be editable for user, so we should duplicate its values to the completer
78
- // local storage.
79
- if (this.state.uniqueProvider && role === 'chat') {
80
- const storageKeyCompleter = STORAGE_KEYS['completer'];
81
- localStorage.setItem(storageKeyCompleter, JSON.stringify(settings));
82
- }
83
- };
84
- /**
85
- * Get the settings from the registry (jupyterlab settings system) for a given role.
86
- */
87
- getSettingsFromRegistry = (role) => {
88
- const settings = this._settings.get('AIproviders')
89
- .composite;
90
- return settings && Object.keys(settings).includes(role)
91
- ? settings[role]
92
- : { provider: 'None' };
93
- };
94
- /**
95
- * Save the settings to the setting registry.
96
- */
97
- saveSettingsToRegistry = (role, settings) => {
98
- const fullSettings = this._settings.get('AIproviders')
99
- .composite;
100
- fullSettings[role] = { ...settings };
101
- // If both chat and completer use the same settings, only the chat settings should
102
- // be editable for user, so we should duplicate its values to the completer
103
- // settings.
104
- if (this.state.uniqueProvider && role === 'chat') {
105
- fullSettings['completer'] = { ...settings };
106
- }
107
- this._settings.set('AIproviders', { ...fullSettings }).catch(console.error);
108
- };
109
- render() {
110
- return (React.createElement("div", null,
111
- React.createElement("h3", null, this.state.uniqueProvider
112
- ? 'Chat and completer provider'
113
- : 'Chat provider'),
114
- React.createElement(AiProviderSettings, { ...this.props, role: 'chat', aiSettings: this }),
115
- !this.state.uniqueProvider && (React.createElement(React.Fragment, null,
116
- React.createElement("h3", null, "Completer provider"),
117
- React.createElement(AiProviderSettings, { ...this.props, role: 'completer', aiSettings: this })))));
118
- }
119
- _settings;
120
- }
121
- export class AiProviderSettings extends React.Component {
122
- constructor(props) {
123
- super(props);
124
- if (!props.formContext.providerRegistry) {
125
- throw new Error('The provider registry is needed to enable the jupyterlite-ai settings panel');
126
- }
127
- this._role = props.role;
128
- this._providerRegistry = props.formContext.providerRegistry;
129
- this._rmRegistry = props.formContext.rmRegistry ?? null;
130
- this._secretsManager = props.formContext.secretsManager ?? null;
131
- this._settings = props.formContext.settings;
132
- const useSecretsManagerSetting = this._settings.get('UseSecretsManager').composite ?? true;
133
- this._useSecretsManager =
134
- useSecretsManagerSetting && this._secretsManager !== null;
135
- // Initialize the providers schema.
136
- const providerSchema = JSONExt.deepCopy(baseSettings);
137
- providerSchema.properties.provider = {
138
- type: 'string',
139
- title: 'Provider',
140
- description: 'The AI provider to use for chat and completion',
141
- default: 'None',
142
- enum: ['None'].concat(this._providerRegistry.providers)
143
- };
144
- this._providerSchema = providerSchema;
145
- // Check if there is saved values in local storage, otherwise use the settings from
146
- // the setting registry (leads to default if there are no user settings).
147
- const storageKey = STORAGE_KEYS[this._role];
148
- const storageSettings = localStorage.getItem(storageKey);
149
- if (storageSettings === null) {
150
- const labSettings = this.props.aiSettings.getSettingsFromRegistry(this._role);
151
- if (Object.keys(labSettings).includes('provider')) {
152
- // Get the provider name.
153
- const provider = Object.entries(labSettings).find(v => v[0] === 'provider')?.[1];
154
- // Save the settings.
155
- const settings = {
156
- _current: provider
157
- };
158
- settings[provider] = labSettings;
159
- this.props.aiSettings.setLocalStorageItem(this._role, null, settings);
160
- }
161
- }
162
- // Initialize the settings from the saved ones.
163
- this._provider = this.getCurrentProvider();
164
- // Initialize the schema.
165
- const schema = this._buildSchema();
166
- // Initialize the current settings.
167
- const isModified = this._updatedFormData(this.getSettingsFromLocalStorage());
168
- this.state = {
169
- schema,
170
- instruction: null,
171
- compatibilityError: null,
172
- isModified: isModified
173
- };
174
- this._renderInstruction();
175
- this._checkProviderCompatibility();
176
- // Update the setting registry.
177
- this.saveSettingsToRegistry();
178
- this._secretsManager?.fieldVisibilityChanged.connect(this._fieldVisibilityChanged);
179
- this._settings.changed.connect(this._settingsChanged);
180
- }
181
- componentDidMount() {
182
- this.componentDidUpdate();
183
- }
184
- async componentDidUpdate() {
185
- if (!this._secretsManager || !this._useSecretsManager) {
186
- return;
187
- }
188
- // Attach the password inputs to the secrets manager.
189
- await this._secretsManager.detachAll(Private.getToken(), SECRETS_NAMESPACE);
190
- const inputs = this._formRef.current?.getElementsByTagName('input') || [];
191
- for (let i = 0; i < inputs.length; i++) {
192
- if (inputs[i].type.toLowerCase() === 'password') {
193
- const label = inputs[i].getAttribute('label');
194
- if (label) {
195
- const id = getSecretId(this._provider, label);
196
- this._secretsManager.attach(Private.getToken(), SECRETS_NAMESPACE, id, inputs[i], (value) => this._onPasswordUpdated(label, value));
197
- }
198
- }
199
- }
200
- }
201
- componentWillUnmount() {
202
- this._settings.changed.disconnect(this._settingsChanged);
203
- this._secretsManager?.fieldVisibilityChanged.disconnect(this._fieldVisibilityChanged);
204
- if (!this._secretsManager || !this._useSecretsManager) {
205
- return;
206
- }
207
- this._secretsManager.detachAll(Private.getToken(), SECRETS_NAMESPACE);
208
- }
209
- /**
210
- * Get the current provider from the local storage.
211
- */
212
- getCurrentProvider() {
213
- const settings = this.props.aiSettings.getLocalStorage(this._role);
214
- return settings['_current'] ?? 'None';
215
- }
216
- /**
217
- * Save the current provider to the local storage.
218
- */
219
- saveCurrentProvider() {
220
- this.props.aiSettings.setLocalStorageItem(this._role, '_current', this._provider);
221
- }
222
- /**
223
- * Get settings from local storage for the current provider provider.
224
- */
225
- getSettingsFromLocalStorage() {
226
- const settings = this.props.aiSettings.getLocalStorage(this._role);
227
- return settings[this._provider] ?? { provider: this._provider };
228
- }
229
- /**
230
- * Save settings in local storage for a given provider.
231
- */
232
- saveSettingsToLocalStorage() {
233
- const currentSettings = { ...this._currentSettings };
234
- // Do not save secrets in local storage if using the secrets manager.
235
- if (this._useSecretsManager) {
236
- this._secretFields.forEach(field => delete currentSettings[field]);
237
- }
238
- this.props.aiSettings.setLocalStorageItem(this._role, this._provider, currentSettings);
239
- }
240
- /**
241
- * Save the settings to the setting registry.
242
- */
243
- saveSettingsToRegistry() {
244
- const sanitizedSettings = { ...this._currentSettings };
245
- if (this._useSecretsManager) {
246
- this._secretFields.forEach(field => {
247
- sanitizedSettings[field] = SECRETS_REPLACEMENT;
248
- });
249
- }
250
- this.props.aiSettings.saveSettingsToRegistry(this._role, {
251
- provider: this._provider,
252
- ...sanitizedSettings
253
- });
254
- }
255
- /**
256
- * Triggered when the settings has changed.
257
- */
258
- _settingsChanged = (settings) => {
259
- this._updateUseSecretsManager(this._settings.get('UseSecretsManager').composite ?? true);
260
- };
261
- /**
262
- * Triggered when the secret fields visibility has changed.
263
- */
264
- _fieldVisibilityChanged = (_, value) => {
265
- if (this._useSecretsManager) {
266
- this._updateSchema();
267
- }
268
- };
269
- /**
270
- * Update the settings whether the secrets manager is used or not.
271
- *
272
- * @param value - whether to use the secrets manager or not.
273
- */
274
- _updateUseSecretsManager = (value) => {
275
- // No-op if the value did not change or the secrets manager has not been provided.
276
- if (value === this._useSecretsManager || this._secretsManager === null) {
277
- return;
278
- }
279
- // Update the secrets manager.
280
- this._useSecretsManager = value;
281
- if (!value) {
282
- // Detach all the password inputs attached to the secrets manager, and save the
283
- // current settings to the local storage to save the password.
284
- this._secretsManager.detachAll(Private.getToken(), SECRETS_NAMESPACE);
285
- }
286
- else {
287
- // Remove all the keys stored locally.
288
- const settings = this.props.aiSettings.getLocalStorage(this._role);
289
- Object.keys(settings).forEach(provider => {
290
- Object.keys(settings[provider])
291
- .filter(key => key.toLowerCase().includes('key'))
292
- .forEach(key => {
293
- delete settings[provider][key];
294
- });
295
- });
296
- this.props.aiSettings.setLocalStorageItem(this._role, null, settings);
297
- }
298
- this._updateSchema();
299
- this.saveSettingsToLocalStorage();
300
- this.saveSettingsToRegistry();
301
- };
302
- /**
303
- * Build the schema for a given provider.
304
- */
305
- _buildSchema() {
306
- const schema = JSONExt.deepCopy(baseSettings);
307
- this._uiSchema = {};
308
- const settingsSchema = this._providerRegistry.getSettingsSchema(this._provider);
309
- this._secretFields = [];
310
- this._defaultFormData = {};
311
- if (settingsSchema) {
312
- Object.entries(settingsSchema).forEach(([key, value]) => {
313
- if (key.toLowerCase().includes('key')) {
314
- this._secretFields.push(key);
315
- // If the secrets manager is not used, show the secrets fields.
316
- // If the secrets manager is used, check if the fields should be visible.
317
- const showSecretFields = !this._useSecretsManager ||
318
- (this._secretsManager?.secretFieldsVisibility ?? true);
319
- if (!showSecretFields) {
320
- return;
321
- }
322
- this._uiSchema[key] = { 'ui:widget': 'password' };
323
- }
324
- schema.properties[key] = value;
325
- if (value.default !== undefined) {
326
- this._defaultFormData[key] = value.default;
327
- }
328
- });
329
- }
330
- return schema;
331
- }
332
- /**
333
- * Update the schema state for the given provider, that trigger the re-rendering of
334
- * the component.
335
- */
336
- _updateSchema() {
337
- const schema = this._buildSchema();
338
- this.setState({ schema });
339
- }
340
- /**
341
- * Render the markdown instructions for the current provider.
342
- */
343
- async _renderInstruction() {
344
- let instructions = this._providerRegistry.getInstructions(this._provider);
345
- if (!this._rmRegistry || !instructions) {
346
- this.setState({ instruction: null });
347
- return;
348
- }
349
- instructions = `---\n\n${instructions}\n\n---`;
350
- const renderer = this._rmRegistry.createRenderer(MD_MIME_TYPE);
351
- const model = this._rmRegistry.createModel({
352
- data: { [MD_MIME_TYPE]: instructions }
353
- });
354
- await renderer.renderModel(model);
355
- this.setState({ instruction: renderer.node });
356
- }
357
- /**
358
- * Check for compatibility of the provider with the current environment.
359
- * If the provider is not compatible, display an error message.
360
- */
361
- async _checkProviderCompatibility() {
362
- const compatibilityCheck = this._providerRegistry.getCompatibilityCheck(this._provider);
363
- if (!compatibilityCheck) {
364
- this.setState({ compatibilityError: null });
365
- return;
366
- }
367
- const error = await compatibilityCheck();
368
- if (!error) {
369
- this.setState({ compatibilityError: null });
370
- return;
371
- }
372
- const errorDiv = document.createElement('div');
373
- errorDiv.className = ERROR_CLASS;
374
- errorDiv.innerHTML = error;
375
- this.setState({ compatibilityError: error });
376
- }
377
- /**
378
- * Triggered when the provider has changed, to update the schema and values.
379
- * Update the Jupyterlab settings accordingly.
380
- */
381
- _onProviderChanged = (e) => {
382
- const provider = e.formData.provider;
383
- if (provider === this._currentSettings.provider) {
384
- return;
385
- }
386
- this._provider = provider;
387
- this.saveCurrentProvider();
388
- this._updateSchema();
389
- this._renderInstruction();
390
- this._checkProviderCompatibility();
391
- // Initialize the current settings.
392
- const isModified = this._updatedFormData(this.getSettingsFromLocalStorage());
393
- if (isModified !== this.state.isModified) {
394
- this.setState({ isModified });
395
- }
396
- this.saveSettingsToRegistry();
397
- };
398
- /**
399
- * Callback function called when the password input has been programmatically updated
400
- * with the secret manager.
401
- */
402
- _onPasswordUpdated = (fieldName, value) => {
403
- this._currentSettings[fieldName] = value;
404
- this.saveSettingsToRegistry();
405
- };
406
- /**
407
- * Update the current settings with the new values from the form.
408
- *
409
- * @param data - The form data to update.
410
- * @returns - Boolean whether the form is not the default one.
411
- */
412
- _updatedFormData(data) {
413
- let isModified = false;
414
- Object.entries(data).forEach(([key, value]) => {
415
- if (this._defaultFormData[key] !== undefined) {
416
- if (value === undefined) {
417
- const schemaProperty = this.state.schema.properties?.[key];
418
- if (schemaProperty.type === 'string') {
419
- data[key] = '';
420
- }
421
- }
422
- if (value !== this._defaultFormData[key]) {
423
- isModified = true;
424
- }
425
- }
426
- });
427
- this._currentSettings = JSONExt.deepCopy(data);
428
- return isModified;
429
- }
430
- /**
431
- * Triggered when the form value has changed, to update the current settings and save
432
- * it in local storage.
433
- * Update the Jupyterlab settings accordingly.
434
- */
435
- _onFormChanged = (e) => {
436
- const { formData } = e;
437
- const isModified = this._updatedFormData(formData);
438
- this.saveSettingsToLocalStorage();
439
- this.saveSettingsToRegistry();
440
- if (isModified !== this.state.isModified) {
441
- this.setState({ isModified });
442
- }
443
- };
444
- /**
445
- * Handler for the "Restore to defaults" button - clears all
446
- * modified settings then calls `setFormData` to restore the
447
- * values.
448
- */
449
- _reset = async (event) => {
450
- event.stopPropagation();
451
- this._currentSettings = {
452
- ...this._currentSettings,
453
- ...this._defaultFormData
454
- };
455
- this.saveSettingsToLocalStorage();
456
- this.saveSettingsToRegistry();
457
- this.setState({ isModified: false });
458
- };
459
- render() {
460
- return (React.createElement("div", { ref: this._formRef },
461
- React.createElement(WrappedFormComponent, { formData: { provider: this._provider }, schema: this._providerSchema, onChange: this._onProviderChanged, idPrefix: `jp-SettingsEditor-${PLUGIN_IDS.providerRegistry}-${this._role}` }),
462
- this.state.compatibilityError !== null && (React.createElement("div", { className: ERROR_CLASS },
463
- React.createElement("i", { className: 'fas fa-exclamation-triangle' }),
464
- React.createElement("span", null, this.state.compatibilityError))),
465
- this.state.instruction !== null && (React.createElement("details", null,
466
- React.createElement("summary", { className: INSTRUCTION_CLASS }, "Instructions"),
467
- React.createElement("span", { ref: node => node && node.replaceChildren(this.state.instruction) }))),
468
- React.createElement("div", { className: "jp-SettingsHeader" },
469
- React.createElement("h3", { title: this._provider }, this._provider),
470
- React.createElement("div", { className: "jp-SettingsHeader-buttonbar" }, this.state.isModified && (React.createElement(Button, { className: "jp-RestoreButton", onClick: this._reset }, "Restore to Defaults")))),
471
- React.createElement(WrappedFormComponent, { formData: this._currentSettings, schema: this.state.schema, onChange: this._onFormChanged, uiSchema: this._uiSchema, idPrefix: `jp-SettingsEditor-${PLUGIN_IDS.providerRegistry}-${this._role}`, formContext: {
472
- ...this.props.formContext,
473
- defaultFormData: this._defaultFormData
474
- } })));
475
- }
476
- _role;
477
- _providerRegistry;
478
- _provider;
479
- _providerSchema;
480
- _useSecretsManager;
481
- _rmRegistry;
482
- _secretsManager;
483
- _currentSettings = { provider: 'None' };
484
- _uiSchema = {};
485
- _settings;
486
- _formRef = React.createRef();
487
- _secretFields = [];
488
- _defaultFormData = {};
489
- }
490
- var Private;
491
- (function (Private) {
492
- /**
493
- * The token to use with the secrets manager.
494
- */
495
- let secretsToken;
496
- /**
497
- * Set of the token.
498
- */
499
- function setToken(value) {
500
- secretsToken = value;
501
- }
502
- Private.setToken = setToken;
503
- /**
504
- * get the token.
505
- */
506
- function getToken() {
507
- return secretsToken;
508
- }
509
- Private.getToken = getToken;
510
- })(Private || (Private = {}));
@@ -1,2 +0,0 @@
1
- import { IFormRenderer } from '@jupyterlab/ui-components';
2
- export declare const textArea: IFormRenderer;
@@ -1,18 +0,0 @@
1
- import React, { useState } from 'react';
2
- const TEXTAREA_CLASS = 'jp-AISettingsTextArea';
3
- export const textArea = {
4
- fieldRenderer: (props) => {
5
- const settings = props.formContext.settings;
6
- const schema = settings.schema.properties?.[props.name];
7
- const [formData, setFormData] = useState(props.formData);
8
- settings.changed.connect(() => {
9
- setFormData(settings.get(props.name).composite);
10
- });
11
- const onChange = (event) => {
12
- settings.set(props.name, event.target.value);
13
- };
14
- return (React.createElement(React.Fragment, null,
15
- schema?.title && (React.createElement("h3", { className: "jp-FormGroup-fieldLabel jp-FormGroup-contentItem" }, schema.title)),
16
- React.createElement("textarea", { className: TEXTAREA_CLASS, onChange: onChange }, formData)));
17
- }
18
- };
@@ -1,2 +0,0 @@
1
- export declare const SECRETS_REPLACEMENT = "***";
2
- export declare function getSecretId(provider: string, label: string): string;
@@ -1,4 +0,0 @@
1
- export const SECRETS_REPLACEMENT = '***';
2
- export function getSecretId(provider, label) {
3
- return `${provider}-${label}`;
4
- }
@@ -1,24 +0,0 @@
1
- import { CompletionHandler, IInlineCompletionContext } from '@jupyterlab/completer';
2
- import { IterableReadableStream } from '@langchain/core/utils/stream';
3
- /**
4
- * The reduced AI chat model interface.
5
- */
6
- export type AIChatModel = {
7
- /**
8
- * The stream function of the chat model.
9
- */
10
- stream: (input: any, options?: any) => Promise<IterableReadableStream<any>>;
11
- };
12
- /**
13
- * The reduced AI completer interface.
14
- */
15
- export type AICompleter = {
16
- /**
17
- * The fetch function of the completer.
18
- */
19
- fetch: (request: CompletionHandler.IRequest, context: IInlineCompletionContext) => Promise<any>;
20
- /**
21
- * The optional request completion function of the completer.
22
- */
23
- requestCompletion?: () => void;
24
- };
@@ -1,5 +0,0 @@
1
- /*
2
- * Copyright (c) Jupyter Development Team.
3
- * Distributed under the terms of the Modified BSD License.
4
- */
5
- export {};
package/schema/chat.json DELETED
@@ -1,28 +0,0 @@
1
- {
2
- "title": "Chat Configuration",
3
- "description": "Configuration for the chat panel",
4
- "jupyter.lab.setting-icon": "jupyter-chat::chat",
5
- "jupyter.lab.setting-icon-label": "Jupyter Chat",
6
- "type": "object",
7
- "properties": {
8
- "sendWithShiftEnter": {
9
- "description": "Whether to send a message via Shift-Enter instead of Enter.",
10
- "type": "boolean",
11
- "default": false,
12
- "readOnly": false
13
- },
14
- "enableCodeToolbar": {
15
- "description": "Whether to enable or not the code toolbar.",
16
- "type": "boolean",
17
- "default": true,
18
- "readOnly": false
19
- },
20
- "personaName": {
21
- "type": "string",
22
- "title": "AI persona name",
23
- "description": "The name of the AI persona",
24
- "default": "Jupyternaut"
25
- }
26
- },
27
- "additionalProperties": false
28
- }
@@ -1,29 +0,0 @@
1
- {
2
- "title": "AI providers",
3
- "description": "Provider registry settings",
4
- "jupyter.lab.setting-icon": "@jupyterlite/ai:jupyternaut-lite",
5
- "jupyter.lab.setting-icon-label": "JupyterLite AI provider",
6
- "type": "object",
7
- "properties": {
8
- "UseSecretsManager": {
9
- "type": "boolean",
10
- "title": "Use secrets manager",
11
- "description": "Whether to use or not the secrets manager. If not, secrets will be stored in the browser (local storage)",
12
- "default": true
13
- },
14
- "UniqueProvider": {
15
- "type": "boolean",
16
- "title": "Use the same provider for chat and completer",
17
- "description": "Whether to use only one provider for the chat and the completer.\nThis will overwrite all the settings for the completer, and copy the ones from the chat.",
18
- "default": true
19
- },
20
- "AIproviders": {
21
- "type": "object",
22
- "title": "AI providers",
23
- "description": "The AI providers configuration",
24
- "default": {},
25
- "additionalProperties": true
26
- }
27
- },
28
- "additionalProperties": false
29
- }
@@ -1,22 +0,0 @@
1
- {
2
- "title": "AI system prompts",
3
- "description": "System prompts",
4
- "jupyter.lab.setting-icon": "@jupyterlite/ai:jupyternaut-lite",
5
- "jupyter.lab.setting-icon-label": "JupyterLite AI Chat",
6
- "type": "object",
7
- "properties": {
8
- "chatSystemPrompt": {
9
- "type": "string",
10
- "title": "Chat message system prompt",
11
- "description": "The system prompt for the chat messages",
12
- "default": "You are Jupyternaut, a conversational assistant living in JupyterLab to help users.\nYou are not a language model, but rather an application built on a foundation model from $provider_name$.\nYou are talkative and you provide lots of specific details from the foundation model's context.\nYou may use Markdown to format your response.\nIf your response includes code, they must be enclosed in Markdown fenced code blocks (with triple backticks before and after).\nIf your response includes mathematical notation, they must be expressed in LaTeX markup and enclosed in LaTeX delimiters.\nAll dollar quantities (of USD) must be formatted in LaTeX, with the `$` symbol escaped by a single backslash `\\`.\n- Example prompt: `If I have \\\\$100 and spend \\\\$20, how much money do I have left?`\n- **Correct** response: `You have \\(\\$80\\) remaining.`\n- **Incorrect** response: `You have $80 remaining.`\nIf you do not know the answer to a question, answer truthfully by responding that you do not know.\nThe following is a friendly conversation between you and a human."
13
- },
14
- "completionSystemPrompt": {
15
- "type": "string",
16
- "title": "Completion system prompt",
17
- "description": "The system prompt for the completion",
18
- "default": "You are an application built to provide helpful code completion suggestions.\nYou should only produce code. Keep comments to minimum, use the programming language comment syntax. Produce clean code.\nThe code is written in JupyterLab, a data analysis and code development environment which can execute code extended with additional syntax for interactive features, such as magics.\nOnly give raw strings back, do not format the response using backticks.\nThe output should be a single string, and should only contain the code that will complete the give code passed as input, no explanation whatsoever. Do not include the prompt in the output, only the string that should be appended to the current input. Here is the code to complete:"
19
- }
20
- },
21
- "additionalProperties": false
22
- }