@jupyterlite/ai 0.3.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. package/lib/chat-handler.d.ts +10 -4
  2. package/lib/chat-handler.js +42 -10
  3. package/lib/completion-provider.d.ts +5 -18
  4. package/lib/completion-provider.js +8 -34
  5. package/lib/{llm-models/anthropic-completer.d.ts → default-providers/Anthropic/completer.d.ts} +1 -1
  6. package/lib/{llm-models/anthropic-completer.js → default-providers/Anthropic/completer.js} +1 -1
  7. package/lib/{llm-models/chrome-completer.d.ts → default-providers/ChromeAI/completer.d.ts} +1 -1
  8. package/lib/{llm-models/chrome-completer.js → default-providers/ChromeAI/completer.js} +1 -1
  9. package/lib/default-providers/ChromeAI/instructions.d.ts +2 -0
  10. package/lib/default-providers/ChromeAI/instructions.js +24 -0
  11. package/lib/{llm-models/codestral-completer.d.ts → default-providers/MistralAI/completer.d.ts} +1 -1
  12. package/lib/{llm-models/codestral-completer.js → default-providers/MistralAI/completer.js} +1 -1
  13. package/lib/default-providers/MistralAI/instructions.d.ts +2 -0
  14. package/lib/default-providers/MistralAI/instructions.js +16 -0
  15. package/lib/{llm-models/openai-completer.d.ts → default-providers/OpenAI/completer.d.ts} +1 -1
  16. package/lib/{llm-models/openai-completer.js → default-providers/OpenAI/completer.js} +1 -1
  17. package/lib/default-providers/index.d.ts +2 -0
  18. package/lib/default-providers/index.js +60 -0
  19. package/lib/index.d.ts +3 -3
  20. package/lib/index.js +51 -64
  21. package/lib/provider.d.ts +45 -17
  22. package/lib/provider.js +97 -41
  23. package/lib/settings/base.json +7 -0
  24. package/lib/settings/panel.d.ts +84 -0
  25. package/lib/settings/panel.js +267 -0
  26. package/lib/tokens.d.ts +103 -0
  27. package/lib/tokens.js +5 -0
  28. package/package.json +12 -5
  29. package/schema/provider-registry.json +23 -0
  30. package/src/chat-handler.ts +50 -13
  31. package/src/completion-provider.ts +13 -37
  32. package/src/{llm-models/anthropic-completer.ts → default-providers/Anthropic/completer.ts} +2 -2
  33. package/src/{llm-models/chrome-completer.ts → default-providers/ChromeAI/completer.ts} +3 -2
  34. package/src/default-providers/ChromeAI/instructions.ts +24 -0
  35. package/src/{llm-models/codestral-completer.ts → default-providers/MistralAI/completer.ts} +2 -2
  36. package/src/default-providers/MistralAI/instructions.ts +16 -0
  37. package/src/{llm-models/openai-completer.ts → default-providers/OpenAI/completer.ts} +2 -2
  38. package/src/default-providers/index.ts +71 -0
  39. package/src/index.ts +75 -77
  40. package/src/provider.ts +100 -43
  41. package/src/settings/panel.tsx +346 -0
  42. package/src/tokens.ts +112 -0
  43. package/style/base.css +4 -0
  44. package/lib/llm-models/index.d.ts +0 -3
  45. package/lib/llm-models/index.js +0 -3
  46. package/lib/llm-models/utils.d.ts +0 -16
  47. package/lib/llm-models/utils.js +0 -86
  48. package/lib/slash-commands.d.ts +0 -16
  49. package/lib/slash-commands.js +0 -25
  50. package/lib/token.d.ts +0 -13
  51. package/lib/token.js +0 -2
  52. package/schema/ai-provider.json +0 -17
  53. package/src/llm-models/index.ts +0 -3
  54. package/src/llm-models/utils.ts +0 -90
  55. package/src/slash-commands.tsx +0 -55
  56. package/src/token.ts +0 -19
  57. /package/lib/{llm-models/base-completer.d.ts → base-completer.d.ts} +0 -0
  58. /package/lib/{llm-models/base-completer.js → base-completer.js} +0 -0
  59. /package/lib/{_provider-settings/anthropic.json → default-providers/Anthropic/settings-schema.json} +0 -0
  60. /package/lib/{_provider-settings/chromeAI.json → default-providers/ChromeAI/settings-schema.json} +0 -0
  61. /package/lib/{_provider-settings/mistralAI.json → default-providers/MistralAI/settings-schema.json} +0 -0
  62. /package/lib/{_provider-settings/openAI.json → default-providers/OpenAI/settings-schema.json} +0 -0
  63. /package/src/{llm-models/base-completer.ts → base-completer.ts} +0 -0
  64. /package/src/{llm-models/svg.d.ts → global.d.ts} +0 -0
