@jupyter/chat 0.8.0 → 0.9.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 (54) hide show
  1. package/lib/components/chat-input.d.ts +3 -11
  2. package/lib/components/chat-input.js +26 -40
  3. package/lib/components/chat-messages.d.ts +17 -4
  4. package/lib/components/chat-messages.js +9 -9
  5. package/lib/components/chat.d.ts +5 -5
  6. package/lib/components/chat.js +9 -8
  7. package/lib/components/code-blocks/copy-button.js +6 -3
  8. package/lib/components/input/buttons/attach-button.d.ts +6 -0
  9. package/lib/components/input/{attach-button.js → buttons/attach-button.js} +11 -8
  10. package/lib/components/input/buttons/cancel-button.d.ts +6 -0
  11. package/lib/components/input/{cancel-button.js → buttons/cancel-button.js} +5 -7
  12. package/lib/components/input/buttons/index.d.ts +3 -0
  13. package/lib/components/input/buttons/index.js +7 -0
  14. package/lib/components/input/buttons/send-button.d.ts +6 -0
  15. package/lib/components/input/{send-button.js → buttons/send-button.js} +52 -42
  16. package/lib/components/input/index.d.ts +3 -3
  17. package/lib/components/input/index.js +3 -3
  18. package/lib/components/input/toolbar-registry.d.ts +98 -0
  19. package/lib/components/input/toolbar-registry.js +85 -0
  20. package/lib/components/input/use-chat-commands.js +3 -2
  21. package/lib/components/mui-extras/tooltipped-button.d.ts +1 -1
  22. package/lib/components/mui-extras/tooltipped-button.js +3 -2
  23. package/lib/components/mui-extras/tooltipped-icon-button.js +4 -2
  24. package/lib/input-model.d.ts +41 -0
  25. package/lib/input-model.js +17 -1
  26. package/lib/model.d.ts +22 -0
  27. package/lib/model.js +18 -2
  28. package/lib/types.d.ts +0 -18
  29. package/lib/widgets/chat-widget.d.ts +5 -1
  30. package/lib/widgets/chat-widget.js +7 -1
  31. package/package.json +1 -1
  32. package/src/components/chat-input.tsx +40 -65
  33. package/src/components/chat-messages.tsx +31 -14
  34. package/src/components/chat.tsx +12 -21
  35. package/src/components/code-blocks/copy-button.tsx +9 -3
  36. package/src/components/input/{attach-button.tsx → buttons/attach-button.tsx} +15 -20
  37. package/src/components/input/{cancel-button.tsx → buttons/cancel-button.tsx} +9 -16
  38. package/src/components/input/buttons/index.ts +8 -0
  39. package/src/components/input/{send-button.tsx → buttons/send-button.tsx} +62 -61
  40. package/src/components/input/index.ts +3 -3
  41. package/src/components/input/toolbar-registry.tsx +162 -0
  42. package/src/components/input/use-chat-commands.tsx +8 -2
  43. package/src/components/mui-extras/tooltipped-button.tsx +4 -2
  44. package/src/components/mui-extras/tooltipped-icon-button.tsx +5 -2
  45. package/src/input-model.ts +58 -1
  46. package/src/model.ts +36 -2
  47. package/src/types.ts +0 -21
  48. package/src/widgets/chat-widget.tsx +8 -1
  49. package/style/base.css +1 -0
  50. package/style/chat.css +10 -0
  51. package/style/input.css +32 -0
  52. package/lib/components/input/attach-button.d.ts +0 -14
  53. package/lib/components/input/cancel-button.d.ts +0 -11
  54. package/lib/components/input/send-button.d.ts +0 -18
@@ -8,36 +8,29 @@ import SendIcon from '@mui/icons-material/Send';
8
8
  import { Box, Menu, MenuItem, Typography } from '@mui/material';
9
9
  import React, { useCallback, useEffect, useState } from 'react';
10
10
 
11
- import { TooltippedButton } from '../mui-extras/tooltipped-button';
12
- import { includeSelectionIcon } from '../../icons';
13
- import { IInputModel } from '../../input-model';
14
- import { Selection } from '../../types';
11
+ import { InputToolbarRegistry } from '../toolbar-registry';
12
+ import { TooltippedButton } from '../../mui-extras/tooltipped-button';
13
+ import { includeSelectionIcon } from '../../../icons';
14
+ import { IInputModel, InputModel } from '../../../input-model';
15
15
 
