@jupyter/chat 0.8.1 → 0.10.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 (69) hide show
  1. package/lib/__tests__/mocks.d.ts +9 -0
  2. package/lib/__tests__/mocks.js +18 -0
  3. package/lib/__tests__/model.spec.js +17 -10
  4. package/lib/__tests__/widgets.spec.js +4 -4
  5. package/lib/chat-commands/types.d.ts +2 -1
  6. package/lib/components/chat-input.d.ts +4 -12
  7. package/lib/components/chat-input.js +26 -40
  8. package/lib/components/chat-messages.d.ts +17 -4
  9. package/lib/components/chat-messages.js +28 -15
  10. package/lib/components/chat.d.ts +5 -5
  11. package/lib/components/chat.js +9 -8
  12. package/lib/components/code-blocks/copy-button.js +6 -3
  13. package/lib/components/input/buttons/attach-button.d.ts +6 -0
  14. package/lib/components/input/{attach-button.js → buttons/attach-button.js} +11 -8
  15. package/lib/components/input/buttons/cancel-button.d.ts +6 -0
  16. package/lib/components/input/{cancel-button.js → buttons/cancel-button.js} +5 -7
  17. package/lib/components/input/buttons/index.d.ts +3 -0
  18. package/lib/components/input/buttons/index.js +7 -0
  19. package/lib/components/input/buttons/send-button.d.ts +6 -0
  20. package/lib/components/input/{send-button.js → buttons/send-button.js} +52 -42
  21. package/lib/components/input/index.d.ts +3 -3
  22. package/lib/components/input/index.js +3 -3
  23. package/lib/components/input/toolbar-registry.d.ts +98 -0
  24. package/lib/components/input/toolbar-registry.js +85 -0
  25. package/lib/components/input/use-chat-commands.js +6 -5
  26. package/lib/components/mui-extras/tooltipped-button.d.ts +1 -1
  27. package/lib/components/mui-extras/tooltipped-button.js +3 -2
  28. package/lib/components/mui-extras/tooltipped-icon-button.js +4 -2
  29. package/lib/index.d.ts +1 -1
  30. package/lib/index.js +1 -1
  31. package/lib/input-model.d.ts +93 -1
  32. package/lib/input-model.js +55 -1
  33. package/lib/model.d.ts +76 -9
  34. package/lib/model.js +42 -12
  35. package/lib/types.d.ts +5 -18
  36. package/lib/utils.d.ts +15 -0
  37. package/lib/utils.js +29 -0
  38. package/lib/widgets/chat-widget.d.ts +5 -1
  39. package/lib/widgets/chat-widget.js +7 -1
  40. package/package.json +1 -1
  41. package/src/__tests__/mocks.ts +31 -0
  42. package/src/__tests__/model.spec.ts +21 -11
  43. package/src/__tests__/widgets.spec.ts +5 -4
  44. package/src/chat-commands/types.ts +1 -1
  45. package/src/components/chat-input.tsx +41 -66
  46. package/src/components/chat-messages.tsx +44 -17
  47. package/src/components/chat.tsx +12 -21
  48. package/src/components/code-blocks/copy-button.tsx +9 -3
  49. package/src/components/input/{attach-button.tsx → buttons/attach-button.tsx} +15 -20
  50. package/src/components/input/{cancel-button.tsx → buttons/cancel-button.tsx} +9 -16
  51. package/src/components/input/buttons/index.ts +8 -0
  52. package/src/components/input/{send-button.tsx → buttons/send-button.tsx} +62 -61
  53. package/src/components/input/index.ts +3 -3
  54. package/src/components/input/toolbar-registry.tsx +162 -0
  55. package/src/components/input/use-chat-commands.tsx +14 -6
  56. package/src/components/mui-extras/tooltipped-button.tsx +4 -2
  57. package/src/components/mui-extras/tooltipped-icon-button.tsx +5 -2
  58. package/src/index.ts +1 -1
  59. package/src/input-model.ts +140 -2
  60. package/src/model.ts +110 -12
  61. package/src/types.ts +5 -21
  62. package/src/utils.ts +34 -0
  63. package/src/widgets/chat-widget.tsx +8 -1
  64. package/style/base.css +1 -0
  65. package/style/chat.css +6 -0
  66. package/style/input.css +32 -0
  67. package/lib/components/input/attach-button.d.ts +0 -14
  68. package/lib/components/input/cancel-button.d.ts +0 -11
  69. package/lib/components/input/send-button.d.ts +0 -18
