@jupyterlite/ai 0.5.0 → 0.6.1
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/chat-handler.d.ts +2 -0
- package/lib/chat-handler.js +8 -1
- package/lib/completion-provider.d.ts +7 -0
- package/lib/components/stop-button.d.ts +19 -0
- package/lib/components/stop-button.js +32 -0
- package/lib/index.d.ts +2 -1
- package/lib/index.js +56 -16
- package/lib/provider.d.ts +15 -10
- package/lib/provider.js +67 -9
- package/lib/settings/index.d.ts +3 -0
- package/lib/settings/index.js +3 -0
- package/lib/settings/panel.d.ts +6 -5
- package/lib/settings/panel.js +66 -19
- package/lib/settings/settings-connector.d.ts +31 -0
- package/lib/settings/settings-connector.js +61 -0
- package/lib/settings/utils.d.ts +2 -0
- package/lib/settings/utils.js +4 -0
- package/lib/tokens.d.ts +22 -3
- package/lib/tokens.js +7 -0
- package/package.json +17 -12
- package/schema/provider-registry.json +6 -0
- package/src/chat-handler.ts +9 -1
- package/src/completion-provider.ts +7 -0
- package/src/components/stop-button.tsx +56 -0
- package/src/index.ts +102 -52
- package/src/provider.ts +84 -12
- package/src/settings/index.ts +3 -0
- package/src/settings/panel.tsx +72 -17
- package/src/settings/settings-connector.ts +89 -0
- package/src/settings/utils.ts +5 -0
- package/src/tokens.ts +24 -3
package/lib/chat-handler.d.ts
CHANGED
|
@@ -22,12 +22,14 @@ export declare class ChatHandler extends ChatModel {
|
|
|
22
22
|
getHistory(): Promise<IChatHistory>;
|
|
23
23
|
dispose(): void;
|
|
24
24
|
messageAdded(message: IChatMessage): void;
|
|
25
|
+
stopStreaming(): void;
|
|
25
26
|
private _providerRegistry;
|
|
26
27
|
private _personaName;
|
|
27
28
|
private _prompt;
|
|
28
29
|
private _errorMessage;
|
|
29
30
|
private _history;
|
|
30
31
|
private _defaultErrorMessage;
|
|
32
|
+
private _controller;
|
|
31
33
|
}
|
|
32
34
|
export declare namespace ChatHandler {
|
|
33
35
|
interface IOptions extends ChatModel.IOptions {
|
package/lib/chat-handler.js
CHANGED
|
@@ -20,6 +20,7 @@ export class ChatHandler extends ChatModel {
|
|
|
20
20
|
this._errorMessage = '';
|
|
21
21
|
this._history = { messages: [] };
|
|
22
22
|
this._defaultErrorMessage = 'AI provider not configured';
|
|
23
|
+
this._controller = null;
|
|
23
24
|
this._providerRegistry = options.providerRegistry;
|
|
24
25
|
this._prompt = chatSystemPrompt({
|
|
25
26
|
provider_name: this._providerRegistry.currentName
|
|
@@ -107,8 +108,9 @@ export class ChatHandler extends ChatModel {
|
|
|
107
108
|
type: 'msg'
|
|
108
109
|
};
|
|
109
110
|
let content = '';
|
|
111
|
+
this._controller = new AbortController();
|
|
110
112
|
try {
|
|
111
|
-
for await (const chunk of await this._providerRegistry.currentChatModel.stream(messages)) {
|
|
113
|
+
for await (const chunk of await this._providerRegistry.currentChatModel.stream(messages, { signal: this._controller.signal })) {
|
|
112
114
|
content += (_a = chunk.content) !== null && _a !== void 0 ? _a : chunk;
|
|
113
115
|
botMsg.body = content;
|
|
114
116
|
this.messageAdded(botMsg);
|
|
@@ -130,6 +132,7 @@ export class ChatHandler extends ChatModel {
|
|
|
130
132
|
}
|
|
131
133
|
finally {
|
|
132
134
|
this.updateWriters([]);
|
|
135
|
+
this._controller = null;
|
|
133
136
|
}
|
|
134
137
|
}
|
|
135
138
|
async getHistory() {
|
|
@@ -141,6 +144,10 @@ export class ChatHandler extends ChatModel {
|
|
|
141
144
|
messageAdded(message) {
|
|
142
145
|
super.messageAdded(message);
|
|
143
146
|
}
|
|
147
|
+
stopStreaming() {
|
|
148
|
+
var _a;
|
|
149
|
+
(_a = this._controller) === null || _a === void 0 ? void 0 : _a.abort();
|
|
150
|
+
}
|
|
144
151
|
}
|
|
145
152
|
(function (ChatHandler) {
|
|
146
153
|
class ClearCommandProvider {
|
|
@@ -21,7 +21,14 @@ export declare class CompletionProvider implements IInlineCompletionProvider {
|
|
|
21
21
|
}
|
|
22
22
|
export declare namespace CompletionProvider {
|
|
23
23
|
interface IOptions {
|
|
24
|
+
/**
|
|
25
|
+
* The registry where the completion provider belongs.
|
|
26
|
+
*/
|
|
24
27
|
providerRegistry: IAIProviderRegistry;
|
|
28
|
+
/**
|
|
29
|
+
* The request completion commands, can be useful if a provider needs to request
|
|
30
|
+
* the completion by itself.
|
|
31
|
+
*/
|
|
25
32
|
requestCompletion: () => void;
|
|
26
33
|
}
|
|
27
34
|
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
import { InputToolbarRegistry } from '@jupyter/chat';
|
|
3
|
+
/**
|
|
4
|
+
* Properties of the stop button.
|
|
5
|
+
*/
|
|
6
|
+
export interface IStopButtonProps extends InputToolbarRegistry.IToolbarItemProps {
|
|
7
|
+
/**
|
|
8
|
+
* The function to stop streaming.
|
|
9
|
+
*/
|
|
10
|
+
stopStreaming: () => void;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* The stop button.
|
|
14
|
+
*/
|
|
15
|
+
export declare function StopButton(props: IStopButtonProps): JSX.Element;
|
|
16
|
+
/**
|
|
17
|
+
* factory returning the toolbar item.
|
|
18
|
+
*/
|
|
19
|
+
export declare function stopItem(stopStreaming: () => void): InputToolbarRegistry.IToolbarItem;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) Jupyter Development Team.
|
|
3
|
+
* Distributed under the terms of the Modified BSD License.
|
|
4
|
+
*/
|
|
5
|
+
import StopIcon from '@mui/icons-material/Stop';
|
|
6
|
+
import React from 'react';
|
|
7
|
+
import { TooltippedButton } from '@jupyter/chat';
|
|
8
|
+
/**
|
|
9
|
+
* The stop button.
|
|
10
|
+
*/
|
|
11
|
+
export function StopButton(props) {
|
|
12
|
+
const tooltip = 'Stop streaming';
|
|
13
|
+
return (React.createElement(TooltippedButton, { onClick: props.stopStreaming, tooltip: tooltip, buttonProps: {
|
|
14
|
+
size: 'small',
|
|
15
|
+
variant: 'contained',
|
|
16
|
+
title: tooltip
|
|
17
|
+
} },
|
|
18
|
+
React.createElement(StopIcon, null)));
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* factory returning the toolbar item.
|
|
22
|
+
*/
|
|
23
|
+
export function stopItem(stopStreaming) {
|
|
24
|
+
return {
|
|
25
|
+
element: (props) => {
|
|
26
|
+
const stopProps = { ...props, stopStreaming };
|
|
27
|
+
return StopButton(stopProps);
|
|
28
|
+
},
|
|
29
|
+
position: 50,
|
|
30
|
+
hidden: true /* hidden by default */
|
|
31
|
+
};
|
|
32
|
+
}
|
package/lib/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { IChatCommandRegistry } from '@jupyter/chat';
|
|
2
2
|
import { JupyterFrontEndPlugin } from '@jupyterlab/application';
|
|
3
|
+
import { ISettingConnector } from '@jupyterlab/settingregistry';
|
|
3
4
|
import { IAIProviderRegistry } from './tokens';
|
|
4
|
-
declare const _default: (JupyterFrontEndPlugin<void> | JupyterFrontEndPlugin<IChatCommandRegistry> | JupyterFrontEndPlugin<IAIProviderRegistry>)[];
|
|
5
|
+
declare const _default: (JupyterFrontEndPlugin<void> | JupyterFrontEndPlugin<IChatCommandRegistry> | JupyterFrontEndPlugin<IAIProviderRegistry> | JupyterFrontEndPlugin<ISettingConnector>)[];
|
|
5
6
|
export default _default;
|
package/lib/index.js
CHANGED
|
@@ -1,19 +1,20 @@
|
|
|
1
|
-
import { ActiveCellManager, buildChatSidebar, buildErrorWidget, ChatCommandRegistry, IChatCommandRegistry } from '@jupyter/chat';
|
|
1
|
+
import { ActiveCellManager, buildChatSidebar, buildErrorWidget, ChatCommandRegistry, IChatCommandRegistry, InputToolbarRegistry } from '@jupyter/chat';
|
|
2
2
|
import { IThemeManager } from '@jupyterlab/apputils';
|
|
3
3
|
import { ICompletionProviderManager } from '@jupyterlab/completer';
|
|
4
4
|
import { INotebookTracker } from '@jupyterlab/notebook';
|
|
5
5
|
import { IRenderMimeRegistry } from '@jupyterlab/rendermime';
|
|
6
|
-
import { ISettingRegistry } from '@jupyterlab/settingregistry';
|
|
6
|
+
import { ISettingConnector, ISettingRegistry } from '@jupyterlab/settingregistry';
|
|
7
7
|
import { IFormRendererRegistry } from '@jupyterlab/ui-components';
|
|
8
|
-
import { ISecretsManager } from 'jupyter-secrets-manager';
|
|
8
|
+
import { ISecretsManager, SecretsManager } from 'jupyter-secrets-manager';
|
|
9
9
|
import { ChatHandler } from './chat-handler';
|
|
10
10
|
import { CompletionProvider } from './completion-provider';
|
|
11
11
|
import { defaultProviderPlugins } from './default-providers';
|
|
12
12
|
import { AIProviderRegistry } from './provider';
|
|
13
|
-
import { aiSettingsRenderer } from './settings
|
|
14
|
-
import { IAIProviderRegistry } from './tokens';
|
|
13
|
+
import { aiSettingsRenderer, SettingConnector } from './settings';
|
|
14
|
+
import { IAIProviderRegistry, PLUGIN_IDS } from './tokens';
|
|
15
|
+
import { stopItem } from './components/stop-button';
|
|
15
16
|
const chatCommandRegistryPlugin = {
|
|
16
|
-
id:
|
|
17
|
+
id: PLUGIN_IDS.chatCommandRegistry,
|
|
17
18
|
description: 'Autocompletion registry',
|
|
18
19
|
autoStart: true,
|
|
19
20
|
provides: IChatCommandRegistry,
|
|
@@ -24,7 +25,7 @@ const chatCommandRegistryPlugin = {
|
|
|
24
25
|
}
|
|
25
26
|
};
|
|
26
27
|
const chatPlugin = {
|
|
27
|
-
id:
|
|
28
|
+
id: PLUGIN_IDS.chat,
|
|
28
29
|
description: 'LLM chat extension',
|
|
29
30
|
autoStart: true,
|
|
30
31
|
requires: [IAIProviderRegistry, IRenderMimeRegistry, IChatCommandRegistry],
|
|
@@ -66,12 +67,26 @@ const chatPlugin = {
|
|
|
66
67
|
console.error(`Something went wrong when reading the settings.\n${reason}`);
|
|
67
68
|
});
|
|
68
69
|
let chatWidget = null;
|
|
70
|
+
const inputToolbarRegistry = InputToolbarRegistry.defaultToolbarRegistry();
|
|
71
|
+
const stopButton = stopItem(() => chatHandler.stopStreaming());
|
|
72
|
+
inputToolbarRegistry.addItem('stop', stopButton);
|
|
73
|
+
chatHandler.writersChanged.connect((_, users) => {
|
|
74
|
+
if (users.filter(user => user.username === chatHandler.personaName).length) {
|
|
75
|
+
inputToolbarRegistry.hide('send');
|
|
76
|
+
inputToolbarRegistry.show('stop');
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
inputToolbarRegistry.hide('stop');
|
|
80
|
+
inputToolbarRegistry.show('send');
|
|
81
|
+
}
|
|
82
|
+
});
|
|
69
83
|
try {
|
|
70
84
|
chatWidget = buildChatSidebar({
|
|
71
85
|
model: chatHandler,
|
|
72
86
|
themeManager,
|
|
73
87
|
rmRegistry,
|
|
74
|
-
chatCommandRegistry
|
|
88
|
+
chatCommandRegistry,
|
|
89
|
+
inputToolbarRegistry
|
|
75
90
|
});
|
|
76
91
|
chatWidget.title.caption = 'Jupyterlite AI Chat';
|
|
77
92
|
}
|
|
@@ -83,7 +98,7 @@ const chatPlugin = {
|
|
|
83
98
|
}
|
|
84
99
|
};
|
|
85
100
|
const completerPlugin = {
|
|
86
|
-
id:
|
|
101
|
+
id: PLUGIN_IDS.completer,
|
|
87
102
|
autoStart: true,
|
|
88
103
|
requires: [IAIProviderRegistry, ICompletionProviderManager],
|
|
89
104
|
activate: (app, providerRegistry, manager) => {
|
|
@@ -94,15 +109,24 @@ const completerPlugin = {
|
|
|
94
109
|
manager.registerInlineProvider(completer);
|
|
95
110
|
}
|
|
96
111
|
};
|
|
97
|
-
const providerRegistryPlugin = {
|
|
98
|
-
id:
|
|
112
|
+
const providerRegistryPlugin = SecretsManager.sign(PLUGIN_IDS.providerRegistry, token => ({
|
|
113
|
+
id: PLUGIN_IDS.providerRegistry,
|
|
99
114
|
autoStart: true,
|
|
100
115
|
requires: [IFormRendererRegistry, ISettingRegistry],
|
|
101
|
-
optional: [IRenderMimeRegistry, ISecretsManager],
|
|
116
|
+
optional: [IRenderMimeRegistry, ISecretsManager, ISettingConnector],
|
|
102
117
|
provides: IAIProviderRegistry,
|
|
103
|
-
activate: (app, editorRegistry, settingRegistry, rmRegistry, secretsManager) => {
|
|
104
|
-
const providerRegistry = new AIProviderRegistry(
|
|
105
|
-
|
|
118
|
+
activate: (app, editorRegistry, settingRegistry, rmRegistry, secretsManager, settingConnector) => {
|
|
119
|
+
const providerRegistry = new AIProviderRegistry({
|
|
120
|
+
token,
|
|
121
|
+
secretsManager
|
|
122
|
+
});
|
|
123
|
+
editorRegistry.addRenderer(`${PLUGIN_IDS.providerRegistry}.AIprovider`, aiSettingsRenderer({
|
|
124
|
+
providerRegistry,
|
|
125
|
+
secretsToken: token,
|
|
126
|
+
rmRegistry,
|
|
127
|
+
secretsManager,
|
|
128
|
+
settingConnector
|
|
129
|
+
}));
|
|
106
130
|
settingRegistry
|
|
107
131
|
.load(providerRegistryPlugin.id)
|
|
108
132
|
.then(settings => {
|
|
@@ -112,7 +136,10 @@ const providerRegistryPlugin = {
|
|
|
112
136
|
const providerSettings = ((_a = settings.get('AIprovider').composite) !== null && _a !== void 0 ? _a : {
|
|
113
137
|
provider: 'None'
|
|
114
138
|
});
|
|
115
|
-
providerRegistry.setProvider(
|
|
139
|
+
providerRegistry.setProvider({
|
|
140
|
+
name: providerSettings.provider,
|
|
141
|
+
settings: providerSettings
|
|
142
|
+
});
|
|
116
143
|
};
|
|
117
144
|
settings.changed.connect(() => updateProvider());
|
|
118
145
|
updateProvider();
|
|
@@ -122,11 +149,24 @@ const providerRegistryPlugin = {
|
|
|
122
149
|
});
|
|
123
150
|
return providerRegistry;
|
|
124
151
|
}
|
|
152
|
+
}));
|
|
153
|
+
/**
|
|
154
|
+
* Provides the settings connector as a separate plugin to allow for alternative
|
|
155
|
+
* implementations that may want to fetch settings from a different source or
|
|
156
|
+
* endpoint.
|
|
157
|
+
*/
|
|
158
|
+
const settingsConnector = {
|
|
159
|
+
id: PLUGIN_IDS.settingsConnector,
|
|
160
|
+
description: 'Provides a settings connector which does not save passwords.',
|
|
161
|
+
autoStart: true,
|
|
162
|
+
provides: ISettingConnector,
|
|
163
|
+
activate: (app) => new SettingConnector(app.serviceManager.settings)
|
|
125
164
|
};
|
|
126
165
|
export default [
|
|
127
166
|
providerRegistryPlugin,
|
|
128
167
|
chatCommandRegistryPlugin,
|
|
129
168
|
chatPlugin,
|
|
130
169
|
completerPlugin,
|
|
170
|
+
settingsConnector,
|
|
131
171
|
...defaultProviderPlugins
|
|
132
172
|
];
|
package/lib/provider.d.ts
CHANGED
|
@@ -1,14 +1,18 @@
|
|
|
1
|
-
import { ICompletionProviderManager } from '@jupyterlab/completer';
|
|
2
1
|
import { BaseLanguageModel } from '@langchain/core/language_models/base';
|
|
3
2
|
import { BaseChatModel } from '@langchain/core/language_models/chat_models';
|
|
4
3
|
import { ISignal } from '@lumino/signaling';
|
|
5
4
|
import { ReadonlyPartialJSONObject } from '@lumino/coreutils';
|
|
6
|
-
import { IBaseCompleter } from './base-completer';
|
|
7
|
-
import { IAIProvider, IAIProviderRegistry } from './tokens';
|
|
8
5
|
import { JSONSchema7 } from 'json-schema';
|
|
6
|
+
import { ISecretsManager } from 'jupyter-secrets-manager';
|
|
7
|
+
import { IBaseCompleter } from './base-completer';
|
|
8
|
+
import { IAIProvider, IAIProviderRegistry, ISetProviderOptions } from './tokens';
|
|
9
9
|
export declare const chatSystemPrompt: (options: AIProviderRegistry.IPromptOptions) => string;
|
|
10
10
|
export declare const COMPLETION_SYSTEM_PROMPT = "\nYou are an application built to provide helpful code completion suggestions.\nYou should only produce code. Keep comments to minimum, use the\nprogramming language comment syntax. Produce clean code.\nThe code is written in JupyterLab, a data analysis and code development\nenvironment which can execute code extended with additional syntax for\ninteractive 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 correspond to what a human users\nwould write.\nDo not include the prompt in the output, only the string that should be appended to the current input.\n";
|
|
11
11
|
export declare class AIProviderRegistry implements IAIProviderRegistry {
|
|
12
|
+
/**
|
|
13
|
+
* The constructor of the provider registry.
|
|
14
|
+
*/
|
|
15
|
+
constructor(options: AIProviderRegistry.IOptions);
|
|
12
16
|
/**
|
|
13
17
|
* Get the list of provider names.
|
|
14
18
|
*/
|
|
@@ -53,14 +57,14 @@ export declare class AIProviderRegistry implements IAIProviderRegistry {
|
|
|
53
57
|
* Set the providers (chat model and completer).
|
|
54
58
|
* Creates the providers if the name has changed, otherwise only updates their config.
|
|
55
59
|
*
|
|
56
|
-
* @param
|
|
57
|
-
* @param settings - the settings for the models.
|
|
60
|
+
* @param options - An object with the name and the settings of the provider to use.
|
|
58
61
|
*/
|
|
59
|
-
setProvider(
|
|
62
|
+
setProvider(options: ISetProviderOptions): Promise<void>;
|
|
60
63
|
/**
|
|
61
64
|
* A signal emitting when the provider or its settings has changed.
|
|
62
65
|
*/
|
|
63
66
|
get providerChanged(): ISignal<IAIProviderRegistry, void>;
|
|
67
|
+
private _secretsManager;
|
|
64
68
|
private _currentProvider;
|
|
65
69
|
private _completer;
|
|
66
70
|
private _chatModel;
|
|
@@ -69,6 +73,7 @@ export declare class AIProviderRegistry implements IAIProviderRegistry {
|
|
|
69
73
|
private _chatError;
|
|
70
74
|
private _completerError;
|
|
71
75
|
private _providers;
|
|
76
|
+
private _deferredProvider;
|
|
72
77
|
}
|
|
73
78
|
export declare namespace AIProviderRegistry {
|
|
74
79
|
/**
|
|
@@ -76,13 +81,13 @@ export declare namespace AIProviderRegistry {
|
|
|
76
81
|
*/
|
|
77
82
|
interface IOptions {
|
|
78
83
|
/**
|
|
79
|
-
* The
|
|
84
|
+
* The secrets manager used in the application.
|
|
80
85
|
*/
|
|
81
|
-
|
|
86
|
+
secretsManager?: ISecretsManager;
|
|
82
87
|
/**
|
|
83
|
-
* The
|
|
88
|
+
* The token used to request the secrets manager.
|
|
84
89
|
*/
|
|
85
|
-
|
|
90
|
+
token: symbol;
|
|
86
91
|
}
|
|
87
92
|
/**
|
|
88
93
|
* The options for the Chat system prompt.
|
package/lib/provider.js
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import { Signal } from '@lumino/signaling';
|
|
2
|
+
import { getSecretId, SECRETS_REPLACEMENT } from './settings';
|
|
3
|
+
import { PLUGIN_IDS } from './tokens';
|
|
4
|
+
const SECRETS_NAMESPACE = PLUGIN_IDS.providerRegistry;
|
|
2
5
|
export const chatSystemPrompt = (options) => `
|
|
3
6
|
You are Jupyternaut, a conversational assistant living in JupyterLab to help users.
|
|
4
7
|
You are not a language model, but rather an application built on a foundation model from ${options.provider_name}.
|
|
@@ -26,7 +29,10 @@ would write.
|
|
|
26
29
|
Do not include the prompt in the output, only the string that should be appended to the current input.
|
|
27
30
|
`;
|
|
28
31
|
export class AIProviderRegistry {
|
|
29
|
-
|
|
32
|
+
/**
|
|
33
|
+
* The constructor of the provider registry.
|
|
34
|
+
*/
|
|
35
|
+
constructor(options) {
|
|
30
36
|
this._currentProvider = null;
|
|
31
37
|
this._completer = null;
|
|
32
38
|
this._chatModel = null;
|
|
@@ -35,6 +41,9 @@ export class AIProviderRegistry {
|
|
|
35
41
|
this._chatError = '';
|
|
36
42
|
this._completerError = '';
|
|
37
43
|
this._providers = new Map();
|
|
44
|
+
this._deferredProvider = null;
|
|
45
|
+
this._secretsManager = options.secretsManager || null;
|
|
46
|
+
Private.setToken(options.token);
|
|
38
47
|
}
|
|
39
48
|
/**
|
|
40
49
|
* Get the list of provider names.
|
|
@@ -46,10 +55,15 @@ export class AIProviderRegistry {
|
|
|
46
55
|
* Add a new provider.
|
|
47
56
|
*/
|
|
48
57
|
add(provider) {
|
|
58
|
+
var _a;
|
|
49
59
|
if (this._providers.has(provider.name)) {
|
|
50
60
|
throw new Error(`A AI provider named '${provider.name}' is already registered`);
|
|
51
61
|
}
|
|
52
62
|
this._providers.set(provider.name, provider);
|
|
63
|
+
// Set the provider if the loading has been deferred.
|
|
64
|
+
if (provider.name === ((_a = this._deferredProvider) === null || _a === void 0 ? void 0 : _a.name)) {
|
|
65
|
+
this.setProvider(this._deferredProvider);
|
|
66
|
+
}
|
|
53
67
|
}
|
|
54
68
|
/**
|
|
55
69
|
* Get the current provider name.
|
|
@@ -119,15 +133,36 @@ export class AIProviderRegistry {
|
|
|
119
133
|
* Set the providers (chat model and completer).
|
|
120
134
|
* Creates the providers if the name has changed, otherwise only updates their config.
|
|
121
135
|
*
|
|
122
|
-
* @param
|
|
123
|
-
* @param settings - the settings for the models.
|
|
136
|
+
* @param options - An object with the name and the settings of the provider to use.
|
|
124
137
|
*/
|
|
125
|
-
setProvider(
|
|
126
|
-
var _a, _b, _c;
|
|
138
|
+
async setProvider(options) {
|
|
139
|
+
var _a, _b, _c, _d;
|
|
140
|
+
const { name, settings } = options;
|
|
127
141
|
this._currentProvider = (_a = this._providers.get(name)) !== null && _a !== void 0 ? _a : null;
|
|
128
|
-
if (
|
|
142
|
+
if (this._currentProvider === null) {
|
|
143
|
+
// The current provider may not be loaded when the settings are first loaded.
|
|
144
|
+
// Let's defer the provider loading.
|
|
145
|
+
this._deferredProvider = options;
|
|
146
|
+
}
|
|
147
|
+
else {
|
|
148
|
+
this._deferredProvider = null;
|
|
149
|
+
}
|
|
150
|
+
// Build a new settings object containing the secrets.
|
|
151
|
+
const fullSettings = {};
|
|
152
|
+
for (const key of Object.keys(settings)) {
|
|
153
|
+
if (settings[key] === SECRETS_REPLACEMENT) {
|
|
154
|
+
const id = getSecretId(name, key);
|
|
155
|
+
const secrets = await ((_b = this._secretsManager) === null || _b === void 0 ? void 0 : _b.get(Private.getToken(), SECRETS_NAMESPACE, id));
|
|
156
|
+
fullSettings[key] = (secrets === null || secrets === void 0 ? void 0 : secrets.value) || settings[key];
|
|
157
|
+
continue;
|
|
158
|
+
}
|
|
159
|
+
fullSettings[key] = settings[key];
|
|
160
|
+
}
|
|
161
|
+
if (((_c = this._currentProvider) === null || _c === void 0 ? void 0 : _c.completer) !== undefined) {
|
|
129
162
|
try {
|
|
130
|
-
this._completer = new this._currentProvider.completer({
|
|
163
|
+
this._completer = new this._currentProvider.completer({
|
|
164
|
+
...fullSettings
|
|
165
|
+
});
|
|
131
166
|
this._completerError = '';
|
|
132
167
|
}
|
|
133
168
|
catch (e) {
|
|
@@ -137,9 +172,11 @@ export class AIProviderRegistry {
|
|
|
137
172
|
else {
|
|
138
173
|
this._completer = null;
|
|
139
174
|
}
|
|
140
|
-
if (((
|
|
175
|
+
if (((_d = this._currentProvider) === null || _d === void 0 ? void 0 : _d.chatModel) !== undefined) {
|
|
141
176
|
try {
|
|
142
|
-
this._chatModel = new this._currentProvider.chatModel({
|
|
177
|
+
this._chatModel = new this._currentProvider.chatModel({
|
|
178
|
+
...fullSettings
|
|
179
|
+
});
|
|
143
180
|
this._chatError = '';
|
|
144
181
|
}
|
|
145
182
|
catch (e) {
|
|
@@ -197,3 +234,24 @@ export class AIProviderRegistry {
|
|
|
197
234
|
}
|
|
198
235
|
AIProviderRegistry.updateConfig = updateConfig;
|
|
199
236
|
})(AIProviderRegistry || (AIProviderRegistry = {}));
|
|
237
|
+
var Private;
|
|
238
|
+
(function (Private) {
|
|
239
|
+
/**
|
|
240
|
+
* The token to use with the secrets manager.
|
|
241
|
+
*/
|
|
242
|
+
let secretsToken;
|
|
243
|
+
/**
|
|
244
|
+
* Set of the token.
|
|
245
|
+
*/
|
|
246
|
+
function setToken(value) {
|
|
247
|
+
secretsToken = value;
|
|
248
|
+
}
|
|
249
|
+
Private.setToken = setToken;
|
|
250
|
+
/**
|
|
251
|
+
* get the token.
|
|
252
|
+
*/
|
|
253
|
+
function getToken() {
|
|
254
|
+
return secretsToken;
|
|
255
|
+
}
|
|
256
|
+
Private.getToken = getToken;
|
|
257
|
+
})(Private || (Private = {}));
|
package/lib/settings/panel.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { IRenderMimeRegistry } from '@jupyterlab/rendermime';
|
|
2
|
+
import { ISettingConnector } from '@jupyterlab/settingregistry';
|
|
2
3
|
import { IFormRenderer } from '@jupyterlab/ui-components';
|
|
3
4
|
import type { FieldProps } from '@rjsf/utils';
|
|
4
5
|
import { JSONSchema7 } from 'json-schema';
|
|
@@ -7,8 +8,10 @@ import React from 'react';
|
|
|
7
8
|
import { IAIProviderRegistry, IDict } from '../tokens';
|
|
8
9
|
export declare const aiSettingsRenderer: (options: {
|
|
9
10
|
providerRegistry: IAIProviderRegistry;
|
|
11
|
+
secretsToken?: symbol;
|
|
10
12
|
rmRegistry?: IRenderMimeRegistry;
|
|
11
13
|
secretsManager?: ISecretsManager;
|
|
14
|
+
settingConnector?: ISettingConnector;
|
|
12
15
|
}) => IFormRenderer;
|
|
13
16
|
export interface ISettingsFormStates {
|
|
14
17
|
schema: JSONSchema7;
|
|
@@ -17,6 +20,7 @@ export interface ISettingsFormStates {
|
|
|
17
20
|
export declare class AiSettings extends React.Component<FieldProps, ISettingsFormStates> {
|
|
18
21
|
constructor(props: FieldProps);
|
|
19
22
|
componentDidUpdate(): Promise<void>;
|
|
23
|
+
componentWillUnmount(): void;
|
|
20
24
|
/**
|
|
21
25
|
* Get the current provider from the local storage.
|
|
22
26
|
*/
|
|
@@ -34,11 +38,6 @@ export declare class AiSettings extends React.Component<FieldProps, ISettingsFor
|
|
|
34
38
|
*/
|
|
35
39
|
saveSettings(value: IDict<any>): void;
|
|
36
40
|
private updateUseSecretsManager;
|
|
37
|
-
/**
|
|
38
|
-
* Update the UI schema of the form.
|
|
39
|
-
* Currently use to hide API keys.
|
|
40
|
-
*/
|
|
41
|
-
private _updateUiSchema;
|
|
42
41
|
/**
|
|
43
42
|
* Build the schema for a given provider.
|
|
44
43
|
*/
|
|
@@ -73,8 +72,10 @@ export declare class AiSettings extends React.Component<FieldProps, ISettingsFor
|
|
|
73
72
|
private _provider;
|
|
74
73
|
private _providerSchema;
|
|
75
74
|
private _useSecretsManager;
|
|
75
|
+
private _hideSecretFields;
|
|
76
76
|
private _rmRegistry;
|
|
77
77
|
private _secretsManager;
|
|
78
|
+
private _settingConnector;
|
|
78
79
|
private _currentSettings;
|
|
79
80
|
private _uiSchema;
|
|
80
81
|
private _settings;
|