Skip to content

997 show console in notebook as it is running#1120

Merged
johbaxter merged 2 commits intodevfrom
997-show-console-in-notebook-as-it-is-running
May 15, 2025
Merged

997 show console in notebook as it is running#1120
johbaxter merged 2 commits intodevfrom
997-show-console-in-notebook-as-it-is-running

Conversation

@JaganSomannaKanini
Copy link
Copy Markdown
Contributor

Description

When we have multiple print statements in a cell, now we can see the output one after the other.

Changes Made

Added a condition for the code cell to display the output one after the other.

How to Test

The code given in the ticket is small to display the output one after the other, so we have to use a delay to see the changes in the output.

Notes

To add delay use "import time" in the first line and use "time.sleep(1)" in between the print statements. This will create 1 second delay.

@JaganSomannaKanini JaganSomannaKanini requested a review from a team as a code owner May 13, 2025 13:52
@JaganSomannaKanini JaganSomannaKanini linked an issue May 13, 2025 that may be closed by this pull request
@github-actions
Copy link
Copy Markdown

@CodiumAI-Agent /describe

@QodoAI-Agent
Copy link
Copy Markdown

Title

997 show console in notebook as it is running


User description

Description

When we have multiple print statements in a cell, now we can see the output one after the other.

Changes Made

Added a condition for the code cell to display the output one after the other.

How to Test

The code given in the ticket is small to display the output one after the other, so we have to use a delay to see the changes in the output.

Notes

To add delay use "import time" in the first line and use "time.sleep(1)" in between the print statements. This will create 1 second delay.


PR Type

Enhancement


Description

  • Split cell actions for code vs non-code widgets

  • Show console only if messages exist

  • Wrap console output under code cells only

  • Preserve non-code cell behavior


Changes walkthrough 📝

Relevant files
Enhancement
NotebookCell.tsx
Refactor notebook cell console rendering                                 