@@ -0,0 +1,346 @@
1
+ import { IRenderMimeRegistry } from '@jupyterlab/rendermime';
2
+ import { ISettingRegistry } from '@jupyterlab/settingregistry';
3
+ import { FormComponent, IFormRenderer } from '@jupyterlab/ui-components';
4
+ import { ArrayExt } from '@lumino/algorithm';
5
+ import { JSONExt } from '@lumino/coreutils';
6
+ import { IChangeEvent } from '@rjsf/core';
7
+ import type { FieldProps } from '@rjsf/utils';
8
+ import validator from '@rjsf/validator-ajv8';
9
+ import { JSONSchema7 } from 'json-schema';
10
+ import { ISecretsManager } from 'jupyter-secrets-manager';
11
+ import React from 'react';
12
+
13
+ import baseSettings from './base.json';
14
+ import { IAIProviderRegistry, IDict } from '../tokens';
15
+
16
+ const SECRETS_NAMESPACE = '@jupyterlite/ai';
17
+ const MD_MIME_TYPE = 'text/markdown';
18
+ const STORAGE_NAME = '@jupyterlite/ai:settings';
19
+ const INSTRUCTION_CLASS = 'jp-AISettingsInstructions';
20
+
21
+ export const aiSettingsRenderer = (options: {
22
+ providerRegistry: IAIProviderRegistry;
23
+ rmRegistry?: IRenderMimeRegistry;
24
+ secretsManager?: ISecretsManager;
25
+ }): IFormRenderer => {
26
+ return {
27
+ fieldRenderer: (props: FieldProps) => {
28
+ props.formContext = { ...props.formContext, ...options };
29
+ return <AiSettings {...props} />;
30
+ }
31
+ };
32
+ };
33
+
34
+ export interface ISettingsFormStates {
35
+ schema: JSONSchema7;
36
+ instruction: HTMLElement | null;
37
+ }
38
+
39
+ const WrappedFormComponent = (props: any): JSX.Element => {
40
+ return <FormComponent {...props} validator={validator} />;
41
+ };
42
+
43
+ export class AiSettings extends React.Component<
44
+ FieldProps,
45
+ ISettingsFormStates
46
+ > {
47
+ constructor(props: FieldProps) {
48
+ super(props);
49
+ if (!props.formContext.providerRegistry) {
50
+ throw new Error(
51
+ 'The provider registry is needed to enable the jupyterlite-ai settings panel'
52
+ );
53
+ }
54
+ this._providerRegistry = props.formContext.providerRegistry;
55
+ this._rmRegistry = props.formContext.rmRegistry ?? null;
56
+ this._secretsManager = props.formContext.secretsManager ?? null;
57
+ this._settings = props.formContext.settings;
58
+
59
+ this._useSecretsManager =
60
+ (this._settings.get('UseSecretsManager').composite as boolean) ?? true;
61
+
62
+ // Initialize the providers schema.
63
+ const providerSchema = JSONExt.deepCopy(baseSettings) as any;
64
+ providerSchema.properties.provider = {
65
+ type: 'string',
66
+ title: 'Provider',
67
+ description: 'The AI provider to use for chat and completion',
68
+ default: 'None',
69
+ enum: ['None'].concat(this._providerRegistry.providers)
70
+ };
71
+ this._providerSchema = providerSchema as JSONSchema7;
72
+
73
+ // Check if there is saved values in local storage, otherwise use the settings from
74
+ // the setting registry (led to default if there are no user settings).
75
+ const storageSettings = localStorage.getItem(STORAGE_NAME);
76
+ if (storageSettings === null) {
77
+ const labSettings = this._settings.get('AIprovider').composite;
78
+ if (labSettings && Object.keys(labSettings).includes('provider')) {
79
+ // Get the provider name.
80
+ const provider = Object.entries(labSettings).find(
81
+ v => v[0] === 'provider'
82
+ )?.[1] as string;
83
+ // Save the settings.
84
+ const settings: any = {
85
+ _current: provider
86
+ };
87
+ settings[provider] = labSettings;
88
+ localStorage.setItem(STORAGE_NAME, JSON.stringify(settings));
89
+ }
90
+ }
91
+
92
+ // Initialize the settings from the saved ones.
93
+ this._provider = this.getCurrentProvider();
94
+ this._currentSettings = this.getSettings();
95
+
96
+ // Initialize the schema.
97
+ const schema = this._buildSchema();
98
+ this.state = { schema, instruction: null };
99
+
100
+ this._renderInstruction();
101
+
102
+ // Update the setting registry.
103
+ this._settings
104
+ .set('AIprovider', this._currentSettings)
105
+ .catch(console.error);
106
+
107
+ this._settings.changed.connect(() => {
108
+ const useSecretsManager =
109
+ (this._settings.get('UseSecretsManager').composite as boolean) ?? true;
110
+ if (useSecretsManager !== this._useSecretsManager) {
111
+ this.updateUseSecretsManager(useSecretsManager);
112
+ }
113
+ });
114
+ }
115
+
116
+ async componentDidUpdate(): Promise<void> {
117
+ if (!this._secretsManager || !this._useSecretsManager) {
118
+ return;
119
+ }
120
+ // Attach the password inputs to the secrets manager only if they have changed.
121
+ const inputs = this._formRef.current?.getElementsByTagName('input') || [];
122
+ if (ArrayExt.shallowEqual(inputs, this._formInputs)) {
123
+ return;
124
+ }
125
+
126
+ await this._secretsManager.detachAll(SECRETS_NAMESPACE);
127
+ this._formInputs = [...inputs];
128
+ this._unsavedFields = [];
129
+ for (let i = 0; i < inputs.length; i++) {
130
+ if (inputs[i].type.toLowerCase() === 'password') {
131
+ const label = inputs[i].getAttribute('label');
132
+ if (label) {
133
+ const id = `${this._provider}-${label}`;
134
+ this._secretsManager.attach(
135
+ SECRETS_NAMESPACE,
136
+ id,
137
+ inputs[i],
138
+ (value: string) => this._onPasswordUpdated(label, value)
139
+ );
140
+ this._unsavedFields.push(label);
141
+ }
142
+ }
143
+ }
144
+ }
145
+
146
+ /**
147
+ * Get the current provider from the local storage.
148
+ */
149
+ getCurrentProvider(): string {
150
+ const settings = JSON.parse(localStorage.getItem(STORAGE_NAME) || '{}');
151
+ return settings['_current'] ?? 'None';
152
+ }
153
+
154
+ /**
155
+ * Save the current provider to the local storage.
156
+ */
157
+ saveCurrentProvider(): void {
158
+ const settings = JSON.parse(localStorage.getItem(STORAGE_NAME) || '{}');
159
+ settings['_current'] = this._provider;
160
+ localStorage.setItem(STORAGE_NAME, JSON.stringify(settings));
161
+ }
162
+
163
+ /**
164
+ * Get settings from local storage for a given provider.
165
+ */
166
+ getSettings(): IDict<any> {
167
+ const settings = JSON.parse(localStorage.getItem(STORAGE_NAME) || '{}');
168
+ return settings[this._provider] ?? { provider: this._provider };
169
+ }
170
+
171
+ /**
172
+ * Save settings in local storage for a given provider.
173
+ */
174
+ saveSettings(value: IDict<any>) {
175
+ const currentSettings = { ...value };
176
+ const settings = JSON.parse(localStorage.getItem(STORAGE_NAME) ?? '{}');
177
+ this._unsavedFields.forEach(field => delete currentSettings[field]);
178
+ settings[this._provider] = currentSettings;
179
+ localStorage.setItem(STORAGE_NAME, JSON.stringify(settings));
180
+ }
181
+
182
+ private updateUseSecretsManager = (value: boolean) => {
183
+ this._useSecretsManager = value;
184
+ if (!value) {
185
+ // Detach all the password inputs attached to the secrets manager, and save the
186
+ // current settings to the local storage to save the password.
187
+ this._secretsManager?.detachAll(SECRETS_NAMESPACE);
188
+ this._formInputs = [];
189
+ this._unsavedFields = [];
190
+ this.saveSettings(this._currentSettings);
191
+ } else {
192
+ // Remove all the keys stored locally and attach the password inputs to the
193
+ // secrets manager.
194
+ const settings = JSON.parse(localStorage.getItem(STORAGE_NAME) || '{}');
195
+ Object.keys(settings).forEach(provider => {
196
+ Object.keys(settings[provider])
197
+ .filter(key => key.toLowerCase().includes('key'))
198
+ .forEach(key => {
199
+ delete settings[provider][key];
200
+ });
201
+ });
202
+ localStorage.setItem(STORAGE_NAME, JSON.stringify(settings));
203
+ this.componentDidUpdate();
204
+ }
205
+ };
206
+
207
+ /**
208
+ * Update the UI schema of the form.
209
+ * Currently use to hide API keys.
210
+ */
211
+ private _updateUiSchema(key: string) {
212
+ if (key.toLowerCase().includes('key')) {
213
+ this._uiSchema[key] = { 'ui:widget': 'password' };
214
+ }
215
+ }
216
+
217
+ /**
218
+ * Build the schema for a given provider.
219
+ */
220
+ private _buildSchema(): JSONSchema7 {
221
+ const schema = JSONExt.deepCopy(baseSettings) as any;
222
+ this._uiSchema = {};
223
+ const settingsSchema = this._providerRegistry.getSettingsSchema(
224
+ this._provider
225
+ );
226
+
227
+ if (settingsSchema) {
228
+ Object.entries(settingsSchema).forEach(([key, value]) => {
229
+ schema.properties[key] = value;
230
+ this._updateUiSchema(key);
231
+ });
232
+ }
233
+ return schema as JSONSchema7;
234
+ }
235
+
236
+ /**
237
+ * Update the schema state for the given provider, that trigger the re-rendering of
238
+ * the component.
239
+ */
240
+ private _updateSchema() {
241
+ const schema = this._buildSchema();
242
+ this.setState({ schema });
243
+ }
244
+
245
+ /**
246
+ * Render the markdown instructions for the current provider.
247
+ */
248
+ private async _renderInstruction(): Promise<void> {
249
+ let instructions = this._providerRegistry.getInstructions(this._provider);
250
+ if (!this._rmRegistry || !instructions) {
251
+ this.setState({ instruction: null });
252
+ return;
253
+ }
254
+ instructions = `---\n\n${instructions}\n\n---`;
255
+ const renderer = this._rmRegistry.createRenderer(MD_MIME_TYPE);
256
+ const model = this._rmRegistry.createModel({
257
+ data: { [MD_MIME_TYPE]: instructions }
258
+ });
259
+ await renderer.renderModel(model);
260
+ this.setState({ instruction: renderer.node });
261
+ }
262
+
263
+ /**
264
+ * Triggered when the provider hes changed, to update the schema and values.
265
+ * Update the Jupyterlab settings accordingly.
266
+ */
267
+ private _onProviderChanged = (e: IChangeEvent) => {
268
+ const provider = e.formData.provider;
269
+ if (provider === this._currentSettings.provider) {
270
+ return;
271
+ }
272
+ this._provider = provider;
273
+ this.saveCurrentProvider();
274
+ this._currentSettings = this.getSettings();
275
+ this._updateSchema();
276
+ this._renderInstruction();
277
+ this._settings
278
+ .set('AIprovider', { provider: this._provider, ...this._currentSettings })
279
+ .catch(console.error);
280
+ };
281
+
282
+ /**
283
+ * Callback function called when the password input has been programmatically updated
284
+ * with the secret manager.
285
+ */
286
+ private _onPasswordUpdated = (fieldName: string, value: string) => {
287
+ this._currentSettings[fieldName] = value;
288
+ this._settings
289
+ .set('AIprovider', { provider: this._provider, ...this._currentSettings })
290
+ .catch(console.error);
291
+ };
292
+
293
+ /**
294
+ * Triggered when the form value has changed, to update the current settings and save
295
+ * it in local storage.
296
+ * Update the Jupyterlab settings accordingly.
297
+ */
298
+ private _onFormChange = (e: IChangeEvent) => {
299
+ this._currentSettings = JSONExt.deepCopy(e.formData);
300
+ this.saveSettings(this._currentSettings);
301
+ this._settings
302
+ .set('AIprovider', { provider: this._provider, ...this._currentSettings })
303
+ .catch(console.error);
304
+ };
305
+
306
+ render(): JSX.Element {
307
+ return (
308
+ <div ref={this._formRef}>
309
+ <WrappedFormComponent
310
+ formData={{ provider: this._provider }}
311
+ schema={this._providerSchema}
312
+ onChange={this._onProviderChanged}
313
+ />
314
+ {this.state.instruction !== null && (
315
+ <details>
316
+ <summary className={INSTRUCTION_CLASS}>Instructions</summary>
317
+ <span
318
+ ref={node =>
319
+ node && node.replaceChildren(this.state.instruction!)
320
+ }
321
+ />
322
+ </details>
323
+ )}
324
+ <WrappedFormComponent
325
+ formData={this._currentSettings}
326
+ schema={this.state.schema}
327
+ onChange={this._onFormChange}
328
+ uiSchema={this._uiSchema}
329
+ />
330
+ </div>
331
+ );
332
+ }
333
+
334
+ private _providerRegistry: IAIProviderRegistry;
335
+ private _provider: string;
336
+ private _providerSchema: JSONSchema7;
337
+ private _useSecretsManager: boolean;
338
+ private _rmRegistry: IRenderMimeRegistry | null;
339
+ private _secretsManager: ISecretsManager | null;
340
+ private _currentSettings: IDict<any> = { provider: 'None' };
341
+ private _uiSchema: IDict<any> = {};
342
+ private _settings: ISettingRegistry.ISettings;
343
+ private _formRef = React.createRef<HTMLDivElement>();
344
+ private _unsavedFields: string[] = [];
345
+ private _formInputs: HTMLInputElement[] = [];
346
+ }
package/src/tokens.ts ADDED
@@ -0,0 +1,112 @@
1
+ import { BaseChatModel } from '@langchain/core/language_models/chat_models';
2
+ import { ReadonlyPartialJSONObject, Token } from '@lumino/coreutils';
3
+ import { ISignal } from '@lumino/signaling';
4
+ import { JSONSchema7 } from 'json-schema';
5
+
6
+ import { IBaseCompleter } from './base-completer';
7
+
8
+ export interface IDict<T = any> {
9
+ [key: string]: T;
10
+ }
11
+
12
+ export interface IType<T> {
13
+ new (...args: any[]): T;
14
+ }
15
+
16
+ /**
17
+ * The provider interface.
18
+ */
19
+ export interface IAIProvider {
20
+ /**
21
+ * The name of the provider.
22
+ */
23
+ name: string;
24
+ /**
25
+ * The chat model class to use.
26
+ */
27
+ chatModel?: IType<BaseChatModel>;
28
+ /**
29
+ * The completer class to use.
30
+ */
31
+ completer?: IType<IBaseCompleter>;
32
+ /**
33
+ * the settings schema for the provider.
34
+ */
35
+ settingsSchema?: any;
36
+ /**
37
+ * The instructions to be displayed in the settings, as helper to use the provider.
38
+ * A markdown renderer is used to render the instructions.
39
+ */
40
+ instructions?: string;
41
+ /**
42
+ * A function that extract the error message from the provider API error.
43
+ * Default to `(error) => error.message`.
44
+ */
45
+ errorMessage?: (error: any) => string;
46
+ }
47
+
48
+ /**
49
+ * The provider registry interface.
50
+ */
51
+ export interface IAIProviderRegistry {
52
+ /**
53
+ * Get the list of provider names.
54
+ */
55
+ readonly providers: string[];
56
+ /**
57
+ * Add a new provider.
58
+ */
59
+ add(provider: IAIProvider): void;
60
+ /**
61
+ * Get the current provider name.
62
+ */
63
+ currentName: string;
64
+ /**
65
+ * Get the current completer of the completion provider.
66
+ */
67
+ currentCompleter: IBaseCompleter | null;
68
+ /**
69
+ * Get the current llm chat model.
70
+ */
71
+ currentChatModel: BaseChatModel | null;
72
+ /**
73
+ * Get the settings schema of a given provider.
74
+ */
75
+ getSettingsSchema(provider: string): JSONSchema7;
76
+ /**
77
+ * Get the instructions of a given provider.
78
+ */
79
+ getInstructions(provider: string): string | undefined;
80
+ /**
81
+ * Format an error message from the current provider.
82
+ */
83
+ formatErrorMessage(error: any): string;
84
+ /**
85
+ * Set the providers (chat model and completer).
86
+ * Creates the providers if the name has changed, otherwise only updates their config.
87
+ *
88
+ * @param name - the name of the provider to use.
89
+ * @param settings - the settings for the models.
90
+ */
91
+ setProvider(name: string, settings: ReadonlyPartialJSONObject): void;
92
+ /**
93
+ * A signal emitting when the provider or its settings has changed.
94
+ */
95
+ readonly providerChanged: ISignal<IAIProviderRegistry, void>;
96
+ /**
97
+ * Get the current chat error;
98
+ */
99
+ readonly chatError: string;
100
+ /**
101
+ * get the current completer error.
102
+ */
103
+ readonly completerError: string;
104
+ }
105
+
106
+ /**
107
+ * The provider registry token.
108
+ */
109
+ export const IAIProviderRegistry = new Token<IAIProviderRegistry>(
110
+ '@jupyterlite/ai:provider-registry',
111
+ 'Provider for chat and completion LLM provider'
112
+ );
package/style/base.css CHANGED
@@ -5,3 +5,7 @@
5
5
  */