@@ -6,8 +6,8 @@ import KeyboardArrowDown from '@mui/icons-material/KeyboardArrowDown';
6
6
  import SendIcon from '@mui/icons-material/Send';
7
7
  import { Box, Menu, MenuItem, Typography } from '@mui/material';
8
8
  import React, { useCallback, useEffect, useState } from 'react';
9
- import { TooltippedButton } from '../mui-extras/tooltipped-button';
10
- import { includeSelectionIcon } from '../../icons';
9
+ import { TooltippedButton } from '../../mui-extras/tooltipped-button';
10
+ import { includeSelectionIcon } from '../../../icons';
11
11
  const SEND_BUTTON_CLASS = 'jp-chat-send-button';
12
12
  const SEND_INCLUDE_OPENER_CLASS = 'jp-chat-send-include-opener';
13
13
  const SEND_INCLUDE_LI_CLASS = 'jp-chat-send-include';
@@ -15,12 +15,13 @@ const SEND_INCLUDE_LI_CLASS = 'jp-chat-send-include';
15
15
  * The send button, with optional 'include selection' menu.
16
16
  */
17
17
  export function SendButton(props) {
18
- var _a, _b;
19
- const { activeCellManager, selectionWatcher } = props.model;
20
- const hideIncludeSelection = (_a = props.hideIncludeSelection) !== null && _a !== void 0 ? _a : false;
21
- const hasButtonOnLeft = (_b = props.hasButtonOnLeft) !== null && _b !== void 0 ? _b : false;
18
+ const { model } = props;
19
+ const { activeCellManager, selectionWatcher } = model;
20
+ const hideIncludeSelection = !activeCellManager || !selectionWatcher;
22
21
  const [menuAnchorEl, setMenuAnchorEl] = useState(null);
23
22
  const [menuOpen, setMenuOpen] = useState(false);
23
+ const [disabled, setDisabled] = useState(false);
24
+ const [tooltip, setTooltip] = useState('');
24
25
  const openMenu = useCallback((el) => {
25
26
  setMenuAnchorEl(el);
26
27
  setMenuOpen(true);
@@ -28,9 +29,31 @@ export function SendButton(props) {
28
29
  const closeMenu = useCallback(() => {
29
30
  setMenuOpen(false);
30
31
  }, []);
31
- const disabled = !props.inputExists;
32
32
  const [selectionTooltip, setSelectionTooltip] = useState('');
33
33
  const [disableInclude, setDisableInclude] = useState(true);
34
+ useEffect(() => {
35
+ var _a;
36
+ const inputChanged = () => {
37
+ const inputExist = !!model.value.trim() || model.attachments.length;
38
+ setDisabled(!inputExist);
39
+ };
40
+ model.valueChanged.connect(inputChanged);
41
+ (_a = model.attachmentsChanged) === null || _a === void 0 ? void 0 : _a.connect(inputChanged);
42
+ inputChanged();
43
+ const configChanged = (_, config) => {
44
+ var _a;
45
+ setTooltip(((_a = config.sendWithShiftEnter) !== null && _a !== void 0 ? _a : false)
46
+ ? 'Send message (SHIFT+ENTER)'
47
+ : 'Send message (ENTER)');
48
+ };
49
+ model.configChanged.connect(configChanged);
50
+ return () => {
51
+ var _a, _b;
52
+ model.valueChanged.disconnect(inputChanged);
53
+ (_a = model.attachmentsChanged) === null || _a === void 0 ? void 0 : _a.disconnect(inputChanged);
54
+ (_b = model.configChanged) === null || _b === void 0 ? void 0 : _b.disconnect(configChanged);
55
+ };
56
+ }, [model]);
34
57
  useEffect(() => {
35
58
  /**
36
59
  * Enable or disable the include selection button, and adapt the tooltip.
@@ -53,44 +76,36 @@ export function SendButton(props) {
53
76
  selectionWatcher === null || selectionWatcher === void 0 ? void 0 : selectionWatcher.selectionChanged.disconnect(toggleIncludeState);
54
77
  activeCellManager === null || activeCellManager === void 0 ? void 0 : activeCellManager.availabilityChanged.disconnect(toggleIncludeState);
55
78
  };
56
- }, [activeCellManager, selectionWatcher, hideIncludeSelection]);
57
- const defaultTooltip = props.sendWithShiftEnter
58
- ? 'Send message (SHIFT+ENTER)'
59
- : 'Send message (ENTER)';
60
- const tooltip = defaultTooltip;
79
+ }, [activeCellManager, selectionWatcher]);
61
80
  function sendWithSelection() {
62
- // Append the selected text if exists.
81
+ let source = '';
63
82
  if (selectionWatcher === null || selectionWatcher === void 0 ? void 0 : selectionWatcher.selection) {
64
- props.onSend({
65
- type: 'text',
66
- source: selectionWatcher.selection.text
67
- });
68
- closeMenu();
69
- return;
83
+ // Append the selected text if exists.
84
+ source = selectionWatcher.selection.text;
85
+ }
86
+ else if (activeCellManager === null || activeCellManager === void 0 ? void 0 : activeCellManager.available) {
87
+ // Append the active cell content if exists.
88
+ source = activeCellManager.getContent(false).source;
70
89
  }
71
- // Append the active cell content if exists.
72
- if (activeCellManager === null || activeCellManager === void 0 ? void 0 : activeCellManager.available) {
73
- props.onSend({
74
- type: 'cell',
75
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
76
- source: activeCellManager.getContent(false).source
77
- });
78
- closeMenu();
79
- return;
90
+ let content = model.value;
91
+ if (source) {
92
+ content += `
93
+
94
+ \`\`\`
95
+ ${source}
96
+ \`\`\`
97
+ `;
80
98
  }
99
+ model.send(content);
100
+ closeMenu();
101
+ model.value = '';
81
102
  }
82
- return (React.createElement(Box, { sx: { display: 'flex', flexWrap: 'nowrap' } },
83
- React.createElement(TooltippedButton, { onClick: () => props.onSend(), disabled: disabled, tooltip: tooltip, buttonProps: {
103
+ return (React.createElement(React.Fragment, null,
104
+ React.createElement(TooltippedButton, { onClick: () => model.send(model.value), disabled: disabled, tooltip: tooltip, buttonProps: {
84
105
  size: 'small',
85
- title: defaultTooltip,
106
+ title: tooltip,
86
107
  variant: 'contained',
87
108
  className: SEND_BUTTON_CLASS
88
- }, sx: {
89
- minWidth: 'unset',
90
- borderTopLeftRadius: hasButtonOnLeft ? '0px' : '2px',
91
- borderTopRightRadius: hideIncludeSelection ? '2px' : '0px',
92
- borderBottomRightRadius: hideIncludeSelection ? '2px' : '0px',
93
- borderBottomLeftRadius: hasButtonOnLeft ? '0px' : '2px'
94
109
  } },
95
110
  React.createElement(SendIcon, null)),
96
111
  !hideIncludeSelection && (React.createElement(React.Fragment, null,
@@ -108,11 +123,6 @@ export function SendButton(props) {
108
123
  e.stopPropagation();
109
124
  },
110
125
  className: SEND_INCLUDE_OPENER_CLASS
111
- }, sx: {
112
- minWidth: 'unset',
113
- padding: '4px 0px',
114
- borderRadius: '0px 2px 2px 0px',
115
- marginLeft: '1px'
116
126
  } },
117
127
  React.createElement(KeyboardArrowDown, null)),
118
128
  React.createElement(Menu, { open: menuOpen, onClose: closeMenu, anchorEl: menuAnchorEl, anchorOrigin: {
@@ -1,3 +1,3 @@
1
- export * from './attach-button';
2
- export * from './cancel-button';
3
- export * from './send-button';
1
+ export * from './buttons';
2
+ export * from './toolbar-registry';
3
+ export * from './use-chat-commands';
@@ -2,6 +2,6 @@
2
2
  * Copyright (c) Jupyter Development Team.
3
3
  * Distributed under the terms of the Modified BSD License.
4
4
  */
5
- export * from './attach-button';
6
- export * from './cancel-button';
7
- export * from './send-button';
5
+ export * from './buttons';
6
+ export * from './toolbar-registry';
7
+ export * from './use-chat-commands';
@@ -0,0 +1,98 @@
1
+ import * as React from 'react';
2
+ import { IInputModel } from '../../input-model';
3
+ import { ISignal } from '@lumino/signaling';
4
+ /**
5
+ * The toolbar registry interface.
6
+ */
7
+ export interface IInputToolbarRegistry {
8
+ /**
9
+ * A signal emitting when the items has changed.
10
+ */
11
+ readonly itemsChanged: ISignal<IInputToolbarRegistry, void>;
12
+ /**
13
+ * Get a toolbar item.
14
+ */
15
+ get(name: string): InputToolbarRegistry.IToolbarItem | undefined;
16
+ /**
17
+ * Get the list of the visible toolbar items in order.
18
+ */
19
+ getItems(): InputToolbarRegistry.IToolbarItem[];
20
+ /**
21
+ * Add a toolbar item.
22
+ */
23
+ addItem(name: string, item: InputToolbarRegistry.IToolbarItem): void;
24
+ /**
25
+ * Hide an element.
26
+ */
27
+ hide(name: string): void;
28
+ /**
29
+ * Show an element.
30
+ */
31
+ show(name: string): void;
32
+ }
33
+ /**
34
+ * The toolbar registry implementation.
35
+ */
36
+ export declare class InputToolbarRegistry implements IInputToolbarRegistry {
37
+ /**
38
+ * A signal emitting when the items has changed.
39
+ */
40
+ get itemsChanged(): ISignal<IInputToolbarRegistry, void>;
41
+ /**
42
+ * Get a toolbar item.
43
+ */
44
+ get(name: string): InputToolbarRegistry.IToolbarItem | undefined;
45
+ /**
46
+ * Get the list of the visible toolbar items in order.
47
+ */
48
+ getItems(): InputToolbarRegistry.IToolbarItem[];
49
+ /**
50
+ * Add a toolbar item.
51
+ */
52
+ addItem(name: string, item: InputToolbarRegistry.IToolbarItem): void;
53
+ /**
54
+ * Hide an element.
55
+ */
56
+ hide(name: string): void;
57
+ /**
58
+ * Show an element.
59
+ */
60
+ show(name: string): void;
61
+ private _items;
62
+ private _itemsChanged;
63
+ }
64
+ export declare namespace InputToolbarRegistry {
65
+ /**
66
+ * The toolbar item interface.
67
+ */
68
+ interface IToolbarItem {
69
+ /**
70
+ * The react functional component with the button.
71
+ *
72
+ * NOTE:
73
+ * This component must be a TooltippedButton for a good integration in the toolbar.
74
+ */
75
+ element: React.FunctionComponent<IToolbarItemProps>;
76
+ /**
77
+ * The position of the button in the toolbar.
78
+ */
79
+ position: number;
80
+ /**
81
+ * Whether the button is hidden or not.
82
+ */
83
+ hidden?: boolean;
84
+ }
85
+ /**
86
+ * The toolbar item properties, send to the button.
87
+ */
88
+ interface IToolbarItemProps {
89
+ /**
90
+ * The input model of the input component including the button.
91
+ */
92
+ model: IInputModel;
93
+ }
94
+ /**
95
+ * The default toolbar registry if none is provided.
96
+ */
97
+ function defaultToolbarRegistry(): InputToolbarRegistry;
98
+ }
@@ -0,0 +1,85 @@
1
+ import { AttachButton, CancelButton, SendButton } from './buttons';
2
+ import { Signal } from '@lumino/signaling';
3
+ /**
4
+ * The toolbar registry implementation.
5
+ */
6
+ export class InputToolbarRegistry {
7
+ constructor() {
8
+ this._items = new Map();
9
+ this._itemsChanged = new Signal(this);
10
+ }
11
+ /**
12
+ * A signal emitting when the items has changed.
13
+ */
14
+ get itemsChanged() {
15
+ return this._itemsChanged;
16
+ }
17
+ /**
18
+ * Get a toolbar item.
19
+ */
20
+ get(name) {
21
+ return this._items.get(name);
22
+ }
23
+ /**
24
+ * Get the list of the visible toolbar items in order.
25
+ */
26
+ getItems() {
27
+ return Array.from(this._items.values())
28
+ .filter(item => !item.hidden)
29
+ .sort((a, b) => a.position - b.position);
30
+ }
31
+ /**
32
+ * Add a toolbar item.
33
+ */
34
+ addItem(name, item) {
35
+ if (!this._items.has(name)) {
36
+ this._items.set(name, item);
37
+ this._itemsChanged.emit();
38
+ }
39
+ else {
40
+ console.warn(`A chat input toolbar item '${name}' is already registered`);
41
+ }
42
+ }
43
+ /**
44
+ * Hide an element.
45
+ */
46
+ hide(name) {
47
+ const item = this._items.get(name);
48
+ if (item) {
49
+ item.hidden = true;
50
+ this._itemsChanged.emit();
51
+ }
52
+ }
53
+ /**
54
+ * Show an element.
55
+ */
56
+ show(name) {
57
+ const item = this._items.get(name);
58
+ if (item) {
59
+ item.hidden = false;
60
+ this._itemsChanged.emit();
61
+ }
62
+ }
63
+ }
64
+ (function (InputToolbarRegistry) {
65
+ /**
66
+ * The default toolbar registry if none is provided.
67
+ */
68
+ function defaultToolbarRegistry() {
69
+ const registry = new InputToolbarRegistry();
70
+ registry.addItem('send', {
71
+ element: SendButton,
72
+ position: 100
73
+ });
74
+ registry.addItem('attach', {
75
+ element: AttachButton,
76
+ position: 20
77
+ });
78
+ registry.addItem('cancel', {
79
+ element: CancelButton,
80
+ position: 10
81
+ });
82
+ return registry;
83
+ }
84
+ InputToolbarRegistry.defaultToolbarRegistry = defaultToolbarRegistry;
85
+ })(InputToolbarRegistry || (InputToolbarRegistry = {}));
@@ -2,9 +2,9 @@
2
2
  * Copyright (c) Jupyter Development Team.
3
3
  * Distributed under the terms of the Modified BSD License.
4
4
  */
5
- import React from 'react';
6
- import { useEffect, useState } from 'react';
5
+ import { LabIcon } from '@jupyterlab/ui-components';
7
6
  import { Box } from '@mui/material';
7
+ import React, { useEffect, useState } from 'react';
8
8
  /**
9
9
  * A hook which automatically returns the list of command options given the
10
10
  * current input and chat command registry.
@@ -83,12 +83,13 @@ export function useChatCommands(inputModel, chatCommandRegistry) {
83
83
  getOptionLabel: (command) => command.name,
84
84
  renderOption: (defaultProps, command, __, ___) => {
85
85
  const { key, ...listItemProps } = defaultProps;
86
- const commandIcon = (React.createElement("span", null, typeof command.icon === 'object' ? (React.createElement(command.icon.react, null)) : (command.icon)));
86
+ const commandIcon = React.isValidElement(command.icon) ? (command.icon) : (React.createElement("span", null, command.icon instanceof LabIcon ? (React.createElement(command.icon.react, null)) : (command.icon)));
87
87
  return (React.createElement(Box, { key: key, component: "li", ...listItemProps },
88
88
  commandIcon,
89
89
  React.createElement("p", { className: "jp-chat-command-name" }, command.name),
90
- React.createElement("span", null, " - "),
91
- React.createElement("p", { className: "jp-chat-command-description" }, command.description)));
90
+ command.description && (React.createElement(React.Fragment, null,
91
+ React.createElement("span", null, " - "),
92
+ React.createElement("p", { className: "jp-chat-command-description" }, command.description)))));
92
93
  },
93
94
  // always show all options, since command providers should exclusively
94
95
  // define what commands are added to the menu.
@@ -1,5 +1,5 @@
1
- import React from 'react';
2
1
  import { ButtonProps, SxProps, TooltipProps } from '@mui/material';
2
+ import React from 'react';
3
3
  export type TooltippedButtonProps = {
4
4
  onClick: React.MouseEventHandler<HTMLButtonElement>;
5
5
  tooltip: string;
@@ -2,9 +2,10 @@
2
2
  * Copyright (c) Jupyter Development Team.
3
3
  * Distributed under the terms of the Modified BSD License.
4
4
  */
5
- import React from 'react';
6
5
  import { Button } from '@mui/material';
6
+ import React from 'react';
7
7
  import { ContrastingTooltip } from './contrasting-tooltip';
8
+ const TOOLTIPPED_WRAP_CLASS = 'jp-chat-tooltipped-wrap';
8
9
  /**
9
10
  * A component that renders an MUI `Button` with a high-contrast tooltip
10
11
  * provided by `ContrastingTooltip`. This component differs from the MUI
@@ -34,7 +35,7 @@ export function TooltippedButton(props) {
34
35
  ]
35
36
  }
36
37
  } },
37
- React.createElement("span", { style: { cursor: 'default' } },
38
+ React.createElement("span", { style: { cursor: 'default' }, className: TOOLTIPPED_WRAP_CLASS },
38
39
  React.createElement(Button, { ...props.buttonProps, onClick: props.onClick, disabled: props.disabled, sx: {
39
40
  lineHeight: 0,
40
41
  ...(props.disabled && { opacity: 0.5 }),
@@ -2,9 +2,11 @@
2
2
  * Copyright (c) Jupyter Development Team.
3
3
  * Distributed under the terms of the Modified BSD License.
4
4
  */
5
- import React from 'react';
5
+ import { classes } from '@jupyterlab/ui-components';
6
6
  import { IconButton } from '@mui/material';
7
+ import React from 'react';
7
8
  import { ContrastingTooltip } from './contrasting-tooltip';
9
+ const TOOLTIPPED_WRAP_CLASS = 'jp-chat-tooltipped-wrap';
8
10
  /**
9
11
  * A component that renders an MUI `IconButton` with a high-contrast tooltip
10
12
  * provided by `ContrastingTooltip`. This component differs from the MUI
@@ -31,7 +33,7 @@ export function TooltippedIconButton(props) {
31
33
  ]
32
34
  }
33
35
  } },
34
- React.createElement("span", { className: props.className },
36
+ React.createElement("span", { className: classes(props.className, TOOLTIPPED_WRAP_CLASS) },
35
37
  React.createElement(IconButton, { ...props.iconButtonProps, onClick: props.onClick, disabled: props.disabled, sx: {
36
38
  marginLeft: '8px',
37
39
  lineHeight: 0,
package/lib/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export * from './active-cell-manager';
2
+ export * from './chat-commands';
2
3
  export * from './components';
3
4
  export * from './icons';
4
5
  export * from './input-model';
@@ -9,4 +10,3 @@ export * from './types';
9
10
  export * from './widgets/chat-error';
10
11
  export * from './widgets/chat-sidebar';
11
12
  export * from './widgets/chat-widget';
12
- export * from './chat-commands';
package/lib/index.js CHANGED
@@ -3,6 +3,7 @@
3
3
  * Distributed under the terms of the Modified BSD License.
4
4
  */
5
5
  export * from './active-cell-manager';
6
+ export * from './chat-commands';
6
7
  export * from './components';
7
8
  export * from './icons';
8
9
  export * from './input-model';
@@ -13,4 +14,3 @@ export * from './types';
13
14
  export * from './widgets/chat-error';
14
15
  export * from './widgets/chat-sidebar';
15
16
  export * from './widgets/chat-widget';
16
- export * from './chat-commands';
@@ -1,12 +1,26 @@
1
+ import { IDocumentManager } from '@jupyterlab/docmanager';
1
2
  import { IDisposable } from '@lumino/disposable';
2
3
  import { ISignal } from '@lumino/signaling';
3
4
  import { IActiveCellManager } from './active-cell-manager';
4
5
  import { ISelectionWatcher } from './selection-watcher';
5
- import { IAttachment } from './types';
6
+ import { IChatContext } from './model';
7
+ import { IAttachment, IUser } from './types';
6
8
  /**
7
9
  * The chat input interface.
8
10
  */
9
11
  export interface IInputModel extends IDisposable {
12
+ /**
13
+ * The chat context (a readonly subset of the chat model).
14
+ */
15
+ readonly chatContext: IChatContext;
16
+ /**
17
+ * Function to send a message.
18
+ */
19
+ send: (content: string) => void;
20
+ /**
21
+ * Optional function to cancel edition.
22
+ */
23
+ cancel: (() => void) | undefined;
10
24
  /**
11
25
  * The entire input value.
12
26
  */
@@ -40,6 +54,10 @@ export interface IInputModel extends IDisposable {
40
54
  * Get the selection watcher.
41
55
  */
42
56
  readonly selectionWatcher: ISelectionWatcher | null;
57
+ /**
58
+ * Get the document manager.
59
+ */
60
+ readonly documentManager: IDocumentManager | null;
43
61
  /**
44
62
  * The input configuration.
45
63
  */
@@ -80,12 +98,40 @@ export interface IInputModel extends IDisposable {
80
98
  * Replace the current word in the input with a new one.
81
99
  */
82
100
  replaceCurrentWord(newWord: string): void;
101
+ /**
102
+ * The mentioned user list.
103
+ */
104
+ readonly mentions: IUser[];
105
+ /**
106
+ * Add user mention.
107
+ */
108
+ addMention?(user: IUser): void;
109
+ /**
110
+ * Remove a user mention.
111
+ */
112
+ removeMention(user: IUser): void;
113
+ /**
114
+ * Clear mentions list.
115
+ */
116
+ clearMentions(): void;
83
117
  }
84
118
  /**
85
119
  * The input model.
86
120
  */
87
121
  export declare class InputModel implements IInputModel {
88
122
  constructor(options: InputModel.IOptions);
123
+ /**
124
+ * The chat context (a readonly subset of the chat model);
125
+ */
126
+ get chatContext(): IChatContext;
127
+ /**
128
+ * Function to send a message.
129
+ */
130
+ send: (input: string) => void;
131
+ /**
132
+ * Optional function to cancel edition.
133
+ */
134
+ cancel: (() => void) | undefined;
89
135
  /**
90
136
  * The entire input value.
91
137
  */
@@ -120,6 +166,10 @@ export declare class InputModel implements IInputModel {
120
166
  * Get the selection watcher.
121
167
  */
122
168
  get selectionWatcher(): ISelectionWatcher | null;
169
+ /**
170
+ * Get the document manager.
171
+ */
172
+ get documentManager(): IDocumentManager | null;
123
173
  /**
124
174
  * The input configuration.
125
175
  */
@@ -161,6 +211,22 @@ export declare class InputModel implements IInputModel {
161
211
  * Replace the current word in the input with a new one.
162
212
  */
163
213
  replaceCurrentWord(newWord: string): void;
214
+ /**
215
+ * The mentioned user list.
216
+ */
217
+ get mentions(): IUser[];
218
+ /**
219
+ * Add a user mention.
220
+ */
221
+ addMention(user: IUser): void;
222
+ /**
223
+ * Remove a user mention.
224
+ */
225
+ removeMention(user: IUser): void;
226
+ /**
227
+ * Clear mentions list.
228
+ */
229
+ clearMentions: () => void;
164
230
  /**
165
231
  * Dispose the input model.
166
232
  */
@@ -169,12 +235,16 @@ export declare class InputModel implements IInputModel {
169
235
  * Whether the input model is disposed.
170
236
  */
171
237
  get isDisposed(): boolean;
238
+ private _onSend;
239
+ private _chatContext;
172
240
  private _value;
173
241
  private _cursorIndex;
174
242
  private _currentWord;
175
243
  private _attachments;
244
+ private _mentions;
176
245
  private _activeCellManager;
177
246
  private _selectionWatcher;
247
+ private _documentManager;
178
248
  private _config;
179
249
  private _valueChanged;
180
250
  private _cursorIndexChanged;
@@ -186,6 +256,20 @@ export declare class InputModel implements IInputModel {
186
256
  }
187
257
  export declare namespace InputModel {
188
258
  interface IOptions {
259
+ /**
260
+ * The chat context (a readonly subset of the chat model).
261
+ */
262
+ chatContext: IChatContext;
263
+ /**
264
+ * The function that should send the message.
265
+ * @param content - the content of the message.
266
+ * @param model - the model of the input sending the message.
267
+ */
268
+ onSend: (content: string, model?: InputModel) => void;
269
+ /**
270
+ * Function that should cancel the message edition.
271
+ */
272
+ onCancel?: () => void;
189
273
  /**
190
274
  * The initial value of the input.
191
275
  */
@@ -194,6 +278,10 @@ export declare namespace InputModel {
194
278
  * The initial attachments.
195
279
  */
196
280
  attachments?: IAttachment[];
281
+ /**
282
+ * The initial mentions.
283
+ */
284
+ mentions?: IUser[];
197
285
  /**
198
286
  * The current cursor index.
199
287
  * This refers to the index of the character in front of the cursor.
@@ -211,6 +299,10 @@ export declare namespace InputModel {
211
299
  * Selection watcher.
212
300
  */
213
301
  selectionWatcher?: ISelectionWatcher | null;
302
+ /**
303
+ * Document manager.
304
+ */
305
+ documentManager?: IDocumentManager | null;
214
306
  }
215
307
  interface IConfig {
216
308
  /**