diff --git a/schema/chat.json b/schema/chat.json index 0e79f64..e96a484 100644 --- a/schema/chat.json +++ b/schema/chat.json @@ -22,6 +22,12 @@ "title": "AI persona name", "description": "The name of the AI persona", "default": "Jupyternaut" + }, + "enableFileAttachment": { + "type": "boolean", + "title": "Enable file attachment support", + "default": false, + "description": "This allow you to sending attached files along with your message. ⚠️ This may send large content to the LLM, consuming many tokens." } }, "additionalProperties": false diff --git a/src/chat-handler.ts b/src/chat-handler.ts index 4d10fe5..ba2a9d3 100644 --- a/src/chat-handler.ts +++ b/src/chat-handler.ts @@ -39,12 +39,12 @@ export const welcomeMessage = (providers: string[]) => ` #### Ask JupyterLite AI -The provider to use can be set in the , by selecting it from -the _AI provider_ settings. +The provider to use can be set in the , by selecting it from +the _AI providers_ settings. The current providers that are available are _${providers.sort().join('_, _')}_. -To clear the chat, you can use the \`/clear\` command from the chat input. +- To clear the chat, you can use the \`/clear\` command from the chat input. `; export type ConnectionMessage = { diff --git a/src/index.ts b/src/index.ts index 06e870d..8fe94b1 100644 --- a/src/index.ts +++ b/src/index.ts @@ -20,6 +20,7 @@ import { ISettingRegistry } from '@jupyterlab/settingregistry'; import { IFormRendererRegistry } from '@jupyterlab/ui-components'; import { ReadonlyPartialJSONObject } from '@lumino/coreutils'; import { ISecretsManager, SecretsManager } from 'jupyter-secrets-manager'; +import { IDocumentManager } from '@jupyterlab/docmanager'; import { ChatHandler, welcomeMessage } from './chat-handler'; import { CompletionProvider } from './completion-provider'; @@ -50,7 +51,8 @@ const chatPlugin: JupyterFrontEndPlugin = { INotebookTracker, ISettingRegistry, IThemeManager, - ILayoutRestorer + ILayoutRestorer, + IDocumentManager ], activate: async ( app: JupyterFrontEnd, @@ -60,7 +62,8 @@ const chatPlugin: JupyterFrontEndPlugin = { notebookTracker: INotebookTracker | null, settingsRegistry: ISettingRegistry | null, themeManager: IThemeManager | null, - restorer: ILayoutRestorer | null + restorer: ILayoutRestorer | null, + docManager: IDocumentManager | null ) => { let activeCellManager: IActiveCellManager | null = null; if (notebookTracker) { @@ -72,22 +75,33 @@ const chatPlugin: JupyterFrontEndPlugin = { const chatHandler = new ChatHandler({ providerRegistry, - activeCellManager + activeCellManager, + documentManager: docManager ?? undefined }); let sendWithShiftEnter = false; let enableCodeToolbar = true; + let enableFileAttachment = false; let personaName = 'AI'; function loadSetting(setting: ISettingRegistry.ISettings): void { sendWithShiftEnter = setting.get('sendWithShiftEnter') - .composite as boolean; - enableCodeToolbar = setting.get('enableCodeToolbar').composite as boolean; - personaName = setting.get('personaName').composite as string; + ?.composite as boolean; + enableCodeToolbar = setting.get('enableCodeToolbar') + ?.composite as boolean; + personaName = setting.get('personaName')?.composite as string; + enableFileAttachment = setting.get('enableFileAttachment') + ?.composite as boolean; // set the properties chatHandler.config = { sendWithShiftEnter, enableCodeToolbar }; chatHandler.personaName = personaName; + + if (enableFileAttachment) { + inputToolbarRegistry.show('attach'); + } else { + inputToolbarRegistry.hide('attach'); + } } Promise.all([app.restored, settingsRegistry?.load(chatPlugin.id)])