6
6
 
7
7
  @import url('@jupyter/chat/style/index.css');
8
+
9
+ .jp-AISettingsInstructions {
10
+ font-size: var(--jp-content-font-size1);
11
+ }
@@ -1,3 +0,0 @@
1
- export * from './base-completer';
2
- export * from './codestral-completer';
3
- export * from './utils';
@@ -1,3 +0,0 @@
1
- export * from './base-completer';
2
- export * from './codestral-completer';
3
- export * from './utils';
@@ -1,16 +0,0 @@
1
- import { BaseChatModel } from '@langchain/core/language_models/chat_models';
2
- import { IBaseCompleter } from './base-completer';
3
- import { ReadonlyPartialJSONObject } from '@lumino/coreutils';
4
- /**
5
- * Get an LLM completer from the name.
6
- */
7
- export declare function getCompleter(name: string, settings: ReadonlyPartialJSONObject): IBaseCompleter | null;
8
- /**
9
- * Get an LLM chat model from the name.
10
- */
11
- export declare function getChatModel(name: string, settings: ReadonlyPartialJSONObject): BaseChatModel | null;
12
- /**
13
- * Get the error message from provider.
14
- */
15
- export declare function getErrorMessage(name: string, error: any): string;
16
- export declare function getSettings(name: string): any;
@@ -1,86 +0,0 @@
1
- import { ChatAnthropic } from '@langchain/anthropic';
2
- import { ChromeAI } from '@langchain/community/experimental/llms/chrome_ai';
3
- import { ChatMistralAI } from '@langchain/mistralai';
4
- import { ChatOpenAI } from '@langchain/openai';
5
- import { AnthropicCompleter } from './anthropic-completer';
6
- import { CodestralCompleter } from './codestral-completer';
7
- import { ChromeCompleter } from './chrome-completer';
8
- import { OpenAICompleter } from './openai-completer';
9
- import chromeAI from '../_provider-settings/chromeAI.json';
10
- import mistralAI from '../_provider-settings/mistralAI.json';
11
- import anthropic from '../_provider-settings/anthropic.json';
12
- import openAI from '../_provider-settings/openAI.json';
13
- /**
14
- * Get an LLM completer from the name.
15
- */
16
- export function getCompleter(name, settings) {
17
- if (name === 'MistralAI') {
18
- return new CodestralCompleter({ settings });
19
- }
20
- else if (name === 'Anthropic') {
21
- return new AnthropicCompleter({ settings });
22
- }
23
- else if (name === 'ChromeAI') {
24
- return new ChromeCompleter({ settings });
25
- }
26
- else if (name === 'OpenAI') {
27
- return new OpenAICompleter({ settings });
28
- }
29
- return null;
30
- }
31
- /**
32
- * Get an LLM chat model from the name.
33
- */
34
- export function getChatModel(name, settings) {
35
- if (name === 'MistralAI') {
36
- return new ChatMistralAI({ ...settings });
37
- }
38
- else if (name === 'Anthropic') {
39
- return new ChatAnthropic({ ...settings });
40
- }
41
- else if (name === 'ChromeAI') {
42
- // TODO: fix
43
- // @ts-expect-error: missing properties
44
- return new ChromeAI({ ...settings });
45
- }
46
- else if (name === 'OpenAI') {
47
- return new ChatOpenAI({ ...settings });
48
- }
49
- return null;
50
- }
51
- /**
52
- * Get the error message from provider.
53
- */
54
- export function getErrorMessage(name, error) {
55
- if (name === 'MistralAI') {
56
- return error.message;
57
- }
58
- else if (name === 'Anthropic') {
59
- return error.error.error.message;
60
- }
61
- else if (name === 'ChromeAI') {
62
- return error.message;
63
- }
64
- else if (name === 'OpenAI') {
65
- return error.message;
66
- }
67
- return 'Unknown provider';
68
- }
69
- /*
70
- * Get an LLM completer from the name.
71
- */
72
- export function getSettings(name) {
73
- if (name === 'MistralAI') {
74
- return mistralAI.properties;
75
- }
76
- else if (name === 'Anthropic') {
77
- return anthropic.properties;
78
- }
79
- else if (name === 'ChromeAI') {
80
- return chromeAI.properties;
81
- }
82
- else if (name === 'OpenAI') {
83
- return openAI.properties;
84
- }
85
- return null;
86
- }
@@ -1,16 +0,0 @@
1
- /**
2
- * TODO: reuse from Jupyter AI instead of copying?
3
- * https://github.com/jupyterlab/jupyter-ai/blob/main/packages/jupyter-ai/src/slash-autocompletion.tsx
4
- */
5
- /// <reference types="react-addons-linked-state-mixin" />
6
- import { AutocompleteCommand } from '@jupyter/chat';
7
- import React from 'react';
8
- type SlashCommandOption = AutocompleteCommand & {
9
- id: string;
10
- description: string;
11
- };
12
- /**
13
- * Renders an option shown in the slash command autocomplete.
14
- */
15
- export declare function renderSlashCommandOption(optionProps: React.HTMLAttributes<HTMLLIElement>, option: SlashCommandOption): JSX.Element;
16
- export {};
@@ -1,25 +0,0 @@
1
- /**
2
- * TODO: reuse from Jupyter AI instead of copying?
3
- * https://github.com/jupyterlab/jupyter-ai/blob/main/packages/jupyter-ai/src/slash-autocompletion.tsx
4
- */
5
- import { Box, Typography } from '@mui/material';
6
- import HideSource from '@mui/icons-material/HideSource';
7
- import React from 'react';
8
- const DEFAULT_SLASH_COMMAND_ICONS = {
9
- clear: React.createElement(HideSource, null)
10
- };
11
- /**
12
- * Renders an option shown in the slash command autocomplete.
13
- */
14
- export function renderSlashCommandOption(optionProps, option) {
15
- const icon = option.id in DEFAULT_SLASH_COMMAND_ICONS
16
- ? DEFAULT_SLASH_COMMAND_ICONS[option.id]
17
- : DEFAULT_SLASH_COMMAND_ICONS.unknown;
18
- return (React.createElement("li", { ...optionProps },
19
- React.createElement(Box, { sx: { lineHeight: 0, marginRight: 4, opacity: 0.618 } }, icon),
20
- React.createElement(Box, { sx: { flexGrow: 1 } },
21
- React.createElement(Typography, { component: "span", sx: {
22
- fontSize: 'var(--jp-ui-font-size1)'
23
- } }, option.label),
24
- React.createElement(Typography, { component: "span", sx: { opacity: 0.618, fontSize: 'var(--jp-ui-font-size0)' } }, ' — ' + option.description))));
25
- }
package/lib/token.d.ts DELETED
@@ -1,13 +0,0 @@
1
- import { BaseChatModel } from '@langchain/core/language_models/chat_models';
2
- import { Token } from '@lumino/coreutils';
3
- import { ISignal } from '@lumino/signaling';
4
- import { IBaseCompleter } from './llm-models';
5
- export interface IAIProvider {
6
- name: string;
7
- completer: IBaseCompleter | null;
8
- chatModel: BaseChatModel | null;
9
- modelChange: ISignal<IAIProvider, void>;
10
- chatError: string;
11
- completerError: string;
12
- }
13
- export declare const IAIProvider: Token<IAIProvider>;
package/lib/token.js DELETED
@@ -1,2 +0,0 @@
1
- import { Token } from '@lumino/coreutils';
2
- export const IAIProvider = new Token('@jupyterlite/ai:AIProvider', 'Provider for chat and completion LLM provider');
@@ -1,17 +0,0 @@
1
- {
2
- "title": "AI provider",
3
- "description": "Provider settings",
4
- "jupyter.lab.setting-icon": "@jupyterlite/ai:jupyternaut-lite",
5
- "jupyter.lab.setting-icon-label": "JupyterLite AI Chat",
6
- "type": "object",
7
- "properties": {
8
- "provider": {
9
- "type": "string",
10
- "title": "The AI provider",
11
- "description": "The AI provider to use for chat and completion",
12
- "default": "None",
13
- "enum": ["None", "Anthropic", "ChromeAI", "MistralAI", "OpenAI"]
14
- }
15
- },
16
- "additionalProperties": true
17
- }
@@ -1,3 +0,0 @@
1
- export * from './base-completer';
2
- export * from './codestral-completer';
3
- export * from './utils';