@jupyter/chat 0.20.0-alpha.1 → 0.20.0-alpha.2

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.
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,37 @@
1
+ /*
2
+ * Copyright (c) Jupyter Development Team.
3
+ * Distributed under the terms of the Modified BSD License.
4
+ */
5
+ import { MessagePreambleRegistry } from '../registers/preambles';
6
+ describe('MessagePreambleRegistry', () => {
7
+ let registry;
8
+ beforeEach(() => {
9
+ registry = new MessagePreambleRegistry();
10
+ });
11
+ it('should start with no components', () => {
12
+ expect(registry.getComponents()).toEqual([]);
13
+ });
14
+ it('should add a component', () => {
15
+ const component = () => null;
16
+ registry.addComponent(component);
17
+ expect(registry.getComponents()).toHaveLength(1);
18
+ expect(registry.getComponents()[0]).toBe(component);
19
+ });
20
+ it('should preserve insertion order', () => {
21
+ const first = () => null;
22
+ const second = () => null;
23
+ registry.addComponent(first);
24
+ registry.addComponent(second);
25
+ const components = registry.getComponents();
26
+ expect(components).toHaveLength(2);
27
+ expect(components[0]).toBe(first);
28
+ expect(components[1]).toBe(second);
29
+ });
30
+ it('should return a copy from getComponents', () => {
31
+ const component = () => null;
32
+ registry.addComponent(component);
33
+ const result = registry.getComponents();
34
+ result.push(() => null);
35
+ expect(registry.getComponents()).toHaveLength(1);
36
+ });
37
+ });
@@ -3,7 +3,7 @@ import { IThemeManager } from '@jupyterlab/apputils';
3
3
  import { IRenderMimeRegistry } from '@jupyterlab/rendermime';
4
4
  import { IInputToolbarRegistry } from './input';
5
5
  import { IChatModel } from '../model';
6
- import { IAttachmentOpenerRegistry, IChatCommandRegistry, IMessageFooterRegistry } from '../registers';
6
+ import { IAttachmentOpenerRegistry, IChatCommandRegistry, IMessageFooterRegistry, IMessagePreambleRegistry } from '../registers';
7
7
  import { ChatArea } from '../types';
8
8
  export declare function ChatBody(props: Chat.IChatProps): JSX.Element;
9
9
  export declare function Chat(props: Chat.IOptions): JSX.Element;