packages/client/src/components/notebook/NotebookCell.tsx

  • Introduced cell.widget === 'code' branch
  • Added cell.messages.length check before rendering
  • Restructured StyledCardActions rendering logic
  • Moved Divider into conditional branches
  • +107/-44

    Need help?
  • Type /help how to ... in the comments thread for any questions about PR-Agent usage.
  • Check out the documentation for more information.
  • @github-actions
    Copy link
    Copy Markdown

    @CodiumAI-Agent /review

    @QodoAI-Agent
    Copy link
    Copy Markdown

    PR Reviewer Guide 🔍

    Here are some key observations to aid the review process:

    ⏱️ Estimated effort to review: 3 🔵🔵🔵⚪⚪
    🧪 No relevant tests
    🔒 No security concerns identified
    ⚡ Recommended focus areas for review

    UI Duplication

    The rendering logic for executed cells is duplicated almost verbatim in two branches (for 'code' widgets and others). Consider refactoring into a shared component or helper to reduce code duplication and ease maintenance.

    {cell.widget === 'code' ? (
        <>
            {cell.messages.length > 0 && (
                <>
                    {(notebook?.selectedCell?.id ?? '') ==
                        cell.id && <Divider />}
                    <StyledCardActions
                        id={`notebook-cell-${queryId}-${cellId}-card-actions`}
                        ref={cardActionsRef}
                    >
                        <Stack
                            id={`notebook-cell-actions-${queryId}-${cellId}`}
                            direction="column"
                            width="100%"
                        >
                            <Stack
                                direction="row"
                                alignItems="center"
                                width="100%"
                            >
                                {getExecutionLabel()}
                            </Stack>
                            {outputExpanded && (
                                <>
                                    <NotebookCellConsole
                                        messages={
                                            cell.messages
                                        }
                                    />
                                    {cell.isExecuted
                                        ? cell.operation.map(
                                              (o, oIdx) => {
                                                  return (
                                                      <Operation
                                                          key={
                                                              oIdx
                                                          }
                                                          operation={
                                                              o
                                                          }
                                                          output={
                                                              cell.output
                                                          }
                                                      />
                                                  );
                                              },
                                          )
                                        : null}
                                </>
                            )}
                        </Stack>
                    </StyledCardActions>
                </>
            )}
        </>
    ) : (
        <>
            {cell.isExecuted && (
                <>
                    {(notebook?.selectedCell?.id ?? '') ==
                        cell.id && <Divider />}
                    <StyledCardActions
                        id={`notebook-cell-${queryId}-${cellId}-card-actions`}
                        ref={cardActionsRef}
                    >
                        <Stack
                            id={`notebook-cell-actions-${queryId}-${cellId}`}
                            direction="column"
                            width="100%"
                        >
                            <Stack
                                direction="row"
                                alignItems="center"
                                width="100%"
                            >
                                {getExecutionLabel()}
                            </Stack>
                            {outputExpanded && (
                                <>
                                    <NotebookCellConsole
                                        messages={
                                            cell.messages
                                        }
                                    />
                                    {cell.isExecuted
                                        ? cell.operation.map(
                                              (o, oIdx) => {
                                                  return (
                                                      <Operation
                                                          key={
                                                              oIdx
                                                          }
                                                          operation={
                                                              o
                                                          }
                                                          output={
                                                              cell.output
                                                          }
                                                      />
                                                  );
                                              },
                                          )
                                        : null}
                                </>
                            )}
                        </Stack>
                    </StyledCardActions>
                </>
            )}
        </>
    )}
    React Key Usage

    The Operation components use the array index (oIdx) as the React key. This can cause rendering issues when operations change order. Use a stable unique identifier if available.

            <Operation
                key={
                    oIdx
                }
                operation={
                    o
                }
                output={
                    cell.output
                }
            />
        );
    },

    @github-actions
    Copy link
    Copy Markdown

    @CodiumAI-Agent /improve

    @QodoAI-Agent
    Copy link
    Copy Markdown

    QodoAI-Agent commented May 13, 2025

    PR Code Suggestions ✨

    Latest suggestions up to a9dfd6a

    CategorySuggestion                                                                                                                                    Impact
    Possible issue
    Always show actions when executed

    The UI for executed code cells will be hidden if there are no messages; switch the
    gate to cell.isExecuted so actions still appear even when the cell has no console
    output. This restores the original behavior for zero-message executions.

    packages/client/src/components/notebook/NotebookCell.tsx [785]

    -{cell.messages.length > 0 && (
    +{cell.isExecuted && (
    Suggestion importance[1-10]: 6

    __

    Why: The new gate on cell.messages.length hides the action UI for executed cells with no messages; using cell.isExecuted restores the original behavior so users can still interact with empty executions.

    Low
    General
    Use stable keys for operations

    Relying on the index as a React key can lead to rendering issues when the operations
    array changes; use a unique identifier from the operation object (e.g. o.id) if
    available.

    packages/client/src/components/notebook/NotebookCell.tsx [816-826]

     <Operation
    -    key={oIdx}
    +    key={o.id}
         operation={o}
         output={cell.output}
     />
    Suggestion importance[1-10]: 5

    __

    Why: Replacing the index oIdx with a unique o.id prevents React reconciliation issues when the operations list changes.

    Low
    Enforce strict ID comparison

    Use strict equality (===) when comparing IDs to avoid unintended truthy/falsey
    matches and ensure type safety.

    packages/client/src/components/notebook/NotebookCell.tsx [787-788]

    -(notebook?.selectedCell?.id ?? '') == cell.id && <Divider />
    +(notebook?.selectedCell?.id ?? '') === cell.id && <Divider />
    Suggestion importance[1-10]: 4

    __

    Why: Using === ensures proper type-safe comparison of the selected cell ID and avoids unintended coercion bugs.

    Low
    Remove duplicated action blocks

    The two widget branches duplicate the same markup for StyledCardActions; extract
    this into a shared helper or subcomponent to reduce duplication and ease
    maintenance.

    packages/client/src/components/notebook/NotebookCell.tsx [789-834]

    -<StyledCardActions
    -    id={`notebook-cell-${queryId}-${cellId}-card-actions`}
    -    ref={cardActionsRef}
    ->
    -    … repeated content …
    -</StyledCardActions>
    +{renderCellActions()}
    Suggestion importance[1-10]: 3

    __

    Why: Extracting the repeated <StyledCardActions> markup into a helper would reduce duplication and improve maintainability.

    Low

    Previous suggestions

    Suggestions up to commit a9dfd6a
    CategorySuggestion                                                                                                                                    Impact
    Possible issue
    Combine execution and message guard

    Ensure the action panel still renders when a code cell has no console messages but
    has been executed. Combine the execution flag and message length in the guard.

    packages/client/src/components/notebook/NotebookCell.tsx [785]

    -{cell.messages.length > 0 && (
    +{(cell.isExecuted || cell.messages.length > 0) && (
    Suggestion importance[1-10]: 8

    __

    Why: The current guard hides action panels for executed code cells with no messages; combining cell.isExecuted and cell.messages.length ensures correct rendering.

    Medium
    General
    Extract duplicated JSX block

    Extract this repeated JSX into a standalone component (e.g. ). This centralizes the
    rendering logic for both code and non‐code cells and reduces duplication.

    packages/client/src/components/notebook/NotebookCell.tsx [789-834]

    -<StyledCardActions
    -    id={`notebook-cell-${queryId}-${cellId}-card-actions`}
    -    ref={cardActionsRef}
    ->
    -    <Stack
    -        id={`notebook-cell-actions-${queryId}-${cellId}`}
    -        direction="column"
    -        width="100%"
    -    >
    -        ...
    -    </Stack>
    -</StyledCardActions>
    +<CellActions
    +  queryId={queryId}
    +  cellId={cellId}
    +  cell={cell}
    +  outputExpanded={outputExpanded}
    +  cardActionsRef={cardActionsRef}
    +/>
    Suggestion importance[1-10]: 5

    __

    Why: Extracting the repeated <StyledCardActions> block into a component improves maintainability and reduces duplication.

    Low
    Use stable Operation keys

    Replace the array index key with a stable identifier (e.g. o.id) to prevent
    rendering issues when the list changes.

    packages/client/src/components/notebook/NotebookCell.tsx [816-826]

     <Operation
    -    key={oIdx}
    +    key={o.id ?? oIdx}
         operation={o}
         output={cell.output}
     />
    Suggestion importance[1-10]: 5

    __

    Why: Using a stable identifier like o.id reduces re-render issues compared to array index keys.

    Low
    Use strict equality for ID

    Use strict equality (===) when comparing IDs to avoid unintended type coercion.

    packages/client/src/components/notebook/NotebookCell.tsx [787]

    -{(notebook?.selectedCell?.id ?? '') == cell.id && <Divider />}
    +{(notebook?.selectedCell?.id ?? '') === cell.id && <Divider />}
    Suggestion importance[1-10]: 4

    __

    Why: Replacing == with === avoids unintended type coercion when comparing IDs.

    Low
    Suggestions up to commit a9dfd6a
    CategorySuggestion                                                                                                                                    Impact
    Possible issue
    Render UI when cell executed

    The check on cell.messages.length > 0 prevents the execution UI from showing when a
    code cell has run but produced no messages. Update the condition to use
    cell.isExecuted so that the UI renders whenever the cell has executed, regardless of
    message count.

    packages/client/src/components/notebook/NotebookCell.tsx [785-836]

    -{cell.messages.length > 0 && (
    +{cell.isExecuted && (
         <>
    -        {(notebook?.selectedCell?.id ?? '') ==
    -            cell.id && <Divider />}
    +        {(notebook?.selectedCell?.id ?? '') == cell.id && <Divider />}
             <StyledCardActions
                 id={`notebook-cell-${queryId}-${cellId}-card-actions`}
                 ref={cardActionsRef}
             >
                 ...
             </StyledCardActions>
         </>
     )}
    Suggestion importance[1-10]: 7

    __

    Why: Replacing cell.messages.length > 0 with cell.isExecuted ensures the execution UI always appears for executed code cells, improving consistency when no messages are produced.

    Medium
    General
    Extract duplicated execution UI

    This block is duplicated in both the code‐widget and non‐code‐widget branches.
    Extract the execution UI into a helper constant or function and reuse it to reduce
    repetition and simplify the JSX.

    packages/client/src/components/notebook/NotebookCell.tsx [839-892]

    -<>
    -    {cell.isExecuted && (
    -        <>
    -            {(notebook?.selectedCell?.id ?? '') ==
    -                cell.id && <Divider />}
    -            <StyledCardActions
    -                id={`notebook-cell-${queryId}-${cellId}-card-actions`}
    -                ref={cardActionsRef}
    -            >
    -                <Stack
    -                    id={`notebook-cell-actions-${queryId}-${cellId}`}
    -                    direction="column"
    -                    width="100%"
    -                >
    -                    <Stack
    -                        direction="row"
    -                        alignItems="center"
    -                        width="100%"
    -                    >
    -                        {getExecutionLabel()}
    -                    </Stack>
    -                    {outputExpanded && (
    -                        <>
    -                            <NotebookCellConsole
    -                                messages={cell.messages}
    -                            />
    -                            {cell.isExecuted
    -                                ? cell.operation.map((o, oIdx) => {
    -                                      return (
    -                                          <Operation
    -                                              key={oIdx}
    -                                              operation={o}
    -                                              output={cell.output}
    -                                          />
    -                                      );
    -                                  })
    -                                : null}
    -                        </>
    -                    )}
    -                </Stack>
    -            </StyledCardActions>
    -        </>
    -    )}
    -</>
    +const renderExecutionUI = () => (
    +    <StyledCardActions
    +        id={`notebook-cell-${queryId}-${cellId}-card-actions`}
    +        ref={cardActionsRef}
    +    >
    +        ...
    +    </StyledCardActions>
    +);
    +...
    +{cell.widget === 'code'
    +  ? (cell.isExecuted && renderExecutionUI())
    +  : (cell.isExecuted && renderExecutionUI())}
    Suggestion importance[1-10]: 6

    __

    Why: Factoring out the repeated execution UI into a helper reduces JSX duplication and improves maintainability without altering functionality.

    Low

    @ehynd
    Copy link
    Copy Markdown
    Contributor

    ehynd commented May 14, 2025

    @johbaxter ping me when you do this one and i have test code for you but it is pasting wrong here

    <StyledCardInput>{rendered}</StyledCardInput>
    </StyledCardContent>
    {cell.isExecuted && (
    {cell.widget === 'code' ? (
    Copy link
    Copy Markdown
    Contributor

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    Think about other widgets other than notebook cells. We need to be able to pull the logs for things other than python code cells

    Copy link
    Copy Markdown
    Contributor

    @johbaxter johbaxter left a comment

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    Please make sure this works for all notebook widgets. not just code.. Take a look at my comment in the code

    @JaganSomannaKanini
    Copy link
    Copy Markdown
    Contributor Author

    Sure @johbaxter , will take a look on it.

    Copy link
    Copy Markdown
    Contributor

    @johbaxter johbaxter left a comment

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    Curious about why we have to have the outer condition if cell.widget === 'code'

    image

    @johbaxter johbaxter merged commit 78d6d1e into dev May 15, 2025
    4 checks passed
    @johbaxter johbaxter deleted the 997-show-console-in-notebook-as-it-is-running branch May 15, 2025 21:33
    @github-actions
    Copy link
    Copy Markdown

    @CodiumAI-Agent /update_changelog

    @QodoAI-Agent
    Copy link
    Copy Markdown

    Changelog updates: 🔄

    2025-05-15 *

    Changed

    • Display notebook console output incrementally as code cells execute

    to commit the new content to the CHANGELOG.md file, please type:
    '/update_changelog --pr_update_changelog.push_changelog_changes=true'

    @JaganSomannaKanini
    Copy link
    Copy Markdown
    Contributor Author

    Curious about why we have to have the outer condition if cell.widget === 'code'

    image

    In the ticket it was mentioned for a long Python code @johbaxter, so the condition made sense in that manner. Without that condition it would have affected the ability to show the output for other widget cells because in some cases the output would come through console and in other case the complete output would come only after the cell is executed.

    @QodoAI-Agent
    Copy link
    Copy Markdown

    Changelog updates: 🔄

    2025-05-16 #1120

    Changed

    • Stream notebook console output so multiple print statements appear sequentially as the cell runs.

    to commit the new content to the CHANGELOG.md file, please type:
    '/update_changelog --pr_update_changelog.push_changelog_changes=true'

    johbaxter added a commit that referenced this pull request May 19, 2025
    * feat(enhancement-data-tab): updated the data tab with new style
    
    * build(toolspage): echart tools page refactor and bug fixes
    
    * feat(enhancement-data-tab): updated the data tab with chart rendering
    
    * feat(enhancement-data-tab): updated the data tab with chart rendering
    
    * feat(enhancement-data-tab): updated the data tab by fixing the issues
    
    * feat(enhancement-data-tab): updated the data tab by fixing the issues
    
    * feat(enhancement-data-tab): code clean up
    
    * feat(enhancement-data-tab): code clean up
    
    * feat(enhancement-data-tab): code clean up
    
    * feat(enhancement-data-tab): code clean up
    
    * feat(enhancement-data-tab): code clean up
    
    * feat(enhancement-data-tab): code refactor
    
    * build(toolstab): code refactor with update from dev branch
    
    * feat(enhancement-data-tab): change the asset path
    
    * feat(enhancement-data-tab): solve the merge conflict
    
    * feat(enhancement-data-tab): lint changes
    
    * fix(renderer): fix asset loading for dendrogram
    
    * [#1120] feat(notebook): add live console in notebook as it runs
    
    * feat(enhancement-data-tab): lint changes
    
    ---------
    
    Co-authored-by: Bannaarisamy Shanmugham <bannaarisamy.shanmugham@kanini.com>
    Co-authored-by: Baxter <johbaxter@deloitte.com>
    Co-authored-by: Jagan Somanna <jagansomanna.bharath@kanini.com>
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

    Labels

    None yet

    Projects

    None yet

    Development

    Successfully merging this pull request may close these issues.

    Show console in notebook as it is running

    4 participants