فهرست منبع

Make kernel message typing follow the spec more closely.

All kernel message replies have a status field. This ensures that reply messages reflect this and handle the abort and error status appropriately.

We also simplify typings since we can refer to most content typings using the field accessor.
Jason Grout 6 سال پیش
والد
کامیت
726ce5e19d

+ 1 - 1
packages/completer/src/kernelconnector.ts

@@ -41,7 +41,7 @@ export class KernelConnector extends DataConnector<
       return Promise.reject(new Error('No kernel for completion request.'));
     }
 
-    const contents: KernelMessage.ICompleteRequest = {
+    const contents: KernelMessage.ICompleteRequestMsg['content'] = {
       code: request.text,
       cursor_pos: request.offset
     };

+ 7 - 5
packages/console/src/history.ts

@@ -224,10 +224,12 @@ export class ConsoleHistory implements IConsoleHistory {
     this._history.length = 0;
     let last = '';
     let current = '';
-    for (let i = 0; i < value.content.history.length; i++) {
-      current = (value.content.history[i] as string[])[2];
-      if (current !== last) {
-        this._history.push((last = current));
+    if (value.content.status === 'ok') {
+      for (let i = 0; i < value.content.history.length; i++) {
+        current = (value.content.history[i] as string[])[2];
+        if (current !== last) {
+          this._history.push((last = current));
+        }
       }
     }
     // Reset the history navigation cursor back to the bottom.
@@ -360,7 +362,7 @@ export namespace ConsoleHistory {
  * A namespace for private data.
  */
 namespace Private {
-  export const initialRequest: KernelMessage.IHistoryRequest = {
+  export const initialRequest: KernelMessage.IHistoryRequestMsg['content'] = {
     output: false,
     raw: true,
     hist_access_type: 'tail',

+ 6 - 2
packages/console/src/widget.ts

@@ -646,7 +646,7 @@ export class CodeConsole extends Widget {
         return;
       }
       if (value && value.content.status === 'ok') {
-        let content = value.content as KernelMessage.IExecuteOkReply;
+        let content = value.content;
         // Use deprecated payloads for backwards compatibility.
         if (content.payload && content.payload.length) {
           let setNextInput = content.payload.filter(i => {
@@ -682,7 +682,11 @@ export class CodeConsole extends Widget {
   /**
    * Update the console based on the kernel info.
    */
-  private _handleInfo(info: KernelMessage.IInfoReply): void {
+  private _handleInfo(info: KernelMessage.IInfoReplyMsg['content']): void {
+    if (info.status !== 'ok') {
+      this._banner.model.value.text = 'Error in getting kernel banner';
+      return;
+    }
     this._banner.model.value.text = info.banner;
     let lang = info.language_info as nbformat.ILanguageInfoMetadata;
     this._mimetype = this._mimeTypeService.getMimeTypeByLanguage(lang);

+ 4 - 1
packages/help-extension/src/index.tsx

@@ -164,7 +164,10 @@ function activate(
   helpMenu.addGroup(resourcesGroup, 10);
 
   // Generate a cache of the kernel help links.
-  const kernelInfoCache = new Map<string, KernelMessage.IInfoReply>();
+  const kernelInfoCache = new Map<
+    string,
+    KernelMessage.IInfoReplyMsg['content']
+  >();
   serviceManager.sessions.runningChanged.connect((m, sessions) => {
     // If a new session has been added, it is at the back
     // of the session list. If one has changed or stopped,

+ 1 - 1
packages/inspector/src/kernelconnector.ts

@@ -41,7 +41,7 @@ export class KernelConnector extends DataConnector<
       return Promise.reject(new Error('Inspection fetch requires a kernel.'));
     }
 
-    const contents: KernelMessage.IInspectRequest = {
+    const contents: KernelMessage.IInspectRequestMsg['content'] = {
       code: request.text,
       cursor_pos: request.offset,
       detail_level: 0

+ 2 - 2
packages/notebook/src/actions.tsx

@@ -1488,7 +1488,7 @@ namespace Private {
               }
 
               if (reply.content.status === 'ok') {
-                const content = reply.content as KernelMessage.IExecuteOkReply;
+                const content = reply.content;
 
                 if (content.payload && content.payload.length) {
                   handlePayload(content, notebook, cell);
@@ -1532,7 +1532,7 @@ namespace Private {
    * See [Payloads (DEPRECATED)](https://jupyter-client.readthedocs.io/en/latest/messaging.html#payloads-deprecated).
    */
   function handlePayload(
-    content: KernelMessage.IExecuteOkReply,
+    content: KernelMessage.IExecuteReply,
     notebook: Notebook,
     cell: Cell
   ) {

+ 6 - 2
packages/outputarea/src/widget.ts

@@ -468,7 +468,10 @@ export class OutputArea extends Widget {
     // is overridden from 'execute_reply' to 'display_data' in order to
     // render output.
     let model = this.model;
-    let content = msg.content as KernelMessage.IExecuteOkReply;
+    let content = msg.content;
+    if (content.status !== 'ok') {
+      return;
+    }
     let payload = content && content.payload;
     if (!payload || !payload.length) {
       return;
@@ -557,7 +560,7 @@ export namespace OutputArea {
     ) {
       stopOnError = false;
     }
-    let content: KernelMessage.IExecuteRequest = {
+    let content: KernelMessage.IExecuteRequestMsg['content'] = {
       code,
       stop_on_error: stopOnError
     };
@@ -712,6 +715,7 @@ export class Stdin extends Widget implements IStdin {
       if ((event as KeyboardEvent).keyCode === 13) {
         // Enter
         this._future.sendInputReply({
+          status: 'ok',
           value: input.value
         });
         if (input.type === 'password') {

+ 10 - 7
packages/services/src/kernel/default.ts

@@ -415,6 +415,9 @@ export class DefaultKernel implements Kernel.IKernel {
     if (this.isDisposed) {
       throw new Error('Disposed kernel');
     }
+    if (reply.content.status !== 'ok') {
+      throw new Error('Kernel info reply errored');
+    }
     this._info = reply.content;
     return reply;
   }
@@ -429,7 +432,7 @@ export class DefaultKernel implements Kernel.IKernel {
    * received and validated.
    */
   requestComplete(
-    content: KernelMessage.ICompleteRequest
+    content: KernelMessage.ICompleteRequestMsg['content']
   ): Promise<KernelMessage.ICompleteReplyMsg> {
     let msg = KernelMessage.createMessage({
       msgType: 'complete_request',
@@ -453,7 +456,7 @@ export class DefaultKernel implements Kernel.IKernel {
    * received and validated.
    */
   requestInspect(
-    content: KernelMessage.IInspectRequest
+    content: KernelMessage.IInspectRequestMsg['content']
   ): Promise<KernelMessage.IInspectReplyMsg> {
     let msg = KernelMessage.createMessage({
       msgType: 'inspect_request',
@@ -477,7 +480,7 @@ export class DefaultKernel implements Kernel.IKernel {
    * received and validated.
    */
   requestHistory(
-    content: KernelMessage.IHistoryRequest
+    content: KernelMessage.IHistoryRequestMsg['content']
   ): Promise<KernelMessage.IHistoryReplyMsg> {
     let msg = KernelMessage.createMessage({
       msgType: 'history_request',
@@ -507,7 +510,7 @@ export class DefaultKernel implements Kernel.IKernel {
    * **See also:** [[IExecuteReply]]
    */
   requestExecute(
-    content: KernelMessage.IExecuteRequest,
+    content: KernelMessage.IExecuteRequestMsg['content'],
     disposeOnDone: boolean = true,
     metadata?: JSONObject
   ): Kernel.IFuture<
@@ -544,7 +547,7 @@ export class DefaultKernel implements Kernel.IKernel {
    * received and validated.
    */
   requestIsComplete(
-    content: KernelMessage.IIsCompleteRequest
+    content: KernelMessage.IIsCompleteRequestMsg['content']
   ): Promise<KernelMessage.IIsCompleteReplyMsg> {
     let msg = KernelMessage.createMessage({
       msgType: 'is_complete_request',
@@ -566,7 +569,7 @@ export class DefaultKernel implements Kernel.IKernel {
    * received and validated.
    */
   requestCommInfo(
-    content: KernelMessage.ICommInfoRequest
+    content: KernelMessage.ICommInfoRequestMsg['content']
   ): Promise<KernelMessage.ICommInfoReplyMsg> {
     let msg = KernelMessage.createMessage({
       msgType: 'comm_info_request',
@@ -586,7 +589,7 @@ export class DefaultKernel implements Kernel.IKernel {
    * #### Notes
    * See [Messaging in Jupyter](https://jupyter-client.readthedocs.io/en/latest/messaging.html#messages-on-the-stdin-router-dealer-sockets).
    */
-  sendInputReply(content: KernelMessage.IInputReply): void {
+  sendInputReply(content: KernelMessage.IInputReplyMsg['content']): void {
     if (this.status === 'dead') {
       throw new Error('Kernel is dead');
     }

+ 1 - 1
packages/services/src/kernel/future.ts

@@ -154,7 +154,7 @@ export class KernelFutureHandler<
   /**
    * Send an `input_reply` message.
    */
-  sendInputReply(content: KernelMessage.IInputReply): void {
+  sendInputReply(content: KernelMessage.IInputReplyMsg['content']): void {
     this._kernel.sendInputReply(content);
   }
 

+ 8 - 8
packages/services/src/kernel/kernel.ts

@@ -206,7 +206,7 @@ export namespace Kernel {
      * received and validated.
      */
     requestComplete(
-      content: KernelMessage.ICompleteRequest
+      content: KernelMessage.ICompleteRequestMsg['content']
     ): Promise<KernelMessage.ICompleteReplyMsg>;
 
     /**
@@ -223,7 +223,7 @@ export namespace Kernel {
      * received and validated.
      */
     requestInspect(
-      content: KernelMessage.IInspectRequest
+      content: KernelMessage.IInspectRequestMsg['content']
     ): Promise<KernelMessage.IInspectReplyMsg>;
 
     /**
@@ -240,7 +240,7 @@ export namespace Kernel {
      * received and validated.
      */
     requestHistory(
-      content: KernelMessage.IHistoryRequest
+      content: KernelMessage.IHistoryRequestMsg['content']
     ): Promise<KernelMessage.IHistoryReplyMsg>;
 
     /**
@@ -265,7 +265,7 @@ export namespace Kernel {
      * **See also:** [[IExecuteReply]]
      */
     requestExecute(
-      content: KernelMessage.IExecuteRequest,
+      content: KernelMessage.IExecuteRequestMsg['content'],
       disposeOnDone?: boolean,
       metadata?: JSONObject
     ): Kernel.IFuture<
@@ -287,7 +287,7 @@ export namespace Kernel {
      * received and validated.
      */
     requestIsComplete(
-      content: KernelMessage.IIsCompleteRequest
+      content: KernelMessage.IIsCompleteRequestMsg['content']
     ): Promise<KernelMessage.IIsCompleteReplyMsg>;
 
     /**
@@ -304,7 +304,7 @@ export namespace Kernel {
      * received and validated.
      */
     requestCommInfo(
-      content: KernelMessage.ICommInfoRequest
+      content: KernelMessage.ICommInfoRequestMsg['content']
     ): Promise<KernelMessage.ICommInfoReplyMsg>;
 
     /**
@@ -315,7 +315,7 @@ export namespace Kernel {
      * #### Notes
      * See [Messaging in Jupyter](https://jupyter-client.readthedocs.io/en/latest/messaging.html#messages-on-the-stdin-router-dealer-sockets).
      */
-    sendInputReply(content: KernelMessage.IInputReply): void;
+    sendInputReply(content: KernelMessage.IInputReplyMsg['content']): void;
 
     /**
      * Connect to a comm, or create a new one.
@@ -830,7 +830,7 @@ export namespace Kernel {
     /**
      * Send an `input_reply` message.
      */
-    sendInputReply(content: KernelMessage.IInputReply): void;
+    sendInputReply(content: KernelMessage.IInputReplyMsg['content']): void;
   }
 
   /**

+ 258 - 282
packages/services/src/kernel/messages.ts

@@ -233,34 +233,34 @@ export namespace KernelMessage {
    */
   export interface IMessage<MSGTYPE extends MessageType = MessageType> {
     /**
-     * The message header.
+     * An optional list of binary buffers.
      */
-    header: IHeader<MSGTYPE>;
+    buffers?: (ArrayBuffer | ArrayBufferView)[];
 
     /**
-     * The parent message
+     * The channel on which the message is transmitted.
      */
-    parent_header: IHeader | {};
+    channel: Channel;
 
     /**
-     * Metadata associated with the message.
+     * The content of the message.
      */
-    metadata: JSONObject;
+    content: Message['content'];
 
     /**
-     * The content of the message.
+     * The message header.
      */
-    content: MessageContent;
+    header: IHeader<MSGTYPE>;
 
     /**
-     * The channel on which the message is transmitted.
+     * Metadata associated with the message.
      */
-    channel: Channel;
+    metadata: JSONObject;
 
     /**
-     * An optional list of binary buffers.
+     * The parent message
      */
-    buffers?: (ArrayBuffer | ArrayBufferView)[];
+    parent_header: IHeader | {};
   }
 
   /**
@@ -319,7 +319,9 @@ export namespace KernelMessage {
     | IStreamMsg
     | IUpdateDisplayDataMsg;
 
-  export type MessageContent<T extends Message = Message> = T['content'];
+  //////////////////////////////////////////////////
+  // IOPub Messages
+  /////////////////////////////////////////////////
 
   /**
    * A `'stream'` message on the `'iopub'` channel.
@@ -478,6 +480,10 @@ export namespace KernelMessage {
     return msg.header.msg_type === 'clear_output';
   }
 
+  //////////////////////////////////////////////////
+  // Comm Messages
+  /////////////////////////////////////////////////
+
   /**
    * A `'comm_open'` message on the `'iopub'` channel.
    *
@@ -487,53 +493,21 @@ export namespace KernelMessage {
     T extends 'shell' | 'iopub' = 'iopub' | 'shell'
   > extends IMessage<'comm_open'> {
     channel: T;
-    content: ICommOpen;
-  }
-
-  /**
-   * A `'comm_open'` message on the `'iopub'` channel.
-   *
-   * See [Comm open](https://jupyter-client.readthedocs.io/en/latest/messaging.html#opening-a-comm).
-   */
-  export interface ICommOpenIOPubMsg extends IIOPubMessage<'comm_open'> {
-    channel: 'iopub';
-    content: ICommOpen;
-  }
-
-  /**
-   * A `'comm_open'` message on the `'shell'` channel.
-   *
-   * See [Comm open](https://jupyter-client.readthedocs.io/en/latest/messaging.html#opening-a-comm).
-   */
-  export interface ICommOpenShellMsg extends IShellMessage<'comm_open'> {
-    channel: 'shell';
-    content: ICommOpen;
-  }
-
-  /**
-   * The content of a `'comm_open'` message.  The message can
-   * be received on the `'iopub'` channel or send on the `'shell'` channel.
-   *
-   * See [Comm open](https://jupyter-client.readthedocs.io/en/latest/messaging.html#opening-a-comm).
-   */
-  export interface ICommOpen {
-    comm_id: string;
-    target_name: string;
-    data: JSONObject;
-    target_module?: string;
+    content: {
+      comm_id: string;
+      target_name: string;
+      data: JSONObject;
+      target_module?: string;
+    };
   }
 
   /**
    * Test whether a kernel message is a `'comm_open'` message.
    */
-  export function isCommOpenMsg(
-    msg: IMessage
-  ): msg is ICommOpenIOPubMsg | ICommOpenShellMsg {
+  export function isCommOpenMsg(msg: IMessage): msg is ICommOpenMsg {
     return msg.header.msg_type === 'comm_open';
   }
 
-  export type iopubshell = 'iopub' | 'shell';
-
   /**
    * A `'comm_close'` message on the `'iopub'` channel.
    *
@@ -543,18 +517,10 @@ export namespace KernelMessage {
     T extends 'iopub' | 'shell' = 'iopub' | 'shell'
   > extends IMessage<'comm_close'> {
     channel: T;
-    content: ICommClose;
-  }
-
-  /**
-   * The content of a `'comm_close'` method.  The message can
-   * be received on the `'iopub'` channel or send on the `'shell'` channel.
-   *
-   * See [Comm close](https://jupyter-client.readthedocs.io/en/latest/messaging.html#opening-a-comm).
-   */
-  export interface ICommClose {
-    comm_id: string;
-    data: JSONObject;
+    content: {
+      comm_id: string;
+      data: JSONObject;
+    };
   }
 
   /**
@@ -574,29 +540,72 @@ export namespace KernelMessage {
   export interface ICommMsgMsg<T extends 'iopub' | 'shell' = 'iopub' | 'shell'>
     extends IMessage<'comm_msg'> {
     channel: T;
-    content: ICommMsg;
+    content: {
+      comm_id: string;
+      data: JSONObject;
+    };
   }
 
   /**
-   * The content of a `'comm_msg'` message.  The message can
-   * be received on the `'iopub'` channel or send on the `'shell'` channel.
+   * Test whether a kernel message is a `'comm_msg'` message.
+   */
+  export function isCommMsgMsg(msg: IMessage): msg is ICommMsgMsg {
+    return msg.header.msg_type === 'comm_msg';
+  }
+
+  //////////////////////////////////////////////////
+  // Shell Messages
+  /////////////////////////////////////////////////
+
+  /**
+   * Reply content indicating a sucessful request.
+   */
+  export interface IReplyOkContent {
+    status: 'ok';
+  }
+
+  /**
+   * Reply content indicating an error.
    *
-   * See [Comm msg](https://jupyter-client.readthedocs.io/en/latest/messaging.html#opening-a-comm).
+   * See the [Message spec](https://jupyter-client.readthedocs.io/en/latest/messaging.html#request-reply) for details.
    */
-  export interface ICommMsg {
-    comm_id: string;
-    data: JSONObject;
+  export interface IReplyErrorContent {
+    status: 'error';
+
+    /**
+     * Exception name
+     */
+    ename: string;
+
+    /**
+     * Exception value
+     */
+    evalue: string;
+
+    /**
+     * Traceback
+     */
+    traceback: string[];
   }
 
   /**
-   * Test whether a kernel message is a `'comm_msg'` message.
+   * Reply content indicating an aborted request.
+   *
+   * This is [deprecated](https://jupyter-client.readthedocs.io/en/latest/messaging.html#request-reply)
+   * in message spec 5.1. Kernels should send an 'error' reply instead.
    */
-  export function isCommMsgMsg(
-    msg: IMessage
-  ): msg is ICommMsgMsg<'iopub' | 'shell'> {
-    return msg.header.msg_type === 'comm_msg';
+  export interface IReplyAbortContent {
+    status: 'abort';
   }
 
+  /**
+   * A convenience type for reply content.
+   *
+   * This automatically unions the necessary error and abort replies required in
+   * the [message spec](https://jupyter-client.readthedocs.io/en/latest/messaging.html#request-reply).
+   */
+  type ReplyContent<T> = T | IReplyErrorContent | IReplyAbortContent;
+
   /**
    * A `'kernel_info_request'` message on the `'shell'` channel.
    *
@@ -615,21 +624,11 @@ export namespace KernelMessage {
   }
 
   /**
-   * A `'kernel_info_reply'` message on the `'shell'` channel.
-   *
-   * See [Messaging in Jupyter](https://jupyter-client.readthedocs.io/en/latest/messaging.html#kernel-info).
-   */
-  export interface IInfoReplyMsg extends IShellMessage<'kernel_info_reply'> {
-    parent_header: IHeader<'kernel_info_request'>;
-    content: IInfoReply;
-  }
-
-  /**
-   * The kernel info content.
+   * A `'kernel_info_reply'` message content.
    *
    * See [Messaging in Jupyter](https://jupyter-client.readthedocs.io/en/latest/messaging.html#kernel-info).
    */
-  export interface IInfoReply {
+  export interface IInfoReply extends IReplyOkContent {
     protocol_version: string;
     implementation: string;
     implementation_version: string;
@@ -648,6 +647,16 @@ export namespace KernelMessage {
     nbconverter_exporter?: string;
   }
 
+  /**
+   * A `'kernel_info_reply'` message on the `'shell'` channel.
+   *
+   * See [Messaging in Jupyter](https://jupyter-client.readthedocs.io/en/latest/messaging.html#kernel-info).
+   */
+  export interface IInfoReplyMsg extends IShellMessage<'kernel_info_reply'> {
+    parent_header: IHeader<'kernel_info_request'>;
+    content: ReplyContent<IInfoReply>;
+  }
+
   /**
    * A  `'complete_request'` message.
    *
@@ -657,23 +666,28 @@ export namespace KernelMessage {
    */
   export interface ICompleteRequestMsg
     extends IShellMessage<'complete_request'> {
-    content: ICompleteRequest;
+    content: {
+      code: string;
+      cursor_pos: number;
+    };
   }
 
   /**
-   * The content of a  `'complete_request'` message.
+   * A `'complete_reply'` message content.
    *
    * See [Messaging in Jupyter](https://jupyter-client.readthedocs.io/en/latest/messaging.html#completion).
    *
-   * **See also:** [[ICompleteReply]], [[IKernel.complete]]
+   * **See also:** [[ICompleteRequest]], [[IKernel.complete]]
    */
-  export interface ICompleteRequest {
-    code: string;
-    cursor_pos: number;
+  interface ICompleteReply extends IReplyOkContent {
+    matches: string[];
+    cursor_start: number;
+    cursor_end: number;
+    metadata: JSONObject;
   }
 
   /**
-   * A `'complete_reply'` message on the `'stream'` channel.
+   * A `'complete_reply'` message on the `'shell'` channel.
    *
    * See [Messaging in Jupyter](https://jupyter-client.readthedocs.io/en/latest/messaging.html#completion).
    *
@@ -681,13 +695,7 @@ export namespace KernelMessage {
    */
   export interface ICompleteReplyMsg extends IShellMessage<'complete_reply'> {
     parent_header: IHeader<'complete_request'>;
-    content: {
-      matches: string[];
-      cursor_start: number;
-      cursor_end: number;
-      metadata: JSONObject;
-      status: 'ok' | 'error';
-    };
+    content: ReplyContent<ICompleteReply>;
   }
 
   /**
@@ -698,24 +706,29 @@ export namespace KernelMessage {
    * **See also:** [[IInspectReplyMsg]], [[[IKernel.inspect]]]
    */
   export interface IInspectRequestMsg extends IShellMessage<'inspect_request'> {
-    content: IInspectRequest;
+    content: {
+      code: string;
+      cursor_pos: number;
+      detail_level: 0 | 1;
+    };
   }
 
   /**
-   * The content of an `'inspect_request'` message.
+   * A `'inspect_reply'` message content.
    *
    * See [Messaging in Jupyter](https://jupyter-client.readthedocs.io/en/latest/messaging.html#introspection).
    *
-   * **See also:** [[IInspectReply]], [[[IKernel.inspect]]]
+   * **See also:** [[IInspectRequest]], [[IKernel.inspect]]
    */
-  export interface IInspectRequest {
-    code: string;
-    cursor_pos: number;
-    detail_level: 0 | 1;
+
+  export interface IInspectReply extends IReplyOkContent {
+    found: boolean;
+    data: JSONObject;
+    metadata: JSONObject;
   }
 
   /**
-   * A `'inspect_reply'` message on the `'stream'` channel.
+   * A `'inspect_reply'` message on the `'shell'` channel.
    *
    * See [Messaging in Jupyter](https://jupyter-client.readthedocs.io/en/latest/messaging.html#introspection).
    *
@@ -723,12 +736,7 @@ export namespace KernelMessage {
    */
   export interface IInspectReplyMsg extends IShellMessage<'inspect_reply'> {
     parent_header: IHeader<'inspect_request'>;
-    content: {
-      status: 'ok' | 'error';
-      found: boolean;
-      data: JSONObject;
-      metadata: JSONObject;
-    };
+    content: ReplyContent<IInspectReply>;
   }
 
   /**
@@ -739,14 +747,9 @@ export namespace KernelMessage {
    * **See also:** [[IHistoryReplyMsg]], [[[IKernel.history]]]
    */
   export interface IHistoryRequestMsg extends IShellMessage<'history_request'> {
-    content: IHistoryRequest;
+    content: IHistoryRequestRange | IHistoryRequestSearch | IHistoryRequestTail;
   }
 
-  /**
-   * The history access settings.
-   */
-  export type HistAccess = 'range' | 'tail' | 'search';
-
   /**
    * The content of a `'history_request'` range message.
    *
@@ -764,49 +767,48 @@ export namespace KernelMessage {
   }
 
   /**
-   * The content of a `'history_request'` tail message.
+   * The content of a `'history_request'` search message.
    *
    * See [Messaging in Jupyter](https://jupyter-client.readthedocs.io/en/latest/messaging.html#history).
    *
    * **See also:** [[IHistoryReply]], [[[IKernel.history]]]
    */
-  export interface IHistoryRequestTail {
+  export interface IHistoryRequestSearch {
     output: boolean;
     raw: boolean;
-    hist_access_type: 'tail';
+    hist_access_type: 'search';
     n: number;
+    pattern: string;
+    unique: boolean;
   }
 
   /**
-   * The content of a `'history_request'` search message.
+   * The content of a `'history_request'` tail message.
    *
    * See [Messaging in Jupyter](https://jupyter-client.readthedocs.io/en/latest/messaging.html#history).
    *
    * **See also:** [[IHistoryReply]], [[[IKernel.history]]]
    */
-  export interface IHistoryRequestSearch {
+  export interface IHistoryRequestTail {
     output: boolean;
     raw: boolean;
-    hist_access_type: 'search';
+    hist_access_type: 'tail';
     n: number;
-    pattern: string;
-    unique: boolean;
   }
 
   /**
-   * The content of a `'history_request'` message.
+   * A `'history_reply'` message content.
    *
    * See [Messaging in Jupyter](https://jupyter-client.readthedocs.io/en/latest/messaging.html#history).
    *
-   * **See also:** [[IHistoryReply]], [[[IKernel.history]]]
+   * **See also:** [[IHistoryRequest]], [[IKernel.history]]
    */
-  export type IHistoryRequest =
-    | IHistoryRequestRange
-    | IHistoryRequestTail
-    | IHistoryRequestSearch;
+  export interface IHistoryReply extends IReplyOkContent {
+    history: [number, number, string][] | [number, number, [string, string]][];
+  }
 
   /**
-   * A `'history_reply'` message on the `'stream'` channel.
+   * A `'history_reply'` message on the `'shell'` channel.
    *
    * See [Messaging in Jupyter](https://jupyter-client.readthedocs.io/en/latest/messaging.html#history).
    *
@@ -814,11 +816,7 @@ export namespace KernelMessage {
    */
   export interface IHistoryReplyMsg extends IShellMessage<'history_reply'> {
     parent_header: IHeader<'history_request'>;
-    content: {
-      history:
-        | [number, number, string][]
-        | [number, number, [string, string]][];
-    };
+    content: ReplyContent<IHistoryReply>;
   }
 
   /**
@@ -830,18 +828,9 @@ export namespace KernelMessage {
    */
   export interface IIsCompleteRequestMsg
     extends IShellMessage<'is_complete_request'> {
-    content: IIsCompleteRequest;
-  }
-
-  /**
-   * The content of an `'is_complete_request'` message.
-   *
-   * See [Messaging in Jupyter](https://jupyter-client.readthedocs.io/en/latest/messaging.html#code-completeness).
-   *
-   * **See also:** [[IIsCompleteReply]], [[IKernel.isComplete]]
-   */
-  export interface IIsCompleteRequest {
-    code: string;
+    content: {
+      code: string;
+    };
   }
 
   /**
@@ -854,78 +843,65 @@ export namespace KernelMessage {
   export interface IIsCompleteReplyMsg
     extends IShellMessage<'is_complete_reply'> {
     parent_header: IHeader<'is_complete_request'>;
-    content: {
-      status: string;
-      indent: string;
-    };
+    content: ReplyContent<IIsCompleteReplyIncomplete | IIsCompleteReplyOther>;
   }
 
   /**
-   * An `execute_request` message on the `
+   * An 'incomplete' completion reply
    */
-  export interface IExecuteRequestMsg extends IShellMessage<'execute_request'> {
-    content: IExecuteRequest;
+  export interface IIsCompleteReplyIncomplete {
+    status: 'incomplete';
+    indent: string;
   }
 
   /**
-   * The content of an `'execute_request'` message.
-   *
-   * See [Messaging in Jupyter](https://jupyter-client.readthedocs.io/en/latest/messaging.html#execute).
-   *
-   * **See also:** [[IExecuteReply]], [[IKernel.execute]]
+   * A completion reply for completion or invalid states.
    */
-  export interface IExecuteRequest extends IExecuteOptions {
-    code: string;
+  export interface IIsCompleteReplyOther {
+    status: 'complete' | 'invalid' | 'unknown';
   }
 
   /**
-   * The options used to configure an execute request.
-   *
-   * See [Messaging in Jupyter](https://jupyter-client.readthedocs.io/en/latest/messaging.html#execute).
+   * An `execute_request` message on the `
    */
-  export interface IExecuteOptions {
-    /**
-     * Whether to execute the code as quietly as possible.
-     * The default is `false`.
-     */
-    silent?: boolean;
+  export interface IExecuteRequestMsg extends IShellMessage<'execute_request'> {
+    content: {
+      /**
+       * The code to execute.
+       */
+      code: string;
 
-    /**
-     * Whether to store history of the execution.
-     * The default `true` if silent is False.
-     * It is forced to  `false ` if silent is `true`.
-     */
-    store_history?: boolean;
+      /**
+       * Whether to execute the code as quietly as possible.
+       * The default is `false`.
+       */
+      silent?: boolean;
 
-    /**
-     * A mapping of names to expressions to be evaluated in the
-     * kernel's interactive namespace.
-     */
-    user_expressions?: JSONObject;
+      /**
+       * Whether to store history of the execution.
+       * The default `true` if silent is False.
+       * It is forced to  `false ` if silent is `true`.
+       */
+      store_history?: boolean;
 
-    /**
-     * Whether to allow stdin requests.
-     * The default is `true`.
-     */
-    allow_stdin?: boolean;
+      /**
+       * A mapping of names to expressions to be evaluated in the
+       * kernel's interactive namespace.
+       */
+      user_expressions?: JSONObject;
 
-    /**
-     * Whether to the abort execution queue on an error.
-     * The default is `false`.
-     */
-    stop_on_error?: boolean;
-  }
+      /**
+       * Whether to allow stdin requests.
+       * The default is `true`.
+       */
+      allow_stdin?: boolean;
 
-  /**
-   * An `'execute_reply'` message on the `'stream'` channel.
-   *
-   * See [Messaging in Jupyter](https://jupyter-client.readthedocs.io/en/latest/messaging.html#execution-results).
-   *
-   * **See also:** [[IExecuteRequest]], [[IKernel.execute]]
-   */
-  export interface IExecuteReplyMsg extends IShellMessage<'execute_reply'> {
-    parent_header: IHeader<'execute_request'>;
-    content: IExecuteReply;
+      /**
+       * Whether to the abort execution queue on an error.
+       * The default is `false`.
+       */
+      stop_on_error?: boolean;
+    };
   }
 
   /**
@@ -933,17 +909,21 @@ export namespace KernelMessage {
    *
    * See [Messaging in Jupyter](https://jupyter-client.readthedocs.io/en/latest/messaging.html#execution-results).
    */
-  export interface IExecuteReply {
-    status: 'ok' | 'error' | 'abort';
+  export interface IExecuteCount {
     execution_count: nbformat.ExecutionCount;
   }
 
+  /**
+   * A convenience type for a base for an execute reply content.
+   */
+  type IExecuteReplyBase = IExecuteCount & IReplyOkContent;
+
   /**
    * The `'execute_reply'` contents for an `'ok'` status.
    *
    * See [Messaging in Jupyter](https://jupyter-client.readthedocs.io/en/latest/messaging.html#execution-results).
    */
-  export interface IExecuteOkReply extends IExecuteReply {
+  export interface IExecuteReply extends IExecuteReplyBase {
     /**
      * A list of payload objects.
      * Payloads are considered deprecated.
@@ -959,25 +939,15 @@ export namespace KernelMessage {
   }
 
   /**
-   * The `'execute_reply'` contents for an `'error'` status.
+   * An `'execute_reply'` message on the `'stream'` channel.
    *
    * See [Messaging in Jupyter](https://jupyter-client.readthedocs.io/en/latest/messaging.html#execution-results).
+   *
+   * **See also:** [[IExecuteRequest]], [[IKernel.execute]]
    */
-  export interface IExecuteErrorReply extends IExecuteReply {
-    /**
-     * The exception name.
-     */
-    ename: string;
-
-    /**
-     * The Exception value.
-     */
-    evalue: string;
-
-    /**
-     * A list of traceback frames.
-     */
-    traceback: string[];
+  export interface IExecuteReplyMsg extends IShellMessage<'execute_reply'> {
+    parent_header: IHeader<'execute_request'>;
+    content: ReplyContent<IExecuteReply> & IExecuteCount;
   }
 
   /**
@@ -988,95 +958,101 @@ export namespace KernelMessage {
   }
 
   /**
-   * An `'input_request'` message on the `'stdin'` channel.
+   * A `'comm_info_request'` message on the `'shell'` channel.
    *
-   * See [Messaging in Jupyter](https://jupyter-client.readthedocs.io/en/latest/messaging.html#messages-on-the-stdin-router-dealer-sockets).
+   * See [Messaging in Jupyter](https://jupyter-client.readthedocs.io/en/latest/messaging.html#comm-info).
+   *
+   * **See also:** [[ICommInfoReplyMsg]], [[IKernel.commInfo]]
    */
-  export interface IInputRequestMsg extends IStdinMessage<'input_request'> {
-    content: IInputRequest;
+
+  export interface ICommInfoRequestMsg
+    extends IShellMessage<'comm_info_request'> {
+    content: {
+      target?: string;
+    };
   }
 
   /**
-   * The content of an `'input_request'` message.
+   * A `'comm_info_reply'` message content.
+   *
+   * See [Messaging in Jupyter](https://jupyter-client.readthedocs.io/en/latest/messaging.html#comm-info).
+   *
+   * **See also:** [[ICommInfoRequest]], [[IKernel.commInfo]]
    */
-  export interface IInputRequest {
-    /**
-     * The text to show at the prompt.
-     */
-    prompt: string;
 
+  export interface ICommInfoReply extends IReplyOkContent {
     /**
-     * Whether the request is for a password.
-     * If so, the frontend shouldn't echo input.
+     * Mapping of comm ids to target names.
      */
-    password: boolean;
+    comms: { [commId: string]: { target_name: string } };
   }
 
   /**
-   * Test whether a kernel message is an `'input_request'` message.
+   * A `'comm_info_reply'` message on the `'shell'` channel.
+   *
+   * See [Messaging in Jupyter](https://jupyter-client.readthedocs.io/en/latest/messaging.html#comm-info).
+   *
+   * **See also:** [[ICommInfoRequestMsg]], [[IKernel.commInfo]]
    */
-  export function isInputRequestMsg(msg: IMessage): msg is IInputRequestMsg {
-    return msg.header.msg_type === 'input_request';
+  export interface ICommInfoReplyMsg extends IShellMessage<'comm_info_reply'> {
+    parent_header: IHeader<'comm_info_request'>;
+    content: ReplyContent<ICommInfoReply>;
   }
 
+  //////////////////////////////////////////////////
+  // Stdin Messages
+  /////////////////////////////////////////////////
+
   /**
-   * An `'input_reply'` message on the `'stdin'` channel.
+   * An `'input_request'` message on the `'stdin'` channel.
    *
    * See [Messaging in Jupyter](https://jupyter-client.readthedocs.io/en/latest/messaging.html#messages-on-the-stdin-router-dealer-sockets).
    */
-  export interface IInputReplyMsg extends IStdinMessage<'input_reply'> {
-    parent_header: IHeader<'input_request'>;
-    content: IInputReply;
+  export interface IInputRequestMsg extends IStdinMessage<'input_request'> {
+    content: {
+      /**
+       * The text to show at the prompt.
+       */
+      prompt: string;
+
+      /**
+       * Whether the request is for a password.
+       * If so, the frontend shouldn't echo input.
+       */
+      password: boolean;
+    };
   }
 
   /**
-   * The content of an `'input_reply'` message.
-   *
-   * See [Messaging in Jupyter](https://jupyter-client.readthedocs.io/en/latest/messaging.html#messages-on-the-stdin-router-dealer-sockets).
-   *
-   * **See also:** [[IKernel.input_reply]]
+   * Test whether a kernel message is an `'input_request'` message.
    */
-  export interface IInputReply {
-    value: string;
+  export function isInputRequestMsg(msg: IMessage): msg is IInputRequestMsg {
+    return msg.header.msg_type === 'input_request';
   }
 
   /**
-   * Test whether a kernel message is an `'input_reply'` message.
+   * An `'input_reply'` message content.
+   *
+   * See [Messaging in Jupyter](https://jupyter-client.readthedocs.io/en/latest/messaging.html#messages-on-the-stdin-router-dealer-sockets).
    */
-  export function isInputReplyMsg(msg: IMessage): msg is IInputReplyMsg {
-    return msg.header.msg_type === 'input_reply';
-  }
-
-  export interface ICommInfoRequestMsg
-    extends IShellMessage<'comm_info_request'> {
-    content: ICommInfoRequest;
+  export interface IInputReply extends IReplyOkContent {
+    value: string;
   }
 
   /**
-   * The content of a `'comm_info_request'` message.
-   *
-   * See [Messaging in Jupyter](https://jupyter-client.readthedocs.io/en/latest/messaging.html#comm-info).
+   * An `'input_reply'` message on the `'stdin'` channel.
    *
-   * **See also:** [[ICommInfoReply]], [[IKernel.commInfo]]
+   * See [Messaging in Jupyter](https://jupyter-client.readthedocs.io/en/latest/messaging.html#messages-on-the-stdin-router-dealer-sockets).
    */
-  export interface ICommInfoRequest {
-    target?: string;
+  export interface IInputReplyMsg extends IStdinMessage<'input_reply'> {
+    parent_header: IHeader<'input_request'>;
+    content: ReplyContent<IInputReply>;
   }
 
   /**
-   * A `'comm_info_reply'` message on the `'stream'` channel.
-   *
-   * See [Messaging in Jupyter](https://jupyter-client.readthedocs.io/en/latest/messaging.html#comm-info).
-   *
-   * **See also:** [[ICommInfoRequest]], [[IKernel.commInfo]]
+   * Test whether a kernel message is an `'input_reply'` message.
    */
-  export interface ICommInfoReplyMsg extends IShellMessage<'comm_info_reply'> {
-    parent_header: IHeader<'comm_info_request'>;
-    content: {
-      /**
-       * Mapping of comm ids to target names.
-       */
-      comms: { [commId: string]: { target_name: string } };
-    };
+  export function isInputReplyMsg(msg: IMessage): msg is IInputReplyMsg {
+    return msg.header.msg_type === 'input_reply';
   }
 }

+ 1 - 1
packages/tooltip-extension/src/index.ts

@@ -301,7 +301,7 @@ namespace Private {
       return Promise.reject(void 0);
     }
 
-    let contents: KernelMessage.IInspectRequest = {
+    let contents: KernelMessage.IInspectRequestMsg['content'] = {
       code,
       cursor_pos: offset,
       detail_level: detail || 0

+ 1 - 1
tests/test-services/src/kernel/ikernel.spec.ts

@@ -791,7 +791,7 @@ describe('Kernel.IKernel', () => {
 
   describe('#requestIsComplete()', () => {
     it('should resolve the promise', async () => {
-      const options: KernelMessage.IIsCompleteRequest = {
+      const options: KernelMessage.IIsCompleteRequestMsg['content'] = {
         code: 'hello'
       };
       await defaultKernel.requestIsComplete(options);

+ 1 - 1
tests/test-services/src/utils.ts

@@ -58,7 +58,7 @@ export function makeSettings(
   return ServerConnection.makeSettings(settings);
 }
 
-const EXAMPLE_KERNEL_INFO: KernelMessage.IInfoReply = {
+const EXAMPLE_KERNEL_INFO: KernelMessage.IInfoReplyMsg['content'] = {
   protocol_version: '1',
   implementation: 'a',
   implementation_version: '1',