@@ -39,6 +39,10 @@ export declare namespace Chat {
39
39
  * The footer registry.
40
40
  */
41
41
  messageFooterRegistry?: IMessageFooterRegistry;
42
+ /**
43
+ * The preamble registry for content above message body.
44
+ */
45
+ messagePreambleRegistry?: IMessagePreambleRegistry;
42
46
  /**
43
47
  * The welcome message.
44
48
  */
@@ -10,7 +10,7 @@ const SEND_BUTTON_CLASS = 'jp-chat-send-button';
10
10
  * The send button.
11
11
  */
12
12
  export function SendButton(props) {
13
- const { model, chatModel, chatCommandRegistry, edit } = props;
13
+ const { model, chatCommandRegistry, edit } = props;
14
14
  // Don't show this button when in edit mode
15
15
  if (edit) {
16
16
  return React.createElement(React.Fragment, null);
@@ -45,12 +45,9 @@ export function SendButton(props) {
45
45
  async function send() {
46
46
  // Run all command providers
47
47
  await (chatCommandRegistry === null || chatCommandRegistry === void 0 ? void 0 : chatCommandRegistry.onSubmit(model));
48
- // send message through chat model
49
- await (chatModel === null || chatModel === void 0 ? void 0 : chatModel.sendMessage({
50
- body: model.value
51
- }));
52
- // clear input model value & re-focus
48
+ const body = model.value;
53
49
  model.value = '';
50
+ model.send(body);
54
51
  model.focus();
55
52
  }
56
53
  return (React.createElement(TooltippedIconButton, { onClick: send, tooltip: tooltip, disabled: disabled, buttonProps: {
@@ -4,5 +4,6 @@ export * from './message';
4
4
  export * from './message-renderer';
5
5
  export * from './messages';
6
6
  export * from './navigation';
7
+ export * from './preamble';
7
8
  export * from './toolbar';
8
9
  export * from './welcome';
@@ -8,5 +8,6 @@ export * from './message';
8
8
  export * from './message-renderer';
9
9
  export * from './messages';
10
10
  export * from './navigation';
11
+ export * from './preamble';
11
12
  export * from './toolbar';
12
13
  export * from './welcome';
@@ -9,6 +9,7 @@ import React, { useEffect, useState, useRef } from 'react';
9
9
  import { MessageFooterComponent } from './footer';
10
10
  import { ChatMessageHeader } from './header';
11
11
  import { ChatMessage } from './message';
12
+ import { MessagePreambleComponent } from './preamble';
12
13
  import { Navigation } from './navigation';
13
14
  import { WelcomeMessage } from './welcome';
14
15
  import { ScrollContainer } from '../scroll-container';
@@ -22,7 +23,7 @@ const MESSAGE_STACKED_CLASS = 'jp-chat-message-stacked';
22
23
  */
23
24
  export function ChatMessages() {
24
25
  var _a;
25
- const { area, messageFooterRegistry, model, welcomeMessage } = useChatContext();
26
+ const { area, messageFooterRegistry, messagePreambleRegistry, model, welcomeMessage } = useChatContext();
26
27
  const [messages, setMessages] = useState(model.messages);
27
28
  const refMsgBox = useRef(null);
28
29
  const [allRendered, setAllRendered] = useState(false);
@@ -161,6 +162,7 @@ export function ChatMessages() {
161
162
  })
162
163
  }, className: clsx(MESSAGE_CLASS, message.stacked ? MESSAGE_STACKED_CLASS : '') },
163
164
  React.createElement(ChatMessageHeader, { message: message, isCurrentUser: isCurrentUser }),
165
+ messagePreambleRegistry && (React.createElement(MessagePreambleComponent, { message: message })),
164
166
  React.createElement(ChatMessage, { message: message, index: i, renderedPromise: renderedPromise.current[i], ref: el => (listRef.current[i] = el) }),
165
167
  messageFooterRegistry && (React.createElement(MessageFooterComponent, { message: message }))));
166
168
  }))),
@@ -0,0 +1,12 @@
1
+ /// <reference types="react" />
2
+ import { IMessage } from '../../types';
3
+ /**
4
+ * The preamble component properties.
5
+ */
6
+ export interface IMessagePreambleProps {
7
+ message: IMessage;
8
+ }
9
+ /**
10
+ * Renders all registered preamble components vertically above the message body.
11
+ */
12
+ export declare function MessagePreambleComponent(props: IMessagePreambleProps): JSX.Element | null;
@@ -0,0 +1,31 @@
1
+ /*
2
+ * Copyright (c) Jupyter Development Team.
3
+ * Distributed under the terms of the Modified BSD License.
4
+ */
5
+ import React, { useEffect, useState } from 'react';
6
+ import { useChatContext } from '../../context';
7
+ /**
8
+ * Renders all registered preamble components vertically above the message body.
9
+ */
10
+ export function MessagePreambleComponent(props) {
11
+ const [message, setMessage] = useState(props.message.content);
12
+ useEffect(() => {
13
+ function messageChanged() {
14
+ setMessage(props.message.content);
15
+ }
16
+ props.message.changed.connect(messageChanged);
17
+ setMessage(props.message.content);
18
+ return () => {
19
+ props.message.changed.disconnect(messageChanged);
20
+ };
21
+ }, [props.message]);
22
+ const { model, messagePreambleRegistry } = useChatContext();
23
+ if (!messagePreambleRegistry) {
24
+ return null;
25
+ }
26
+ const components = messagePreambleRegistry.getComponents();
27
+ if (!components.length) {
28
+ return null;
29
+ }
30
+ return (React.createElement(React.Fragment, null, components.map((Component, i) => (React.createElement(Component, { key: i, model: model, message: message })))));
31
+ }
package/lib/message.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { IRenderMime } from '@jupyterlab/rendermime';
2
2
  import { ISignal } from '@lumino/signaling';
3
- import { IAttachment, IMessageContent, IMessage, IUser } from './types';
3
+ import { IAttachment, IMessageContent, IMessage, IMessageMetadata, IUser } from './types';
4
4
  /**
5
5
  * The message object.
6
6
  */