16
16
  const SEND_BUTTON_CLASS = 'jp-chat-send-button';
17
17
  const SEND_INCLUDE_OPENER_CLASS = 'jp-chat-send-include-opener';
18
18
  const SEND_INCLUDE_LI_CLASS = 'jp-chat-send-include';
19
19
 
20
- /**
21
- * The send button props.
22
- */
23
- export type SendButtonProps = {
24
- model: IInputModel;
25
- sendWithShiftEnter: boolean;
26
- inputExists: boolean;
27
- onSend: (selection?: Selection) => unknown;
28
- hideIncludeSelection?: boolean;
29
- hasButtonOnLeft?: boolean;
30
- };
31
-
32
20
  /**
33
21
  * The send button, with optional 'include selection' menu.
34
22
  */
35
- export function SendButton(props: SendButtonProps): JSX.Element {
36
- const { activeCellManager, selectionWatcher } = props.model;
37
- const hideIncludeSelection = props.hideIncludeSelection ?? false;
38
- const hasButtonOnLeft = props.hasButtonOnLeft ?? false;
23
+ export function SendButton(
24
+ props: InputToolbarRegistry.IToolbarItemProps
25
+ ): JSX.Element {
26
+ const { model } = props;
27
+ const { activeCellManager, selectionWatcher } = model;
28
+ const hideIncludeSelection = !activeCellManager || !selectionWatcher;
29
+
39
30
  const [menuAnchorEl, setMenuAnchorEl] = useState<HTMLElement | null>(null);
40
31
  const [menuOpen, setMenuOpen] = useState(false);
32
+ const [disabled, setDisabled] = useState(false);
33
+ const [tooltip, setTooltip] = useState<string>('');
41
34
 
42
35
  const openMenu = useCallback((el: HTMLElement | null) => {
43
36
  setMenuAnchorEl(el);
@@ -48,11 +41,36 @@ export function SendButton(props: SendButtonProps): JSX.Element {
48
41
  setMenuOpen(false);
49
42
  }, []);
50
43
 
51
- const disabled = !props.inputExists;
52
-
53
44
  const [selectionTooltip, setSelectionTooltip] = useState<string>('');
54
45
  const [disableInclude, setDisableInclude] = useState<boolean>(true);
55
46
 
47
+ useEffect(() => {
48
+ const inputChanged = () => {
49
+ const inputExist = !!model.value.trim() || model.attachments.length;
50
+ setDisabled(!inputExist);
51
+ };
52
+
53
+ model.valueChanged.connect(inputChanged);
54
+ model.attachmentsChanged?.connect(inputChanged);
55
+
56
+ inputChanged();
57
+
58
+ const configChanged = (_: IInputModel, config: InputModel.IConfig) => {
59
+ setTooltip(
60
+ (config.sendWithShiftEnter ?? false)
61
+ ? 'Send message (SHIFT+ENTER)'
62
+ : 'Send message (ENTER)'
63
+ );
64
+ };
65
+ model.configChanged.connect(configChanged);
66
+
67
+ return () => {
68
+ model.valueChanged.disconnect(inputChanged);
69
+ model.attachmentsChanged?.disconnect(inputChanged);
70
+ model.configChanged?.disconnect(configChanged);
71
+ };
72
+ }, [model]);
73
+
56
74
  useEffect(() => {
57
75
  /**
58
76
  * Enable or disable the include selection button, and adapt the tooltip.
@@ -78,55 +96,44 @@ export function SendButton(props: SendButtonProps): JSX.Element {
78
96
  selectionWatcher?.selectionChanged.disconnect(toggleIncludeState);
79
97
  activeCellManager?.availabilityChanged.disconnect(toggleIncludeState);
80
98
  };
81
- }, [activeCellManager, selectionWatcher, hideIncludeSelection]);
82
-
83
- const defaultTooltip = props.sendWithShiftEnter
84
- ? 'Send message (SHIFT+ENTER)'
85
- : 'Send message (ENTER)';
86
- const tooltip = defaultTooltip;
99
+ }, [activeCellManager, selectionWatcher]);
87
100
 
88
101
  function sendWithSelection() {
89
- // Append the selected text if exists.
102
+ let source = '';
103
+
90
104
  if (selectionWatcher?.selection) {
91
- props.onSend({
92
- type: 'text',
93
- source: selectionWatcher.selection.text
94
- });
95
- closeMenu();
96
- return;
105
+ // Append the selected text if exists.
106
+ source = selectionWatcher.selection.text;
107
+ } else if (activeCellManager?.available) {
108
+ // Append the active cell content if exists.
109
+ source = activeCellManager.getContent(false)!.source;
97
110
  }
111
+ let content = model.value;
112
+ if (source) {
113
+ content += `
98
114
 
99
- // Append the active cell content if exists.
100
- if (activeCellManager?.available) {
101
- props.onSend({
102
- type: 'cell',
103
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
104
- source: activeCellManager.getContent(false)!.source
105
- });
106
- closeMenu();
107
- return;
115
+ \`\`\`
116
+ ${source}
117
+ \`\`\`
118
+ `;
108
119
  }
120
+ model.send(content);
121
+ closeMenu();
122
+ model.value = '';
109
123
  }
110
124
 
111
125
  return (
112
- <Box sx={{ display: 'flex', flexWrap: 'nowrap' }}>
126
+ <>
113
127
  <TooltippedButton
114
- onClick={() => props.onSend()}
128
+ onClick={() => model.send(model.value)}
115
129
  disabled={disabled}
116
130
  tooltip={tooltip}
117
131
  buttonProps={{
118
132
  size: 'small',
119
- title: defaultTooltip,
133
+ title: tooltip,
120
134
  variant: 'contained',
121
135
  className: SEND_BUTTON_CLASS
122
136
  }}
123
- sx={{
124
- minWidth: 'unset',
125
- borderTopLeftRadius: hasButtonOnLeft ? '0px' : '2px',
126
- borderTopRightRadius: hideIncludeSelection ? '2px' : '0px',
127
- borderBottomRightRadius: hideIncludeSelection ? '2px' : '0px',
128
- borderBottomLeftRadius: hasButtonOnLeft ? '0px' : '2px'
129
- }}
130
137
  >
131
138
  <SendIcon />
132
139
  </TooltippedButton>
@@ -151,12 +158,6 @@ export function SendButton(props: SendButtonProps): JSX.Element {
151
158
  },
152
159
  className: SEND_INCLUDE_OPENER_CLASS
153
160
  }}
154
- sx={{
155
- minWidth: 'unset',
156
- padding: '4px 0px',
157
- borderRadius: '0px 2px 2px 0px',
158
- marginLeft: '1px'
159
- }}
160
161
  >
161
162
  <KeyboardArrowDown />
162
163
  </TooltippedButton>
@@ -205,6 +206,6 @@ export function SendButton(props: SendButtonProps): JSX.Element {
205
206
  </Menu>
206
207
  </>
207
208
  )}
208
- </Box>
209
+ </>
209
210
  );
210
211
  }
@@ -3,6 +3,6 @@
3
3
  * Distributed under the terms of the Modified BSD License.
4
4
  */
5
5
 
6
- export * from './attach-button';
7
- export * from './cancel-button';
8
- export * from './send-button';
6
+ export * from './buttons';
7
+ export * from './toolbar-registry';
8
+ export * from './use-chat-commands';
@@ -0,0 +1,162 @@
1
+ /*
2
+ * Copyright (c) Jupyter Development Team.
3
+ * Distributed under the terms of the Modified BSD License.
4
+ */
5
+ import * as React from 'react';
6
+
7
+ import { AttachButton, CancelButton, SendButton } from './buttons';
8
+ import { IInputModel } from '../../input-model';
9
+ import { ISignal, Signal } from '@lumino/signaling';
10
+
11
+ /**
12
+ * The toolbar registry interface.
13
+ */
14
+ export interface IInputToolbarRegistry {
15
+ /**
16
+ * A signal emitting when the items has changed.
17
+ */
18
+ readonly itemsChanged: ISignal<IInputToolbarRegistry, void>;
19
+ /**
20
+ * Get a toolbar item.
21
+ */
22
+ get(name: string): InputToolbarRegistry.IToolbarItem | undefined;
23
+
24
+ /**
25
+ * Get the list of the visible toolbar items in order.
26
+ */
27
+ getItems(): InputToolbarRegistry.IToolbarItem[];
28
+
29
+ /**
30
+ * Add a toolbar item.
31
+ */
32
+ addItem(name: string, item: InputToolbarRegistry.IToolbarItem): void;
33
+
34
+ /**
35
+ * Hide an element.
36
+ */
37
+ hide(name: string): void;
38
+
39
+ /**
40
+ * Show an element.
41
+ */
42
+ show(name: string): void;
43
+ }
44
+
45
+ /**
46
+ * The toolbar registry implementation.
47
+ */
48
+ export class InputToolbarRegistry implements IInputToolbarRegistry {
49
+ /**
50
+ * A signal emitting when the items has changed.
51
+ */
52
+ get itemsChanged(): ISignal<IInputToolbarRegistry, void> {
53
+ return this._itemsChanged;
54
+ }
55
+
56
+ /**
57
+ * Get a toolbar item.
58
+ */
59
+ get(name: string): InputToolbarRegistry.IToolbarItem | undefined {
60
+ return this._items.get(name);
61
+ }
62
+
63
+ /**
64
+ * Get the list of the visible toolbar items in order.
65
+ */
66
+ getItems(): InputToolbarRegistry.IToolbarItem[] {
67
+ return Array.from(this._items.values())
68
+ .filter(item => !item.hidden)
69
+ .sort((a, b) => a.position - b.position);
70
+ }
71
+
72
+ /**
73
+ * Add a toolbar item.
74
+ */
75
+ addItem(name: string, item: InputToolbarRegistry.IToolbarItem): void {
76
+ if (!this._items.has(name)) {
77
+ this._items.set(name, item);
78
+ this._itemsChanged.emit();
79
+ } else {
80
+ console.warn(`A chat input toolbar item '${name}' is already registered`);
81
+ }
82
+ }
83
+
84
+ /**
85
+ * Hide an element.
86
+ */
87
+ hide(name: string): void {
88
+ const item = this._items.get(name);
89
+ if (item) {
90
+ item.hidden = true;
91
+ this._itemsChanged.emit();
92
+ }
93
+ }
94
+
95
+ /**
96
+ * Show an element.
97
+ */
98
+ show(name: string): void {
99
+ const item = this._items.get(name);
100
+ if (item) {
101
+ item.hidden = false;
102
+ this._itemsChanged.emit();
103
+ }
104
+ }
105
+
106
+ private _items = new Map<string, InputToolbarRegistry.IToolbarItem>();
107
+ private _itemsChanged = new Signal<this, void>(this);
108
+ }
109
+
110
+ export namespace InputToolbarRegistry {
111
+ /**
112
+ * The toolbar item interface.
113
+ */
114
+ export interface IToolbarItem {
115
+ /**
116
+ * The react functional component with the button.
117
+ *
118
+ * NOTE:
119
+ * This component must be a TooltippedButton for a good integration in the toolbar.
120
+ */
121
+ element: React.FunctionComponent<IToolbarItemProps>;
122
+ /**
123
+ * The position of the button in the toolbar.
124
+ */
125
+ position: number;
126
+ /**
127
+ * Whether the button is hidden or not.
128
+ */
129
+ hidden?: boolean;
130
+ }
131
+
132
+ /**
133
+ * The toolbar item properties, send to the button.
134
+ */
135
+ export interface IToolbarItemProps {
136
+ /**
137
+ * The input model of the input component including the button.
138
+ */
139
+ model: IInputModel;
140
+ }
141
+
142
+ /**
143
+ * The default toolbar registry if none is provided.
144
+ */
145
+ export function defaultToolbarRegistry(): InputToolbarRegistry {
146
+ const registry = new InputToolbarRegistry();
147
+
148
+ registry.addItem('send', {
149
+ element: SendButton,
150
+ position: 100
151
+ });
152
+ registry.addItem('attach', {
153
+ element: AttachButton,
154
+ position: 20
155
+ });
156
+ registry.addItem('cancel', {
157
+ element: CancelButton,
158
+ position: 10
159
+ });
160
+ return registry;
161
+ }
162
+ }
@@ -144,8 +144,14 @@ export function useChatCommands(
144
144
  <Box key={key} component="li" {...listItemProps}>
145
145
  {commandIcon}
146
146
  <p className="jp-chat-command-name">{command.name}</p>
147
- <span> - </span>
148
- <p className="jp-chat-command-description">{command.description}</p>
147
+ {command.description && (
148
+ <>
149
+ <span> - </span>
150
+ <p className="jp-chat-command-description">
151
+ {command.description}
152
+ </p>
153
+ </>
154
+ )}
149
155
  </Box>
150
156
  );
151
157
  },
@@ -3,11 +3,13 @@
3
3
  * Distributed under the terms of the Modified BSD License.
4
4
  */
5
5
 
6
- import React from 'react';
7
6
  import { Button, ButtonProps, SxProps, TooltipProps } from '@mui/material';
7
+ import React from 'react';
8
8
 
9
9
  import { ContrastingTooltip } from './contrasting-tooltip';
10
10
 
11
+ const TOOLTIPPED_WRAP_CLASS = 'jp-chat-tooltipped-wrap';
12
+
11
13
  export type TooltippedButtonProps = {
12
14
  onClick: React.MouseEventHandler<HTMLButtonElement>;
13
15
  tooltip: string;
@@ -72,7 +74,7 @@ export function TooltippedButton(props: TooltippedButtonProps): JSX.Element {
72
74
 
73
75
  See: https://mui.com/material-ui/react-tooltip/#disabled-elements
74
76
  */}
75
- <span style={{ cursor: 'default' }}>
77
+ <span style={{ cursor: 'default' }} className={TOOLTIPPED_WRAP_CLASS}>
76
78
  <Button
77
79
  {...props.buttonProps}
78
80
  onClick={props.onClick}
@@ -3,11 +3,14 @@
3
3
  * Distributed under the terms of the Modified BSD License.
4
4
  */
5
5
 
6
- import React from 'react';
6
+ import { classes } from '@jupyterlab/ui-components';
7
7
  import { IconButton, IconButtonProps, TooltipProps } from '@mui/material';
8
+ import React from 'react';
8
9
 
9
10
  import { ContrastingTooltip } from './contrasting-tooltip';
10
11
 
12
+ const TOOLTIPPED_WRAP_CLASS = 'jp-chat-tooltipped-wrap';
13
+
11
14
  export type TooltippedIconButtonProps = {
12
15
  onClick: () => unknown;
13
16
  tooltip: string;
@@ -68,7 +71,7 @@ export function TooltippedIconButton(
68
71
 
69
72
  See: https://mui.com/material-ui/react-tooltip/#disabled-elements
70
73
  */}
71
- <span className={props.className}>
74
+ <span className={classes(props.className, TOOLTIPPED_WRAP_CLASS)}>
72
75
  <IconButton
73
76
  {...props.iconButtonProps}
74
77
  onClick={props.onClick}
@@ -8,6 +8,7 @@ import { ISignal, Signal } from '@lumino/signaling';
8
8
  import { IActiveCellManager } from './active-cell-manager';
9
9
  import { ISelectionWatcher } from './selection-watcher';
10
10
  import { IAttachment } from './types';
11
+ import { IDocumentManager } from '@jupyterlab/docmanager';
11
12
 
12
13
  const WHITESPACE = new Set([' ', '\n', '\t']);
13
14
 
@@ -15,6 +16,16 @@ const WHITESPACE = new Set([' ', '\n', '\t']);
15
16
  * The chat input interface.
16
17
  */
17
18
  export interface IInputModel extends IDisposable {
19
+ /**
20
+ * Function to send a message.
21
+ */
22
+ send: (content: string) => void;
23
+
24
+ /**
25
+ * Optional function to cancel edition.
26
+ */
27
+ cancel: (() => void) | undefined;
28
+
18
29
  /**
19
30
  * The entire input value.
20
31
  */
@@ -56,6 +67,11 @@ export interface IInputModel extends IDisposable {
56
67
  */
57
68
  readonly selectionWatcher: ISelectionWatcher | null;
58
69
 
70
+ /**
71
+ * Get the document manager.
72
+ */
73
+ readonly documentManager: IDocumentManager | null;
74
+
59
75
  /**
60
76
  * The input configuration.
61
77
  */
@@ -112,17 +128,32 @@ export interface IInputModel extends IDisposable {
112
128
  */
113
129
  export class InputModel implements IInputModel {
114
130
  constructor(options: InputModel.IOptions) {
131
+ this._onSend = options.onSend;
115
132
  this._value = options.value || '';
116
133
  this._attachments = options.attachments || [];
117
134
  this.cursorIndex = options.cursorIndex || this.value.length;
118
135
  this._activeCellManager = options.activeCellManager ?? null;
119
136
  this._selectionWatcher = options.selectionWatcher ?? null;
120
-
137
+ this._documentManager = options.documentManager ?? null;
121
138
  this._config = {
122
139
  ...options.config
123
140
  };
141
+ this.cancel = options.onCancel;
124
142
  }
125
143
 
144
+ /**
145
+ * Function to send a message.
146
+ */
147
+ send = (input: string): void => {
148
+ this._onSend(input, this);
149
+ this.value = '';
150
+ };
151
+
152
+ /**
153
+ * Optional function to cancel edition.
154
+ */
155
+ cancel: (() => void) | undefined;
156
+
126
157
  /**
127
158
  * The entire input value.
128
159
  */
@@ -199,6 +230,13 @@ export class InputModel implements IInputModel {
199
230
  return this._selectionWatcher;
200
231
  }
201
232
 
233
+ /**
234
+ * Get the document manager.
235
+ */
236
+ get documentManager(): IDocumentManager | null {
237
+ return this._documentManager;
238
+ }
239
+
202
240
  /**
203
241
  * The input configuration.
204
242
  */
@@ -314,12 +352,14 @@ export class InputModel implements IInputModel {
314
352
  return this._isDisposed;
315
353
  }
316
354
 
355
+ private _onSend: (input: string, model?: InputModel) => void;
317
356
  private _value: string;
318
357
  private _cursorIndex: number | null = null;
319
358
  private _currentWord: string | null = null;
320
359
  private _attachments: IAttachment[];
321
360
  private _activeCellManager: IActiveCellManager | null;
322
361
  private _selectionWatcher: ISelectionWatcher | null;
362
+ private _documentManager: IDocumentManager | null;
323
363
  private _config: InputModel.IConfig;
324
364
  private _valueChanged = new Signal<IInputModel, string>(this);
325
365
  private _cursorIndexChanged = new Signal<IInputModel, number | null>(this);
@@ -332,6 +372,18 @@ export class InputModel implements IInputModel {
332
372
 
333
373
  export namespace InputModel {
334
374
  export interface IOptions {
375
+ /**
376
+ * The function that should send the message.
377
+ * @param content - the content of the message.
378
+ * @param model - the model of the input sending the message.
379
+ */
380
+ onSend: (content: string, model?: InputModel) => void;
381
+
382
+ /**
383
+ * Function that should cancel the message edition.
384
+ */
385
+ onCancel?: () => void;
386
+
335
387
  /**
336
388
  * The initial value of the input.
337
389
  */
@@ -362,6 +414,11 @@ export namespace InputModel {
362
414
  * Selection watcher.
363
415
  */
364
416
  selectionWatcher?: ISelectionWatcher | null;
417
+
418
+ /**
419
+ * Document manager.
420
+ */
421
+ documentManager?: IDocumentManager | null;
365
422
  }
366
423
 
367
424
  export interface IConfig {
package/src/model.ts CHANGED
@@ -3,6 +3,7 @@
3
3
  * Distributed under the terms of the Modified BSD License.
4
4
  */
5
5
 
6
+ import { IDocumentManager } from '@jupyterlab/docmanager';
6
7
  import { CommandRegistry } from '@lumino/commands';
7
8
  import { IDisposable } from '@lumino/disposable';
8
9
  import { ISignal, Signal } from '@lumino/signaling';
@@ -67,6 +68,11 @@ export interface IChatModel extends IDisposable {
67
68
  */
68
69
  readonly selectionWatcher: ISelectionWatcher | null;
69
70
 
71
+ /**
72
+ * Get the selection watcher.
73
+ */
74
+ readonly documentManager: IDocumentManager | null;
75
+
70
76
  /**
71
77
  * A signal emitting when the messages list is updated.
72
78
  */
@@ -101,6 +107,11 @@ export interface IChatModel extends IDisposable {
101
107
  */
102
108
  sendMessage(message: INewMessage): Promise<boolean | void> | boolean | void;
103
109
 
110
+ /**
111
+ * Clear the message list.
112
+ */
113
+ clearMessages(): void;
114
+
104
115
  /**
105
116
  * Optional, to update a message from the chat panel.
106
117
  *
@@ -189,16 +200,18 @@ export class ChatModel implements IChatModel {
189
200
  this._inputModel = new InputModel({
190
201
  activeCellManager: options.activeCellManager,
191
202
  selectionWatcher: options.selectionWatcher,
203
+ documentManager: options.documentManager,
192
204
  config: {
193
205
  sendWithShiftEnter: config.sendWithShiftEnter
194
- }
206
+ },
207
+ onSend: (input: string) => this.sendMessage({ body: input })
195
208
  });
196
209
 
197
210
  this._commands = options.commands;
198
211
 
199
212
  this._activeCellManager = options.activeCellManager ?? null;
200
-
201
213
  this._selectionWatcher = options.selectionWatcher ?? null;
214
+ this._documentManager = options.documentManager ?? null;
202
215
  }
203
216
 
204
217
  /**
@@ -249,6 +262,13 @@ export class ChatModel implements IChatModel {
249
262
  return this._selectionWatcher;
250
263
  }
251
264
 
265
+ /**
266
+ * Get the document manager.
267
+ */
268
+ get documentManager(): IDocumentManager | null {
269
+ return this._documentManager;
270
+ }
271
+
252
272
  /**
253
273
  * Timestamp of the last read message in local storage.
254
274
  */
@@ -403,6 +423,14 @@ export class ChatModel implements IChatModel {
403
423
  */
404
424
  sendMessage(message: INewMessage): Promise<boolean | void> | boolean | void {}
405
425
 
426
+ /**
427
+ * Clear the message list.
428
+ */
429
+ clearMessages(): void {
430
+ this._messages = [];
431
+ this._messagesUpdated.emit();
432
+ }
433
+
406
434
  /**
407
435
  * Dispose the chat model.
408
436
  */
@@ -569,6 +597,7 @@ export class ChatModel implements IChatModel {
569
597
  private _commands?: CommandRegistry;
570
598
  private _activeCellManager: IActiveCellManager | null;
571
599
  private _selectionWatcher: ISelectionWatcher | null;
600
+ private _documentManager: IDocumentManager | null;
572
601
  private _notificationId: string | null = null;
573
602
  private _messagesUpdated = new Signal<IChatModel, void>(this);
574
603
  private _configChanged = new Signal<IChatModel, IConfig>(this);
@@ -609,5 +638,10 @@ export namespace ChatModel {
609
638
  * Selection watcher.
610
639
  */
611
640
  selectionWatcher?: ISelectionWatcher | null;
641
+
642
+ /**
643
+ * Document manager.
644
+ */
645
+ documentManager?: IDocumentManager | null;
612
646
  }
613
647
  }
package/src/types.ts CHANGED
@@ -94,24 +94,3 @@ export interface IAttachment {
94
94
  * An empty interface to describe optional settings that could be fetched from server.
95
95
  */
96
96
  export interface ISettings {} /* eslint-disable-line @typescript-eslint/no-empty-object-type */
97
-
98
- /**
99
- * Representation of a selected text.
100
- */
101
- export type TextSelection = {
102
- type: 'text';
103
- source: string;
104
- };
105
-
106
- /**
107
- * Representation of a selected cell.
108
- */
109
- export type CellSelection = {
110
- type: 'cell';
111
- source: string;
112
- };
113
-
114
- /**
115
- * Selection object (text or cell).
116
- */
117
- export type Selection = TextSelection | CellSelection;