@@ -29,6 +29,7 @@ export declare class Message implements IMessage {
29
29
  get deleted(): boolean | undefined;
30
30
  get edited(): boolean | undefined;
31
31
  get stacked(): boolean | undefined;
32
+ get metadata(): IMessageMetadata | undefined;
32
33
  /**
33
34
  * A signal emitting when the message has been updated.
34
35
  */
package/lib/message.js CHANGED
@@ -58,6 +58,9 @@ export class Message {
58
58
  get stacked() {
59
59
  return this._content.stacked;
60
60
  }
61
+ get metadata() {
62
+ return this._content.metadata;
63
+ }
61
64
  /**
62
65
  * A signal emitting when the message has been updated.
63
66
  */
@@ -1,3 +1,4 @@
1
1
  export * from './attachment-openers';
2
2
  export * from './chat-commands';
3
3
  export * from './footers';
4
+ export * from './preambles';
@@ -5,3 +5,4 @@
5
5
  export * from './attachment-openers';
6
6
  export * from './chat-commands';
7
7
  export * from './footers';
8
+ export * from './preambles';
@@ -0,0 +1,44 @@
1
+ /// <reference types="react" />
2
+ import { Token } from '@lumino/coreutils';
3
+ import { IChatModel } from '../model';
4
+ import { IMessageContent } from '../types';
5
+ /**
6
+ * The token providing the chat preamble registry.
7
+ */
8
+ export declare const IMessagePreambleRegistry: Token<IMessagePreambleRegistry>;
9
+ /**
10
+ * The props passed to each preamble component.
11
+ */
12
+ export type MessagePreambleProps = {
13
+ model: IChatModel;
14
+ message: IMessageContent;
15
+ };
16
+ /**
17
+ * The interface of a registry to provide message preamble components.
18
+ * Preamble components render above the message body, after the header.
19
+ */
20
+ export interface IMessagePreambleRegistry {
21
+ /**
22
+ * Add a preamble component to the registry.
23
+ * Components are rendered in the order they are added.
24
+ */
25
+ addComponent(component: (props: MessagePreambleProps) => JSX.Element | null): void;
26
+ /**
27
+ * Get all registered preamble components.
28
+ */
29
+ getComponents(): ((props: MessagePreambleProps) => JSX.Element | null)[];
30
+ }
31
+ /**
32
+ * The default implementation of the message preamble registry.
33
+ */
34
+ export declare class MessagePreambleRegistry implements IMessagePreambleRegistry {
35
+ /**
36
+ * Add a preamble component to the registry.
37
+ */
38
+ addComponent(component: (props: MessagePreambleProps) => JSX.Element | null): void;
39
+ /**
40
+ * Get all registered preamble components.
41
+ */
42
+ getComponents(): ((props: MessagePreambleProps) => JSX.Element | null)[];
43
+ private _components;
44
+ }
@@ -0,0 +1,29 @@
1
+ /*
2
+ * Copyright (c) Jupyter Development Team.
3
+ * Distributed under the terms of the Modified BSD License.
4
+ */
5
+ import { Token } from '@lumino/coreutils';
6
+ /**
7
+ * The token providing the chat preamble registry.
8
+ */
9
+ export const IMessagePreambleRegistry = new Token('@jupyter/chat:ChatPreambleRegistry');
10
+ /**
11
+ * The default implementation of the message preamble registry.
12
+ */
13
+ export class MessagePreambleRegistry {
14
+ constructor() {
15
+ this._components = [];
16
+ }
17
+ /**
18
+ * Add a preamble component to the registry.
19
+ */
20
+ addComponent(component) {
21
+ this._components.push(component);
22
+ }
23
+ /**
24
+ * Get all registered preamble components.
25
+ */
26
+ getComponents() {
27
+ return [...this._components];
28
+ }
29
+ }
package/lib/types.d.ts CHANGED
@@ -53,6 +53,20 @@ export interface IConfig {
53
53
  */
54
54
  showDeleted?: boolean;
55
55
  }
56
+ /**
57
+ * An empty interface to describe optional metadata attached to a chat message.
58
+ * Extensions can augment this interface to add custom fields:
59
+ *
60
+ * ```ts
61
+ * declare module '@jupyter/chat' {
62
+ * interface IMessageMetadata {
63
+ * myField?: MyType;
64
+ * }
65
+ * }
66
+ * ```
67
+ */
68
+ export interface IMessageMetadata {
69
+ }
56
70
  /**
57
71
  * The chat message description.
58
72
  */
@@ -68,10 +82,8 @@ export type IMessageContent<T = IUser, U = IAttachment> = {
68
82
  deleted?: boolean;
69
83
  edited?: boolean;
70
84
  stacked?: boolean;
85
+ metadata?: IMessageMetadata;
71
86
  };
72
- /**
73
- *
74
- */
75
87
  export interface IMessage extends IMessageContent {
76
88
  /**
77
89
  * Update one or several fields of the message.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jupyter/chat",
3
- "version": "0.20.0-alpha.1",
3
+ "version": "0.20.0-alpha.2",
4
4
  "description": "A package that provides UI components that can be used to create a chat in a Jupyterlab extension.",
5
5
  "keywords": [
6
6
  "jupyter",
@@ -0,0 +1,51 @@
1
+ /*
2
+ * Copyright (c) Jupyter Development Team.
3
+ * Distributed under the terms of the Modified BSD License.
4
+ */
5
+
6
+ import {
7
+ MessagePreambleRegistry,
8
+ MessagePreambleProps
9
+ } from '../registers/preambles';
10
+
11
+ describe('MessagePreambleRegistry', () => {
12
+ let registry: MessagePreambleRegistry;
13
+
14
+ beforeEach(() => {
15
+ registry = new MessagePreambleRegistry();
16
+ });
17
+
18
+ it('should start with no components', () => {
19
+ expect(registry.getComponents()).toEqual([]);
20
+ });
21
+
22
+ it('should add a component', () => {
23
+ const component: (props: MessagePreambleProps) => JSX.Element | null = () =>
24
+ null;
25
+ registry.addComponent(component);
26
+ expect(registry.getComponents()).toHaveLength(1);
27
+ expect(registry.getComponents()[0]).toBe(component);
28
+ });
29
+
30
+ it('should preserve insertion order', () => {
31
+ const first: (props: MessagePreambleProps) => JSX.Element | null = () =>
32
+ null;
33
+ const second: (props: MessagePreambleProps) => JSX.Element | null = () =>
34
+ null;
35
+ registry.addComponent(first);
36
+ registry.addComponent(second);
37
+ const components = registry.getComponents();
38
+ expect(components).toHaveLength(2);
39
+ expect(components[0]).toBe(first);
40
+ expect(components[1]).toBe(second);
41
+ });
42
+
43
+ it('should return a copy from getComponents', () => {
44
+ const component: (props: MessagePreambleProps) => JSX.Element | null = () =>
45
+ null;
46
+ registry.addComponent(component);
47
+ const result = registry.getComponents();
48
+ result.push(() => null);
49
+ expect(registry.getComponents()).toHaveLength(1);
50
+ });
51
+ });
@@ -24,7 +24,8 @@ import { IChatModel } from '../model';
24
24
  import {
25
25
  IAttachmentOpenerRegistry,
26
26
  IChatCommandRegistry,
27
- IMessageFooterRegistry
27
+ IMessageFooterRegistry,
28
+ IMessagePreambleRegistry
28
29
  } from '../registers';
29
30
  import { ChatArea } from '../types';
30
31
 
@@ -168,6 +169,10 @@ export namespace Chat {
168
169
  * The footer registry.
169
170
  */
170
171
  messageFooterRegistry?: IMessageFooterRegistry;
172
+ /**
173
+ * The preamble registry for content above message body.
174
+ */
175
+ messagePreambleRegistry?: IMessagePreambleRegistry;
171
176
  /**
172
177
  * The welcome message.
173
178
  */
@@ -18,7 +18,7 @@ const SEND_BUTTON_CLASS = 'jp-chat-send-button';
18
18
  export function SendButton(
19
19
  props: InputToolbarRegistry.IToolbarItemProps
20
20
  ): JSX.Element {
21
- const { model, chatModel, chatCommandRegistry, edit } = props;
21
+ const { model, chatCommandRegistry, edit } = props;
22
22
 
23
23
  // Don't show this button when in edit mode
24
24
  if (edit) {
@@ -62,12 +62,10 @@ export function SendButton(
62
62
  // Run all command providers
63
63
  await chatCommandRegistry?.onSubmit(model);
64
64
 
65
- // send message through chat model
66
- await chatModel?.sendMessage({
67
- body: model.value
68
- });
69
- // clear input model value & re-focus
65
+ const body = model.value;
66
+
70
67
  model.value = '';
68
+ model.send(body);
71
69
  model.focus();
72
70
  }
73
71
 
@@ -9,5 +9,6 @@ export * from './message';
9
9
  export * from './message-renderer';
10
10
  export * from './messages';
11
11
  export * from './navigation';
12
+ export * from './preamble';
12
13
  export * from './toolbar';
13
14
  export * from './welcome';
@@ -11,6 +11,7 @@ import React, { useEffect, useState, useRef } from 'react';
11
11
  import { MessageFooterComponent } from './footer';
12
12
  import { ChatMessageHeader } from './header';
13
13
  import { ChatMessage } from './message';
14
+ import { MessagePreambleComponent } from './preamble';
14
15
  import { Navigation } from './navigation';
15
16
  import { WelcomeMessage } from './welcome';
16
17
  import { ScrollContainer } from '../scroll-container';
@@ -27,8 +28,13 @@ const MESSAGE_STACKED_CLASS = 'jp-chat-message-stacked';
27
28
  * The messages list component.
28
29
  */
29
30
  export function ChatMessages(): JSX.Element {
30
- const { area, messageFooterRegistry, model, welcomeMessage } =
31
- useChatContext();
31
+ const {
32
+ area,
33
+ messageFooterRegistry,
34
+ messagePreambleRegistry,
35
+ model,
36
+ welcomeMessage
37
+ } = useChatContext();
32
38
 
33
39
  const [messages, setMessages] = useState<IMessage[]>(model.messages);
34
40
  const refMsgBox = useRef<HTMLDivElement>(null);
@@ -203,6 +209,9 @@ export function ChatMessages(): JSX.Element {
203
209
  message={message}
204
210
  isCurrentUser={isCurrentUser}
205
211
  />
212
+ {messagePreambleRegistry && (
213
+ <MessagePreambleComponent message={message} />
214
+ )}
206
215
  <ChatMessage
207
216
  message={message}
208
217
  index={i}
@@ -0,0 +1,55 @@
1
+ /*
2
+ * Copyright (c) Jupyter Development Team.
3
+ * Distributed under the terms of the Modified BSD License.
4
+ */
5
+
6
+ import React, { useEffect, useState } from 'react';
7
+
8
+ import { useChatContext } from '../../context';
9
+ import { IMessage, IMessageContent } from '../../types';
10
+
11
+ /**
12
+ * The preamble component properties.
13
+ */
14
+ export interface IMessagePreambleProps {
15
+ message: IMessage;
16
+ }
17
+
18
+ /**
19
+ * Renders all registered preamble components vertically above the message body.
20
+ */
21
+ export function MessagePreambleComponent(
22
+ props: IMessagePreambleProps
23
+ ): JSX.Element | null {
24
+ const [message, setMessage] = useState<IMessageContent>(
25
+ props.message.content
26
+ );
27
+
28
+ useEffect(() => {
29
+ function messageChanged() {
30
+ setMessage(props.message.content);
31
+ }
32
+ props.message.changed.connect(messageChanged);
33
+ setMessage(props.message.content);
34
+ return () => {
35
+ props.message.changed.disconnect(messageChanged);
36
+ };
37
+ }, [props.message]);
38
+
39
+ const { model, messagePreambleRegistry } = useChatContext();
40
+ if (!messagePreambleRegistry) {
41
+ return null;
42
+ }
43
+ const components = messagePreambleRegistry.getComponents();
44
+ if (!components.length) {
45
+ return null;
46
+ }
47
+
48
+ return (
49
+ <>
50
+ {components.map((Component, i) => (
51
+ <Component key={i} model={model} message={message} />
52
+ ))}
53
+ </>
54
+ );
55
+ }
package/src/message.ts CHANGED
@@ -5,7 +5,13 @@
5
5
 
6
6
  import { IRenderMime } from '@jupyterlab/rendermime';
7
7
  import { ISignal, Signal } from '@lumino/signaling';
8
- import { IAttachment, IMessageContent, IMessage, IUser } from './types';
8
+ import {
9
+ IAttachment,
10
+ IMessageContent,
11
+ IMessage,
12
+ IMessageMetadata,
13
+ IUser
14
+ } from './types';
9
15
 
10
16
  /**
11
17
  * The message object.
@@ -65,6 +71,9 @@ export class Message implements IMessage {
65
71
  get stacked(): boolean | undefined {
66
72
  return this._content.stacked;
67
73
  }
74
+ get metadata(): IMessageMetadata | undefined {
75
+ return this._content.metadata;
76
+ }
68
77
 
69
78
  /**
70
79
  * A signal emitting when the message has been updated.
@@ -6,3 +6,4 @@
6
6
  export * from './attachment-openers';
7
7
  export * from './chat-commands';
8
8
  export * from './footers';
9
+ export * from './preambles';
@@ -0,0 +1,65 @@
1
+ /*
2
+ * Copyright (c) Jupyter Development Team.
3
+ * Distributed under the terms of the Modified BSD License.
4
+ */
5
+
6
+ import { Token } from '@lumino/coreutils';
7
+ import { IChatModel } from '../model';
8
+ import { IMessageContent } from '../types';
9
+
10
+ /**
11
+ * The token providing the chat preamble registry.
12
+ */
13
+ export const IMessagePreambleRegistry = new Token<IMessagePreambleRegistry>(
14
+ '@jupyter/chat:ChatPreambleRegistry'
15
+ );
16
+
17
+ /**
18
+ * The props passed to each preamble component.
19
+ */
20
+ export type MessagePreambleProps = {
21
+ model: IChatModel;
22
+ message: IMessageContent;
23
+ };
24
+
25
+ /**
26
+ * The interface of a registry to provide message preamble components.
27
+ * Preamble components render above the message body, after the header.
28
+ */
29
+ export interface IMessagePreambleRegistry {
30
+ /**
31
+ * Add a preamble component to the registry.
32
+ * Components are rendered in the order they are added.
33
+ */
34
+ addComponent(
35
+ component: (props: MessagePreambleProps) => JSX.Element | null
36
+ ): void;
37
+ /**
38
+ * Get all registered preamble components.
39
+ */
40
+ getComponents(): ((props: MessagePreambleProps) => JSX.Element | null)[];
41
+ }
42
+
43
+ /**
44
+ * The default implementation of the message preamble registry.
45
+ */
46
+ export class MessagePreambleRegistry implements IMessagePreambleRegistry {
47
+ /**
48
+ * Add a preamble component to the registry.
49
+ */
50
+ addComponent(
51
+ component: (props: MessagePreambleProps) => JSX.Element | null
52
+ ): void {
53
+ this._components.push(component);
54
+ }
55
+
56
+ /**
57
+ * Get all registered preamble components.
58
+ */
59
+ getComponents(): ((props: MessagePreambleProps) => JSX.Element | null)[] {
60
+ return [...this._components];
61
+ }
62
+
63
+ private _components: ((props: MessagePreambleProps) => JSX.Element | null)[] =
64
+ [];
65
+ }
package/src/types.ts CHANGED
@@ -61,6 +61,20 @@ export interface IConfig {
61
61
  showDeleted?: boolean;
62
62
  }
63
63
 
64
+ /**
65
+ * An empty interface to describe optional metadata attached to a chat message.
66
+ * Extensions can augment this interface to add custom fields:
67
+ *
68
+ * ```ts
69
+ * declare module '@jupyter/chat' {
70
+ * interface IMessageMetadata {
71
+ * myField?: MyType;
72
+ * }
73
+ * }
74
+ * ```
75
+ */
76
+ export interface IMessageMetadata {} /* eslint-disable-line @typescript-eslint/no-empty-object-type */
77
+
64
78
  /**
65
79
  * The chat message description.
66
80
  */
@@ -79,11 +93,9 @@ export type IMessageContent<T = IUser, U = IAttachment> = {
79
93
  deleted?: boolean;
80
94
  edited?: boolean;
81
95
  stacked?: boolean;
96
+ metadata?: IMessageMetadata;
82
97
  };
83
98
 
84
- /**
85
- *
86
- */
87
99
  export interface IMessage extends IMessageContent {
88
100
  /**
89
101
  * Update one or several fields of the message.