@datalayer/jupyter-react 1.2.3 → 2.0.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.
- package/README.md +10 -0
- package/lib/app/tabs/components/FileBrowserComponent.js +1 -1
- package/lib/app/tabs/components/FileBrowserComponent.js.map +1 -1
- package/lib/app/tabs/components/NotebookComponent.js +10 -4
- package/lib/app/tabs/components/NotebookComponent.js.map +1 -1
- package/lib/components/console/Console.js +1 -1
- package/lib/components/console/Console.js.map +1 -1
- package/lib/components/filemanager/FileManagerJupyterLab.js +1 -1
- package/lib/components/filemanager/FileManagerJupyterLab.js.map +1 -1
- package/lib/components/jupyterlab/JupyterLabApp.js +1 -1
- package/lib/components/jupyterlab/JupyterLabApp.js.map +1 -1
- package/lib/components/kernel/KernelSelector.js +1 -1
- package/lib/components/kernel/KernelSelector.js.map +1 -1
- package/lib/components/kernel/Kernels.js +1 -1
- package/lib/components/kernel/Kernels.js.map +1 -1
- package/lib/components/notebook/Notebook.d.ts +95 -41
- package/lib/components/notebook/Notebook.js +57 -276
- package/lib/components/notebook/Notebook.js.map +1 -1
- package/lib/components/notebook/NotebookAdapter.d.ts +263 -66
- package/lib/components/notebook/NotebookAdapter.js +639 -583
- package/lib/components/notebook/NotebookAdapter.js.map +1 -1
- package/lib/components/notebook/{Notebook2Base.d.ts → NotebookBase.d.ts} +2 -2
- package/lib/components/notebook/{Notebook2Base.js → NotebookBase.js} +29 -29
- package/lib/components/notebook/NotebookBase.js.map +1 -0
- package/lib/components/notebook/NotebookState.d.ts +37 -89
- package/lib/components/notebook/NotebookState.js +72 -155
- package/lib/components/notebook/NotebookState.js.map +1 -1
- package/lib/components/notebook/index.d.ts +2 -6
- package/lib/components/notebook/index.js +2 -6
- package/lib/components/notebook/index.js.map +1 -1
- package/lib/components/notebook/toolbar/NotebookToolbar.js +11 -16
- package/lib/components/notebook/toolbar/NotebookToolbar.js.map +1 -1
- package/lib/components/output/Output.js +1 -1
- package/lib/components/output/Output.js.map +1 -1
- package/lib/components/terminal/Terminal.js +1 -1
- package/lib/components/terminal/Terminal.js.map +1 -1
- package/lib/examples/Bokeh.js +6 -2
- package/lib/examples/Bokeh.js.map +1 -1
- package/lib/examples/Bqplot.js +7 -3
- package/lib/examples/Bqplot.js.map +1 -1
- package/lib/examples/Cell.js +1 -1
- package/lib/examples/Cell.js.map +1 -1
- package/lib/examples/CellLite.js +1 -1
- package/lib/examples/CellLite.js.map +1 -1
- package/lib/examples/Cells.js +1 -1
- package/lib/examples/Cells.js.map +1 -1
- package/lib/examples/CellsExecute.js +1 -1
- package/lib/examples/CellsExecute.js.map +1 -1
- package/lib/examples/ConsoleLite.js +2 -2
- package/lib/examples/ConsoleLite.js.map +1 -1
- package/lib/examples/Dashboard.js +7 -3
- package/lib/examples/Dashboard.js.map +1 -1
- package/lib/examples/Deno.js +8 -3
- package/lib/examples/Deno.js.map +1 -1
- package/lib/examples/Examples.js +6 -14
- package/lib/examples/Examples.js.map +1 -1
- package/lib/examples/FileBrowser.js +1 -1
- package/lib/examples/FileBrowser.js.map +1 -1
- package/lib/examples/GeoJson.js +9 -5
- package/lib/examples/GeoJson.js.map +1 -1
- package/lib/examples/IPyLeaflet.js +7 -3
- package/lib/examples/IPyLeaflet.js.map +1 -1
- package/lib/examples/IPyReact.js +6 -2
- package/lib/examples/IPyReact.js.map +1 -1
- package/lib/examples/IPyWidgets.js +7 -3
- package/lib/examples/IPyWidgets.js.map +1 -1
- package/lib/examples/IPyWidgetsState.js +13 -4
- package/lib/examples/IPyWidgetsState.js.map +1 -1
- package/lib/examples/JupyterContext.js +47 -24
- package/lib/examples/JupyterContext.js.map +1 -1
- package/lib/examples/JupyterLabTheme.js +4 -3
- package/lib/examples/JupyterLabTheme.js.map +1 -1
- package/lib/examples/KernelExecute.js +1 -1
- package/lib/examples/KernelExecute.js.map +1 -1
- package/lib/examples/KernelExecuteLite.js +1 -1
- package/lib/examples/KernelExecuteLite.js.map +1 -1
- package/lib/examples/KernelExecutor.js +1 -1
- package/lib/examples/KernelExecutor.js.map +1 -1
- package/lib/examples/KernelExecutorLite.js +1 -1
- package/lib/examples/KernelExecutorLite.js.map +1 -1
- package/lib/examples/Kernels.js +1 -1
- package/lib/examples/Kernels.js.map +1 -1
- package/lib/examples/Matplotlib.js +6 -2
- package/lib/examples/Matplotlib.js.map +1 -1
- package/lib/examples/Notebook.js +19 -8
- package/lib/examples/Notebook.js.map +1 -1
- package/lib/examples/{Notebook2Actions.js → NotebookActions.js} +6 -6
- package/lib/examples/NotebookActions.js.map +1 -0
- package/lib/examples/NotebookCellSidebar.js +17 -4
- package/lib/examples/NotebookCellSidebar.js.map +1 -1
- package/lib/examples/NotebookCellToolbar.js +7 -3
- package/lib/examples/NotebookCellToolbar.js.map +1 -1
- package/lib/examples/NotebookCollaborative.js +6 -9
- package/lib/examples/NotebookCollaborative.js.map +1 -1
- package/lib/examples/NotebookColormode.js +2 -2
- package/lib/examples/NotebookColormode.js.map +1 -1
- package/lib/examples/NotebookExtension.js +6 -2
- package/lib/examples/NotebookExtension.js.map +1 -1
- package/lib/examples/NotebookExternalContent.js +22 -14
- package/lib/examples/NotebookExternalContent.js.map +1 -1
- package/lib/examples/NotebookInit.js +23 -48
- package/lib/examples/NotebookInit.js.map +1 -1
- package/lib/examples/NotebookKernel.js +7 -16
- package/lib/examples/NotebookKernel.js.map +1 -1
- package/lib/examples/NotebookKernelChange.js +19 -12
- package/lib/examples/NotebookKernelChange.js.map +1 -1
- package/lib/examples/NotebookLess.js +13 -4
- package/lib/examples/NotebookLess.js.map +1 -1
- package/lib/examples/NotebookLite.js +21 -10
- package/lib/examples/NotebookLite.js.map +1 -1
- package/lib/examples/NotebookLocalServer.js +15 -6
- package/lib/examples/NotebookLocalServer.js.map +1 -1
- package/lib/examples/NotebookNbformat.js +2 -2
- package/lib/examples/NotebookNbformat.js.map +1 -1
- package/lib/examples/NotebookNbformatChange.js +16 -6
- package/lib/examples/NotebookNbformatChange.js.map +1 -1
- package/lib/examples/NotebookNoContext.js +10 -2
- package/lib/examples/NotebookNoContext.js.map +1 -1
- package/lib/examples/NotebookNoPrimer.js +11 -3
- package/lib/examples/NotebookNoPrimer.js.map +1 -1
- package/lib/examples/NotebookOnSessionConnection.js +13 -5
- package/lib/examples/NotebookOnSessionConnection.js.map +1 -1
- package/lib/examples/NotebookPath.js +13 -5
- package/lib/examples/NotebookPath.js.map +1 -1
- package/lib/examples/NotebookPathChange.js +7 -3
- package/lib/examples/NotebookPathChange.js.map +1 -1
- package/lib/examples/NotebookReadonly.js +6 -2
- package/lib/examples/NotebookReadonly.js.map +1 -1
- package/lib/examples/NotebookServiceManager.js +12 -6
- package/lib/examples/NotebookServiceManager.js.map +1 -1
- package/lib/examples/NotebookSkeleton.js +14 -4
- package/lib/examples/NotebookSkeleton.js.map +1 -1
- package/lib/examples/NotebookTOC.js +7 -3
- package/lib/examples/NotebookTOC.js.map +1 -1
- package/lib/examples/NotebookTheme.js +7 -3
- package/lib/examples/NotebookTheme.js.map +1 -1
- package/lib/examples/NotebookThemeColormode.js +2 -2
- package/lib/examples/NotebookThemeColormode.js.map +1 -1
- package/lib/examples/NotebookURL.js +11 -3
- package/lib/examples/NotebookURL.js.map +1 -1
- package/lib/examples/NotebookUnmount.js +8 -6
- package/lib/examples/NotebookUnmount.js.map +1 -1
- package/lib/examples/ObservableHQ.js +8 -3
- package/lib/examples/ObservableHQ.js.map +1 -1
- package/lib/examples/OutputWithMonitoring.js +11 -5
- package/lib/examples/OutputWithMonitoring.js.map +1 -1
- package/lib/examples/Outputs.js +13 -8
- package/lib/examples/Outputs.js.map +1 -1
- package/lib/examples/OutputsIpynb.js +3 -3
- package/lib/examples/OutputsIpynb.js.map +1 -1
- package/lib/examples/Panel.js +8 -4
- package/lib/examples/Panel.js.map +1 -1
- package/lib/examples/Plotly.js +7 -3
- package/lib/examples/Plotly.js.map +1 -1
- package/lib/examples/PyGWalker.js +13 -4
- package/lib/examples/PyGWalker.js.map +1 -1
- package/lib/examples/RunningSessions.js +5 -5
- package/lib/examples/RunningSessions.js.map +1 -1
- package/lib/examples/Vega.js +11 -3
- package/lib/examples/Vega.js.map +1 -1
- package/lib/examples/Viewer.js +2 -2
- package/lib/examples/Viewer.js.map +1 -1
- package/lib/examples/extensions/celltoolbar/CellToolbarComponent.js +8 -25
- package/lib/examples/extensions/celltoolbar/CellToolbarComponent.js.map +1 -1
- package/lib/examples/extensions/toc/TocComponent.d.ts +1 -0
- package/lib/examples/extensions/toc/TocComponent.js +39 -28
- package/lib/examples/extensions/toc/TocComponent.js.map +1 -1
- package/lib/examples/extensions/toc/TocExtension.d.ts +1 -3
- package/lib/examples/extensions/toc/TocExtension.js +28 -11
- package/lib/examples/extensions/toc/TocExtension.js.map +1 -1
- package/lib/jupyter/JupyterConfig.d.ts +9 -2
- package/lib/jupyter/JupyterConfig.js.map +1 -1
- package/lib/jupyter/{JupyterContext.d.ts → JupyterUse.d.ts} +3 -26
- package/lib/jupyter/JupyterUse.js +26 -0
- package/lib/jupyter/JupyterUse.js.map +1 -0
- package/lib/jupyter/index.d.ts +1 -3
- package/lib/jupyter/index.js +1 -3
- package/lib/jupyter/index.js.map +1 -1
- package/lib/jupyter/lite/contents/broadcast.js +5 -2
- package/lib/jupyter/lite/contents/broadcast.js.map +1 -1
- package/lib/jupyter/lite/contents/contents.js +5 -0
- package/lib/jupyter/lite/contents/contents.js.map +1 -1
- package/lib/jupyter/lite/contents/drivecontents.js +5 -0
- package/lib/jupyter/lite/contents/drivecontents.js.map +1 -1
- package/lib/jupyter/lite/contents/drivefs.js +5 -2
- package/lib/jupyter/lite/contents/drivefs.js.map +1 -1
- package/lib/jupyter/lite/contents/emscripten.js +5 -2
- package/lib/jupyter/lite/contents/emscripten.js.map +1 -1
- package/lib/jupyter/lite/contents/index.js +5 -0
- package/lib/jupyter/lite/contents/index.js.map +1 -1
- package/lib/jupyter/lite/contents/tokens.js +5 -0
- package/lib/jupyter/lite/contents/tokens.js.map +1 -1
- package/lib/jupyter/lite/javascript-kernel/comlink.worker.js +15 -0
- package/lib/jupyter/lite/javascript-kernel/comlink.worker.js.map +1 -0
- package/lib/jupyter/lite/javascript-kernel/index.d.ts +2 -0
- package/lib/jupyter/lite/javascript-kernel/index.js +10 -0
- package/lib/jupyter/lite/javascript-kernel/index.js.map +1 -0
- package/lib/jupyter/lite/javascript-kernel/kernel.d.ts +121 -0
- package/lib/jupyter/lite/javascript-kernel/kernel.js +239 -0
- package/lib/jupyter/lite/javascript-kernel/kernel.js.map +1 -0
- package/lib/jupyter/lite/javascript-kernel/tokens.d.ts +27 -0
- package/lib/jupyter/lite/javascript-kernel/tokens.js +7 -0
- package/lib/jupyter/lite/javascript-kernel/tokens.js.map +1 -0
- package/lib/jupyter/lite/javascript-kernel/worker.d.ts +37 -0
- package/lib/jupyter/lite/javascript-kernel/worker.js +117 -0
- package/lib/jupyter/lite/javascript-kernel/worker.js.map +1 -0
- package/lib/jupyter/lite/javascript-kernel-extension/index.d.ts +3 -0
- package/lib/jupyter/lite/javascript-kernel-extension/index.js +37 -0
- package/lib/jupyter/lite/javascript-kernel-extension/index.js.map +1 -0
- package/lib/jupyter/lite/kernel/index.js +5 -0
- package/lib/jupyter/lite/kernel/index.js.map +1 -1
- package/lib/jupyter/lite/kernel/kernel.js +5 -0
- package/lib/jupyter/lite/kernel/kernel.js.map +1 -1
- package/lib/jupyter/lite/kernel/kernels.js +5 -0
- package/lib/jupyter/lite/kernel/kernels.js.map +1 -1
- package/lib/jupyter/lite/kernel/kernelspecs.js +5 -0
- package/lib/jupyter/lite/kernel/kernelspecs.js.map +1 -1
- package/lib/jupyter/lite/kernel/tokens.js +5 -2
- package/lib/jupyter/lite/kernel/tokens.js.map +1 -1
- package/lib/jupyter/lite/licenses/index.js +5 -0
- package/lib/jupyter/lite/licenses/index.js.map +1 -1
- package/lib/jupyter/lite/licenses/licenses.js +5 -0
- package/lib/jupyter/lite/licenses/licenses.js.map +1 -1
- package/lib/jupyter/lite/licenses/tokens.js +5 -0
- package/lib/jupyter/lite/licenses/tokens.js.map +1 -1
- package/lib/jupyter/lite/localforage/index.js +5 -0
- package/lib/jupyter/lite/localforage/index.js.map +1 -1
- package/lib/jupyter/lite/localforage/memory.js +5 -2
- package/lib/jupyter/lite/localforage/memory.js.map +1 -1
- package/lib/jupyter/lite/localforage/tokens.js +5 -2
- package/lib/jupyter/lite/localforage/tokens.js.map +1 -1
- package/lib/jupyter/lite/pyodide-kernel/_pypi.js +5 -0
- package/lib/jupyter/lite/pyodide-kernel/_pypi.js.map +1 -1
- package/lib/jupyter/lite/pyodide-kernel/coincident.worker.js +5 -0
- package/lib/jupyter/lite/pyodide-kernel/coincident.worker.js.map +1 -1
- package/lib/jupyter/lite/pyodide-kernel/comlink.worker.js +5 -0
- package/lib/jupyter/lite/pyodide-kernel/comlink.worker.js.map +1 -1
- package/lib/jupyter/lite/pyodide-kernel/index.js +5 -0
- package/lib/jupyter/lite/pyodide-kernel/index.js.map +1 -1
- package/lib/jupyter/lite/pyodide-kernel/kernel.js +5 -0
- package/lib/jupyter/lite/pyodide-kernel/kernel.js.map +1 -1
- package/lib/jupyter/lite/pyodide-kernel/tokens.js +5 -2
- package/lib/jupyter/lite/pyodide-kernel/tokens.js.map +1 -1
- package/lib/jupyter/lite/pyodide-kernel/worker.js +5 -2
- package/lib/jupyter/lite/pyodide-kernel/worker.js.map +1 -1
- package/lib/jupyter/lite/pyodide-kernel-extension/index.js +6 -1
- package/lib/jupyter/lite/pyodide-kernel-extension/index.js.map +1 -1
- package/lib/jupyter/lite/server/app.js +5 -0
- package/lib/jupyter/lite/server/app.js.map +1 -1
- package/lib/jupyter/lite/server/index.js +5 -0
- package/lib/jupyter/lite/server/index.js.map +1 -1
- package/lib/jupyter/lite/server/router.js +5 -0
- package/lib/jupyter/lite/server/router.js.map +1 -1
- package/lib/jupyter/lite/server/service-manager.js +5 -0
- package/lib/jupyter/lite/server/service-manager.js.map +1 -1
- package/lib/jupyter/lite/server/service-worker.js +5 -0
- package/lib/jupyter/lite/server/service-worker.js.map +1 -1
- package/lib/jupyter/lite/server/status.js +5 -0
- package/lib/jupyter/lite/server/status.js.map +1 -1
- package/lib/jupyter/lite/server/tokens.js +5 -0
- package/lib/jupyter/lite/server/tokens.js.map +1 -1
- package/lib/jupyter/lite/server-extension/index.js +5 -0
- package/lib/jupyter/lite/server-extension/index.js.map +1 -1
- package/lib/jupyter/lite/session/index.js +5 -0
- package/lib/jupyter/lite/session/index.js.map +1 -1
- package/lib/jupyter/lite/session/sessions.js +5 -0
- package/lib/jupyter/lite/session/sessions.js.map +1 -1
- package/lib/jupyter/lite/session/tokens.js +5 -0
- package/lib/jupyter/lite/session/tokens.js.map +1 -1
- package/lib/jupyter/lite/settings/index.js +5 -0
- package/lib/jupyter/lite/settings/index.js.map +1 -1
- package/lib/jupyter/lite/settings/settings.js +5 -0
- package/lib/jupyter/lite/settings/settings.js.map +1 -1
- package/lib/jupyter/lite/settings/tokens.js +5 -0
- package/lib/jupyter/lite/settings/tokens.js.map +1 -1
- package/lib/jupyter/lite/translation/index.js +5 -0
- package/lib/jupyter/lite/translation/index.js.map +1 -1
- package/lib/jupyter/lite/translation/tokens.js +5 -0
- package/lib/jupyter/lite/translation/tokens.js.map +1 -1
- package/lib/jupyter/lite/translation/translation.js +5 -0
- package/lib/jupyter/lite/translation/translation.js.map +1 -1
- package/lib/jupyter/lite/types/index.js +5 -0
- package/lib/jupyter/lite/types/index.js.map +1 -1
- package/lib/jupyter/lite/types/tokens.js +5 -2
- package/lib/jupyter/lite/types/tokens.js.map +1 -1
- package/lib/state/JupyterReactState.d.ts +2 -2
- package/lib/state/JupyterReactState.js +3 -1
- package/lib/state/JupyterReactState.js.map +1 -1
- package/lib/tools/core/executor.d.ts +4 -4
- package/lib/tools/core/executor.js +2 -2
- package/lib/tools/core/executor.js.map +1 -1
- package/lib/utils/Utils.d.ts +7 -0
- package/lib/utils/Utils.js +32 -0
- package/lib/utils/Utils.js.map +1 -1
- package/package.json +4 -1
- package/style/icons/javascript/logo-32x32.png +0 -0
- package/style/icons/javascript/logo-64x64.png +0 -0
- package/lib/components/notebook/Notebook2.d.ts +0 -112
- package/lib/components/notebook/Notebook2.js +0 -121
- package/lib/components/notebook/Notebook2.js.map +0 -1
- package/lib/components/notebook/Notebook2Adapter.d.ts +0 -269
- package/lib/components/notebook/Notebook2Adapter.js +0 -688
- package/lib/components/notebook/Notebook2Adapter.js.map +0 -1
- package/lib/components/notebook/Notebook2Base.js.map +0 -1
- package/lib/components/notebook/Notebook2State.d.ts +0 -59
- package/lib/components/notebook/Notebook2State.js +0 -122
- package/lib/components/notebook/Notebook2State.js.map +0 -1
- package/lib/examples/Notebook2.js +0 -30
- package/lib/examples/Notebook2.js.map +0 -1
- package/lib/examples/Notebook2Actions.js.map +0 -1
- package/lib/examples/Notebook2Collaborative.d.ts +0 -1
- package/lib/examples/Notebook2Collaborative.js +0 -23
- package/lib/examples/Notebook2Collaborative.js.map +0 -1
- package/lib/examples/Notebook2Lite.d.ts +0 -1
- package/lib/examples/Notebook2Lite.js +0 -39
- package/lib/examples/Notebook2Lite.js.map +0 -1
- package/lib/examples/NotebookLiteContext.d.ts +0 -1
- package/lib/examples/NotebookLiteContext.js +0 -24
- package/lib/examples/NotebookLiteContext.js.map +0 -1
- package/lib/examples/toolbars/NotebookToolbarAutoSave.d.ts +0 -4
- package/lib/examples/toolbars/NotebookToolbarAutoSave.js +0 -70
- package/lib/examples/toolbars/NotebookToolbarAutoSave.js.map +0 -1
- package/lib/examples/toolbars/NotebookToolbarStatus.d.ts +0 -4
- package/lib/examples/toolbars/NotebookToolbarStatus.js +0 -15
- package/lib/examples/toolbars/NotebookToolbarStatus.js.map +0 -1
- package/lib/jupyter/Jupyter.d.ts +0 -18
- package/lib/jupyter/Jupyter.js +0 -38
- package/lib/jupyter/Jupyter.js.map +0 -1
- package/lib/jupyter/JupyterContext.js +0 -99
- package/lib/jupyter/JupyterContext.js.map +0 -1
- /package/lib/examples/{Notebook2.d.ts → NotebookActions.d.ts} +0 -0
- /package/lib/{examples/Notebook2Actions.d.ts → jupyter/lite/javascript-kernel/comlink.worker.d.ts} +0 -0
- /package/style/icons/{pyodide.svg → pyodide/pyodide.svg} +0 -0
|
@@ -3,630 +3,686 @@
|
|
|
3
3
|
*
|
|
4
4
|
* MIT License
|
|
5
5
|
*/
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import
|
|
9
|
-
import { Context, DocumentRegistry } from '@jupyterlab/docregistry';
|
|
10
|
-
import { rendererFactory as javascriptRendererFactory } from '@jupyterlab/javascript-extension';
|
|
11
|
-
import { rendererFactory as jsonRendererFactory } from '@jupyterlab/json-extension';
|
|
12
|
-
import { MathJaxTypesetter } from '@jupyterlab/mathjax-extension';
|
|
13
|
-
import { NotebookTracker, NotebookWidgetFactory, StaticNotebook, } from '@jupyterlab/notebook';
|
|
14
|
-
import { RenderMimeRegistry, standardRendererFactories, } from '@jupyterlab/rendermime';
|
|
15
|
-
import { find } from '@lumino/algorithm';
|
|
16
|
-
import { CommandRegistry } from '@lumino/commands';
|
|
17
|
-
import { BoxPanel, Widget } from '@lumino/widgets';
|
|
18
|
-
import { WidgetLabRenderer, WidgetManager } from '../../jupyter';
|
|
19
|
-
import { newUuid } from '../../utils';
|
|
20
|
-
import { JupyterReactContentFactory } from './content/JupyterReactContentFactory';
|
|
21
|
-
import { getMarked } from './marked/marked';
|
|
22
|
-
import { JupyterReactNotebookModelFactory } from './model/JupyterReactNotebookModelFactory';
|
|
23
|
-
import { addNotebookCommands, NotebookPanelProvider } from './NotebookCommands';
|
|
24
|
-
const FALLBACK_NOTEBOOK_PATH = '.datalayer/ping.ipynb';
|
|
6
|
+
import { NotebookActions, } from '@jupyterlab/notebook';
|
|
7
|
+
import { NotebookCommandIds } from './NotebookCommands';
|
|
8
|
+
import * as Diff from 'diff';
|
|
25
9
|
export class NotebookAdapter {
|
|
26
|
-
_boxPanel;
|
|
27
10
|
_commands;
|
|
28
|
-
|
|
11
|
+
_panel;
|
|
12
|
+
_notebook;
|
|
29
13
|
_context;
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
this.
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
this.
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
this.
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
14
|
+
_defaultCellType = 'code';
|
|
15
|
+
constructor(commands, panel, context) {
|
|
16
|
+
this._commands = commands;
|
|
17
|
+
this._panel = panel;
|
|
18
|
+
this._notebook = panel.content;
|
|
19
|
+
this._context = context;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Get the command registry.
|
|
23
|
+
*/
|
|
24
|
+
get commands() {
|
|
25
|
+
return this._commands;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Get the notebook panel.
|
|
29
|
+
*/
|
|
30
|
+
get panel() {
|
|
31
|
+
return this._panel;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Get the notebook widget.
|
|
35
|
+
*/
|
|
36
|
+
get notebook() {
|
|
37
|
+
return this._notebook;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Get the notebook context.
|
|
41
|
+
*/
|
|
42
|
+
get context() {
|
|
43
|
+
return this._context;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Set the default cell type for new cells.
|
|
47
|
+
*/
|
|
48
|
+
setDefaultCellType(cellType) {
|
|
49
|
+
this._defaultCellType = cellType;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Get the default cell type for new cells.
|
|
53
|
+
*/
|
|
54
|
+
get defaultCellType() {
|
|
55
|
+
return this._defaultCellType;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Insert a new cell above the active cell.
|
|
59
|
+
*/
|
|
60
|
+
insertAbove(source) {
|
|
61
|
+
const notebook = this._notebook;
|
|
62
|
+
// Insert above using NotebookActions
|
|
63
|
+
NotebookActions.insertAbove(notebook);
|
|
64
|
+
// Always set the cell type to match _defaultCellType
|
|
65
|
+
// (NotebookActions may create cells with a different default type)
|
|
66
|
+
NotebookActions.changeCellType(notebook, this._defaultCellType);
|
|
67
|
+
// Set the source if provided
|
|
68
|
+
if (source && notebook.activeCell) {
|
|
69
|
+
notebook.activeCell.model.sharedModel.setSource(source);
|
|
79
70
|
}
|
|
80
|
-
|
|
81
|
-
|
|
71
|
+
// Enter edit mode
|
|
72
|
+
notebook.mode = 'edit';
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Insert a new cell below the active cell.
|
|
76
|
+
*/
|
|
77
|
+
insertBelow(source) {
|
|
78
|
+
const notebook = this._notebook;
|
|
79
|
+
// Insert below using NotebookActions
|
|
80
|
+
NotebookActions.insertBelow(notebook);
|
|
81
|
+
// Always set the cell type to match _defaultCellType
|
|
82
|
+
// (NotebookActions may create cells with a different default type)
|
|
83
|
+
NotebookActions.changeCellType(notebook, this._defaultCellType);
|
|
84
|
+
// Set the source if provided
|
|
85
|
+
if (source && notebook.activeCell) {
|
|
86
|
+
notebook.activeCell.model.sharedModel.setSource(source);
|
|
82
87
|
}
|
|
88
|
+
// Enter edit mode
|
|
89
|
+
notebook.mode = 'edit';
|
|
83
90
|
}
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
}
|
|
91
|
+
/**
|
|
92
|
+
* Change the type of the active cell.
|
|
93
|
+
*/
|
|
94
|
+
changeCellType(cellType) {
|
|
95
|
+
const notebook = this._notebook;
|
|
96
|
+
if (notebook.activeCell && notebook.activeCell.model.type !== cellType) {
|
|
97
|
+
NotebookActions.changeCellType(notebook, cellType);
|
|
98
|
+
}
|
|
92
99
|
}
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
const
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
});
|
|
125
|
-
handler.reconciliator = reconciliator;
|
|
126
|
-
});
|
|
127
|
-
handler.editor = editor;
|
|
128
|
-
notebookPanel.content.activeCellChanged.connect((notebook, cell) => {
|
|
129
|
-
if (cell) {
|
|
130
|
-
cell.ready.then(() => {
|
|
131
|
-
handler.editor = cell && cell.editor;
|
|
132
|
-
});
|
|
100
|
+
/**
|
|
101
|
+
* Delete the currently selected cells.
|
|
102
|
+
*/
|
|
103
|
+
deleteCells() {
|
|
104
|
+
const notebook = this._notebook;
|
|
105
|
+
NotebookActions.deleteCells(notebook);
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Get the notebook model.
|
|
109
|
+
*/
|
|
110
|
+
get model() {
|
|
111
|
+
return this._context.model;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Undo the last change in the notebook.
|
|
115
|
+
*
|
|
116
|
+
* @remarks
|
|
117
|
+
* If there is no history to undo (e.g., at the beginning of the undo stack),
|
|
118
|
+
* this operation will have no effect. The notebook must be available and
|
|
119
|
+
* properly initialized for this operation to succeed.
|
|
120
|
+
*/
|
|
121
|
+
undo() {
|
|
122
|
+
const notebook = this._notebook;
|
|
123
|
+
// If we're in edit mode and have an active cell with an editor,
|
|
124
|
+
// try to undo in the cell editor first
|
|
125
|
+
if (notebook.mode === 'edit' && notebook.activeCell?.editor) {
|
|
126
|
+
const editor = notebook.activeCell.editor;
|
|
127
|
+
// CodeMirror editor has an undo method
|
|
128
|
+
if (editor && typeof editor.undo === 'function') {
|
|
129
|
+
editor.undo();
|
|
130
|
+
return;
|
|
133
131
|
}
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
return handler;
|
|
132
|
+
}
|
|
133
|
+
// Otherwise, undo at the notebook level (add/remove cells, etc.)
|
|
134
|
+
NotebookActions.undo(notebook);
|
|
138
135
|
}
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
// await (this._context as any)._maybeCheckpoint(false);
|
|
206
|
-
if (this._context.isDisposed) {
|
|
207
|
-
return;
|
|
208
|
-
}
|
|
209
|
-
// Update the kernel preference.
|
|
210
|
-
const name = this._context._model.defaultKernelName ||
|
|
211
|
-
this._context.sessionContext.kernelPreference.name;
|
|
212
|
-
this._context.sessionContext.kernelPreference = {
|
|
213
|
-
...this._context.sessionContext.kernelPreference,
|
|
214
|
-
name,
|
|
215
|
-
language: this._context._model.defaultKernelLanguage,
|
|
136
|
+
/**
|
|
137
|
+
* Redo the last undone change in the notebook.
|
|
138
|
+
*
|
|
139
|
+
* @remarks
|
|
140
|
+
* If there is no history to redo (e.g., no prior undo operations or at the
|
|
141
|
+
* end of the redo stack), this operation will have no effect. The notebook
|
|
142
|
+
* must be available and properly initialized for this operation to succeed.
|
|
143
|
+
*/
|
|
144
|
+
redo() {
|
|
145
|
+
const notebook = this._notebook;
|
|
146
|
+
// If we're in edit mode and have an active cell with an editor,
|
|
147
|
+
// try to redo in the cell editor first
|
|
148
|
+
if (notebook.mode === 'edit' && notebook.activeCell?.editor) {
|
|
149
|
+
const editor = notebook.activeCell.editor;
|
|
150
|
+
// CodeMirror editor has a redo method
|
|
151
|
+
if (editor && typeof editor.redo === 'function') {
|
|
152
|
+
editor.redo();
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
// Otherwise, redo at the notebook level (add/remove cells, etc.)
|
|
157
|
+
NotebookActions.redo(notebook);
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Set the active cell by index.
|
|
161
|
+
*
|
|
162
|
+
* @param index - The index of the cell to activate (0-based)
|
|
163
|
+
*
|
|
164
|
+
* @remarks
|
|
165
|
+
* This method programmatically selects a cell at the specified index.
|
|
166
|
+
* If the index is out of bounds, the operation has no effect.
|
|
167
|
+
*/
|
|
168
|
+
setActiveCell(index) {
|
|
169
|
+
const notebook = this._notebook;
|
|
170
|
+
const cellCount = notebook.model?.cells.length ?? 0;
|
|
171
|
+
if (index >= 0 && index < cellCount) {
|
|
172
|
+
notebook.activeCellIndex = index;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Get all cells from the notebook.
|
|
177
|
+
*
|
|
178
|
+
* @returns Array of cell data including type, source, and outputs
|
|
179
|
+
*
|
|
180
|
+
* @remarks
|
|
181
|
+
* This method extracts cell information from the notebook model.
|
|
182
|
+
* For code cells, outputs are included. Returns an empty array if
|
|
183
|
+
* the notebook model is not available.
|
|
184
|
+
*/
|
|
185
|
+
getCells() {
|
|
186
|
+
console.log('[NotebookAdapter.getCells] Called');
|
|
187
|
+
const cells = this._notebook.model?.cells;
|
|
188
|
+
if (!cells) {
|
|
189
|
+
console.log('[NotebookAdapter.getCells] No cells model, returning empty array');
|
|
190
|
+
return [];
|
|
191
|
+
}
|
|
192
|
+
console.log(`[NotebookAdapter.getCells] Found ${cells.length} cells`);
|
|
193
|
+
const result = [];
|
|
194
|
+
for (let i = 0; i < cells.length; i++) {
|
|
195
|
+
const cell = cells.get(i);
|
|
196
|
+
if (cell) {
|
|
197
|
+
const cellData = {
|
|
198
|
+
index: i,
|
|
199
|
+
type: cell.type,
|
|
200
|
+
source: cell.sharedModel.getSource(),
|
|
201
|
+
outputs: cell.type === 'code' ? cell.outputs?.toJSON() : undefined,
|
|
216
202
|
};
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
void this._context.sessionContext
|
|
221
|
-
.initialize()
|
|
222
|
-
.then((shouldSelect) => {
|
|
223
|
-
if (shouldSelect) {
|
|
224
|
-
void this._context._dialogs.selectKernel(this._context.sessionContext.sessionContext);
|
|
225
|
-
}
|
|
203
|
+
console.log(`[NotebookAdapter.getCells] Cell ${i}:`, {
|
|
204
|
+
type: cellData.type,
|
|
205
|
+
sourceLength: cellData.source.length,
|
|
226
206
|
});
|
|
227
|
-
|
|
228
|
-
this._context.initialize = async (isNew) => {
|
|
229
|
-
this._context.model.dirty = false;
|
|
230
|
-
const now = new Date().toISOString();
|
|
231
|
-
const model = {
|
|
232
|
-
path: this._id,
|
|
233
|
-
name: this._id,
|
|
234
|
-
type: 'notebook',
|
|
235
|
-
content: undefined,
|
|
236
|
-
writable: true,
|
|
237
|
-
created: now,
|
|
238
|
-
last_modified: now,
|
|
239
|
-
mimetype: 'application/x-ipynb+json',
|
|
240
|
-
format: 'json',
|
|
241
|
-
};
|
|
242
|
-
this._context._updateContentsModel(model);
|
|
243
|
-
await this._context._populate();
|
|
244
|
-
this._context.model.sharedModel.clearUndoHistory();
|
|
245
|
-
};
|
|
246
|
-
}
|
|
247
|
-
// Setup the context listeners.
|
|
248
|
-
this._context.sessionContext.sessionChanged.connect((_, args) => {
|
|
249
|
-
const session = args.newValue;
|
|
250
|
-
console.log('Current Jupyter Session Connection', session);
|
|
251
|
-
if (this._onSessionConnection) {
|
|
252
|
-
if (session) {
|
|
253
|
-
this._onSessionConnection(session);
|
|
254
|
-
this._iPyWidgetsManager?.registerWithKernel(session.kernel);
|
|
255
|
-
const model = this._notebookPanel?.model;
|
|
256
|
-
if (model) {
|
|
257
|
-
this._iPyWidgetsManager?.restoreWidgets(model);
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
});
|
|
262
|
-
this._context.sessionContext.kernelChanged.connect((_, args) => {
|
|
263
|
-
const kernelConnection = args.newValue;
|
|
264
|
-
this._kernelConnection = kernelConnection;
|
|
265
|
-
console.log('Current Jupyter Kernel Connection.', kernelConnection);
|
|
266
|
-
if (kernelConnection && !kernelConnection.handleComms) {
|
|
267
|
-
console.log('Updating the current Kernel Connection to enforce Comms support.', kernelConnection.handleComms);
|
|
268
|
-
kernelConnection.handleComms = true;
|
|
269
|
-
}
|
|
270
|
-
/*
|
|
271
|
-
this._iPyWidgetsManager?.registerWithKernel(kernelConnection);
|
|
272
|
-
this._iPyWidgetsManager?.restoreWidgets(this._notebookPanel?.model!)
|
|
273
|
-
if (this._onSessionConnection) {
|
|
274
|
-
this._onSessionConnection(kernelConnection);
|
|
275
|
-
}
|
|
276
|
-
*/
|
|
277
|
-
});
|
|
278
|
-
this._context.sessionContext.ready.then(() => {
|
|
279
|
-
if (this._onSessionConnection) {
|
|
280
|
-
this._onSessionConnection(this._context?.sessionContext.session ?? undefined);
|
|
281
|
-
}
|
|
282
|
-
const kernelConnection = this._context?.sessionContext.session?.kernel;
|
|
283
|
-
this._kernelConnection = kernelConnection;
|
|
284
|
-
if (this._kernelTransfer) {
|
|
285
|
-
if (kernelConnection) {
|
|
286
|
-
kernelConnection.connectionStatusChanged.connect((_, status) => {
|
|
287
|
-
if (status === 'connected') {
|
|
288
|
-
this._kernelTransfer.transfer(kernelConnection);
|
|
289
|
-
}
|
|
290
|
-
});
|
|
291
|
-
}
|
|
207
|
+
result.push(cellData);
|
|
292
208
|
}
|
|
293
|
-
});
|
|
294
|
-
if (!this._notebookPanel) {
|
|
295
|
-
// Create the Notebook Panel if not yet done.
|
|
296
|
-
/*
|
|
297
|
-
// Option 1 to create the Notebook Panel.
|
|
298
|
-
const content = new Notebook({
|
|
299
|
-
rendermime: this._rendermime!,
|
|
300
|
-
contentFactory: this._contentFactory,
|
|
301
|
-
mimeTypeService: this._mimeTypeService,
|
|
302
|
-
notebookConfig: {
|
|
303
|
-
...StaticNotebook.defaultNotebookConfig,
|
|
304
|
-
windowingMode: 'none',
|
|
305
|
-
recordTiming: true,
|
|
306
|
-
}
|
|
307
|
-
});
|
|
308
|
-
this._notebookPanel = new NotebookPanel({
|
|
309
|
-
context: this._context,
|
|
310
|
-
content,
|
|
311
|
-
});
|
|
312
|
-
*/
|
|
313
|
-
// Option 2 to create the Notebook Panel.
|
|
314
|
-
const notebookFactory = this._documentRegistry?.getWidgetFactory('Notebook');
|
|
315
|
-
this._notebookPanel = notebookFactory?.createNew(this._context);
|
|
316
|
-
// Update panel provider with persistent references
|
|
317
|
-
this._panelProvider.setPanel(this._notebookPanel, this._context);
|
|
318
209
|
}
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
210
|
+
console.log(`[NotebookAdapter.getCells] Returning ${result.length} cells`);
|
|
211
|
+
return result;
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Read all cells from the notebook (alias for getCells).
|
|
215
|
+
*
|
|
216
|
+
* @param format - Response format: 'brief' returns preview only, 'detailed' returns full content
|
|
217
|
+
* @returns Array of cell data - brief or detailed based on format
|
|
218
|
+
*
|
|
219
|
+
* @remarks
|
|
220
|
+
* This method is an alias for getCells() to match the readAllCells tool operation.
|
|
221
|
+
* Provides a consistent naming convention for read operations.
|
|
222
|
+
* Supports brief format (index, type, 40-char preview) and detailed format (full content).
|
|
223
|
+
*/
|
|
224
|
+
readAllCells(format = 'brief') {
|
|
225
|
+
const cells = this.getCells();
|
|
226
|
+
return cells.map((cell, index) => {
|
|
227
|
+
// Get execution count for code cells
|
|
228
|
+
const cellModel = this._notebook.model?.cells.get(index);
|
|
229
|
+
const execution_count = cellModel?.type === 'code'
|
|
230
|
+
? (cellModel.executionCount ?? null)
|
|
231
|
+
: null;
|
|
232
|
+
if (format === 'brief') {
|
|
233
|
+
// Brief format: index, type, 40-char preview
|
|
234
|
+
return {
|
|
235
|
+
index,
|
|
236
|
+
type: cell.type,
|
|
237
|
+
preview: cell.source.substring(0, 40),
|
|
238
|
+
};
|
|
327
239
|
}
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
240
|
+
else {
|
|
241
|
+
// Detailed format: full content with source, execution_count, outputs
|
|
242
|
+
return {
|
|
243
|
+
index,
|
|
244
|
+
type: cell.type,
|
|
245
|
+
source: cell.source,
|
|
246
|
+
execution_count,
|
|
247
|
+
outputs: cell.outputs,
|
|
248
|
+
};
|
|
337
249
|
}
|
|
338
250
|
});
|
|
339
251
|
}
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
},
|
|
252
|
+
/**
|
|
253
|
+
* Get the total number of cells in the notebook.
|
|
254
|
+
*
|
|
255
|
+
* @returns The number of cells, or 0 if the notebook model is not available
|
|
256
|
+
*/
|
|
257
|
+
getCellCount() {
|
|
258
|
+
return this._notebook.model?.cells.length ?? 0;
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* Insert a new cell at a specific index.
|
|
262
|
+
*
|
|
263
|
+
* @param cellIndex - The index where the cell should be inserted (0-based)
|
|
264
|
+
* @param source - Optional source code/text for the new cell
|
|
265
|
+
*
|
|
266
|
+
* @remarks
|
|
267
|
+
* This method inserts a cell at the specified position by:
|
|
268
|
+
* 1. Setting the active cell to cellIndex
|
|
269
|
+
* 2. Calling insertAbove to insert before that cell
|
|
270
|
+
*
|
|
271
|
+
* Note: The cell type is determined by _defaultCellType, which should be set
|
|
272
|
+
* before calling this method (typically done by the store layer).
|
|
273
|
+
*/
|
|
274
|
+
insertAt(cellIndex, source) {
|
|
275
|
+
const cellCount = this.getCellCount();
|
|
276
|
+
console.log('[NotebookAdapter.insertAt] Called with:', {
|
|
277
|
+
cellIndex,
|
|
278
|
+
sourceLength: source?.length || 0,
|
|
279
|
+
sourcePreview: source?.substring(0, 50),
|
|
280
|
+
currentActiveCell: this._notebook.activeCellIndex,
|
|
281
|
+
cellCount,
|
|
282
|
+
defaultCellType: this._defaultCellType,
|
|
372
283
|
});
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
284
|
+
// Validate cell index is within bounds (matches Jupyter MCP Server)
|
|
285
|
+
if (cellIndex < -1 || cellIndex > cellCount) {
|
|
286
|
+
throw new Error(`Index ${cellIndex} is outside valid range [-1, ${cellCount}]. ` +
|
|
287
|
+
`Use -1 to append at end.`);
|
|
288
|
+
}
|
|
289
|
+
// Normalize -1 to append position (matches Jupyter MCP Server)
|
|
290
|
+
const actualIndex = cellIndex === -1 ? cellCount : cellIndex;
|
|
291
|
+
console.log('[NotebookAdapter.insertAt] Normalized index:', {
|
|
292
|
+
originalIndex: cellIndex,
|
|
293
|
+
actualIndex,
|
|
294
|
+
cellCount,
|
|
377
295
|
});
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
296
|
+
// Insert at the actual index
|
|
297
|
+
if (actualIndex >= cellCount) {
|
|
298
|
+
// Append at end
|
|
299
|
+
console.log('[NotebookAdapter.insertAt] Appending at end');
|
|
300
|
+
if (cellCount > 0) {
|
|
301
|
+
this.setActiveCell(cellCount - 1);
|
|
302
|
+
}
|
|
303
|
+
this.insertBelow(source);
|
|
383
304
|
}
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
305
|
+
else {
|
|
306
|
+
// Insert at specific position
|
|
307
|
+
console.log(`[NotebookAdapter.insertAt] Inserting at index ${actualIndex}`);
|
|
308
|
+
this.setActiveCell(actualIndex);
|
|
309
|
+
this.insertAbove(source);
|
|
387
310
|
}
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
registry.addExtension(extensionFactory);
|
|
392
|
-
}
|
|
393
|
-
registry.addExtension({
|
|
394
|
-
name: 'shared-model-binding',
|
|
395
|
-
factory: options => {
|
|
396
|
-
const sharedModel = options.model.sharedModel;
|
|
397
|
-
return EditorExtensionRegistry.createImmutableExtension(ybinding({
|
|
398
|
-
ytext: sharedModel.ysource,
|
|
399
|
-
undoManager: sharedModel.undoManager ?? undefined,
|
|
400
|
-
}));
|
|
401
|
-
},
|
|
402
|
-
});
|
|
403
|
-
return registry;
|
|
404
|
-
};
|
|
405
|
-
const factoryService = new CodeMirrorEditorFactory({
|
|
406
|
-
extensions: editorExtensions(),
|
|
407
|
-
languages,
|
|
311
|
+
console.log('[NotebookAdapter.insertAt] After insertion:', {
|
|
312
|
+
cellCount: this.getCellCount(),
|
|
313
|
+
activeCell: this._notebook.activeCellIndex,
|
|
408
314
|
});
|
|
409
|
-
const editorServices = {
|
|
410
|
-
factoryService,
|
|
411
|
-
mimeTypeService: this._mimeTypeService,
|
|
412
|
-
};
|
|
413
|
-
const editorFactory = editorServices.factoryService.newInlineEditor;
|
|
414
|
-
this._contentFactory = new JupyterReactContentFactory({ editorFactory });
|
|
415
|
-
this._tracker = new NotebookTracker({ namespace: this._id });
|
|
416
|
-
const notebookWidgetFactory = new NotebookWidgetFactory({
|
|
417
|
-
name: 'Notebook',
|
|
418
|
-
label: 'Notebook',
|
|
419
|
-
modelName: 'notebook',
|
|
420
|
-
fileTypes: ['notebook'],
|
|
421
|
-
defaultFor: ['notebook'],
|
|
422
|
-
preferKernel: true,
|
|
423
|
-
autoStartDefault: false,
|
|
424
|
-
canStartKernel: false,
|
|
425
|
-
shutdownOnClose: false,
|
|
426
|
-
rendermime: this._rendermime,
|
|
427
|
-
contentFactory: this._contentFactory,
|
|
428
|
-
mimeTypeService: editorServices.mimeTypeService,
|
|
429
|
-
notebookConfig: {
|
|
430
|
-
...StaticNotebook.defaultNotebookConfig,
|
|
431
|
-
recordTiming: true,
|
|
432
|
-
},
|
|
433
|
-
});
|
|
434
|
-
notebookWidgetFactory.widgetCreated.connect((sender, notebookPanel) => {
|
|
435
|
-
notebookPanel.context.pathChanged.connect(() => {
|
|
436
|
-
this._tracker?.save(notebookPanel);
|
|
437
|
-
});
|
|
438
|
-
this._tracker?.add(notebookPanel);
|
|
439
|
-
});
|
|
440
|
-
this._documentRegistry.addWidgetFactory(notebookWidgetFactory);
|
|
441
|
-
this._notebookModelFactory = new JupyterReactNotebookModelFactory({
|
|
442
|
-
nbformat: this._nbformat,
|
|
443
|
-
readonly: this._readonly,
|
|
444
|
-
});
|
|
445
|
-
this._documentRegistry.addModelFactory(this._notebookModelFactory);
|
|
446
|
-
this.initializeContext();
|
|
447
|
-
}
|
|
448
|
-
get id() {
|
|
449
|
-
return this._id;
|
|
450
|
-
}
|
|
451
|
-
get readonly() {
|
|
452
|
-
return this._readonly;
|
|
453
|
-
}
|
|
454
|
-
get serverless() {
|
|
455
|
-
return this._serverless;
|
|
456
|
-
}
|
|
457
|
-
get lite() {
|
|
458
|
-
return this._lite;
|
|
459
|
-
}
|
|
460
|
-
get path() {
|
|
461
|
-
return this._path;
|
|
462
|
-
}
|
|
463
|
-
get url() {
|
|
464
|
-
return this._url;
|
|
465
|
-
}
|
|
466
|
-
get nbformat() {
|
|
467
|
-
return this._nbformat;
|
|
468
315
|
}
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
return this._boxPanel;
|
|
486
|
-
}
|
|
487
|
-
get commands() {
|
|
488
|
-
return this._commands;
|
|
316
|
+
/**
|
|
317
|
+
* NEW ALIGNED TOOL METHODS
|
|
318
|
+
* These methods align 1:1 with tool operation names for seamless integration
|
|
319
|
+
*/
|
|
320
|
+
/**
|
|
321
|
+
* Insert a cell at a specific index (aligned with insertCell tool).
|
|
322
|
+
*
|
|
323
|
+
* @param cellType - Type of cell to insert (code, markdown, or raw)
|
|
324
|
+
* @param cellIndex - Index where to insert (0-based). If undefined, inserts at end.
|
|
325
|
+
* @param source - Optional source code/text for the cell
|
|
326
|
+
*/
|
|
327
|
+
insertCell(cellType, cellIndex, source) {
|
|
328
|
+
this.setDefaultCellType(cellType);
|
|
329
|
+
// Default to cell count (end of notebook) if index not provided
|
|
330
|
+
const targetIndex = cellIndex ?? this.getCellCount();
|
|
331
|
+
this.insertAt(targetIndex, source);
|
|
489
332
|
}
|
|
490
|
-
|
|
491
|
-
|
|
333
|
+
/**
|
|
334
|
+
* Insert multiple cells at a specific index (aligned with insertCells tool).
|
|
335
|
+
*
|
|
336
|
+
* More efficient than calling insertCell multiple times.
|
|
337
|
+
* Cells are inserted sequentially starting at the given index.
|
|
338
|
+
*
|
|
339
|
+
* @param cells - Array of cells to insert (each with type and source)
|
|
340
|
+
* @param cellIndex - Index where to insert first cell (0-based). Use large number for end.
|
|
341
|
+
*/
|
|
342
|
+
insertCells(cells, cellIndex) {
|
|
343
|
+
let currentIndex = cellIndex;
|
|
344
|
+
for (const cell of cells) {
|
|
345
|
+
this.setDefaultCellType(cell.type);
|
|
346
|
+
this.insertAt(currentIndex, cell.source);
|
|
347
|
+
currentIndex++;
|
|
348
|
+
}
|
|
492
349
|
}
|
|
493
|
-
|
|
494
|
-
*
|
|
350
|
+
/**
|
|
351
|
+
* Delete cell(s) at the specified index/indices (aligned with deleteCell tool and Jupyter MCP Server).
|
|
352
|
+
*
|
|
353
|
+
* @param index - Single cell index, array of indices, or undefined.
|
|
354
|
+
* - Single number: Deletes that cell
|
|
355
|
+
* - Array: Deletes all cells at those indices (in reverse order to prevent shifting)
|
|
356
|
+
* - Undefined: Deletes the active cell if one exists
|
|
357
|
+
*
|
|
358
|
+
* @remarks
|
|
359
|
+
* This method matches the Jupyter MCP Server behavior:
|
|
360
|
+
* - Validates ALL indices are in range before deleting any
|
|
361
|
+
* - Deletes in reverse order (highest to lowest) to prevent index shifting
|
|
362
|
+
* - Throws error with MCP-compatible message format if any index is out of range
|
|
363
|
+
*
|
|
364
|
+
* @throws {Error} If any index is out of range
|
|
495
365
|
*/
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
366
|
+
deleteCell(index) {
|
|
367
|
+
const cells = this._notebook.model?.cells;
|
|
368
|
+
const cellCount = cells?.length ?? 0;
|
|
369
|
+
if (index !== undefined) {
|
|
370
|
+
// Convert single index to array for unified handling
|
|
371
|
+
const indices = Array.isArray(index) ? index : [index];
|
|
372
|
+
// Validate ALL indices first (match Jupyter MCP Server error format)
|
|
373
|
+
for (const idx of indices) {
|
|
374
|
+
if (idx < 0 || idx >= cellCount) {
|
|
375
|
+
console.error(`[NotebookAdapter.deleteCell] Index ${idx} is out of range (cell count: ${cellCount})`);
|
|
376
|
+
throw new Error(`Cell index ${idx} is out of range. Notebook has ${cellCount} cells.`);
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
// Sort indices in REVERSE order (highest to lowest) to prevent index shifting
|
|
380
|
+
// This matches the Jupyter MCP Server behavior
|
|
381
|
+
const sortedIndices = [...indices].sort((a, b) => b - a);
|
|
382
|
+
console.log(`[NotebookAdapter.deleteCell] Deleting ${sortedIndices.length} cell(s) in reverse order:`, sortedIndices);
|
|
383
|
+
// Delete each cell in reverse order
|
|
384
|
+
for (const idx of sortedIndices) {
|
|
385
|
+
this.setActiveCell(idx);
|
|
386
|
+
this.deleteCells();
|
|
387
|
+
}
|
|
499
388
|
}
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
this.
|
|
389
|
+
else {
|
|
390
|
+
// No index provided: check if there's an active cell to delete
|
|
391
|
+
const activeCell = this._notebook.activeCell;
|
|
392
|
+
if (!activeCell) {
|
|
393
|
+
console.warn('[NotebookAdapter.deleteCell] No active cell to delete');
|
|
394
|
+
return; // Safely return without deleting
|
|
395
|
+
}
|
|
396
|
+
// Active cell exists, safe to delete
|
|
397
|
+
this.deleteCells();
|
|
503
398
|
}
|
|
504
399
|
}
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
400
|
+
/**
|
|
401
|
+
* Updates cell source at the specified index and returns a diff.
|
|
402
|
+
* Matches MCP server's overwrite_cell_source behavior.
|
|
403
|
+
*
|
|
404
|
+
* @param index - Cell index (0-based)
|
|
405
|
+
* @param source - New cell source content
|
|
406
|
+
* @returns Diff string showing changes made
|
|
407
|
+
* @throws Error if cell index is out of range or cell not found
|
|
408
|
+
*/
|
|
409
|
+
updateCell(index, source) {
|
|
410
|
+
// Validate cell index
|
|
411
|
+
const cellCount = this._notebook.model?.sharedModel.cells.length ?? 0;
|
|
412
|
+
if (index < 0 || index >= cellCount) {
|
|
413
|
+
throw new Error(`Cell index ${index} is out of range. Notebook has ${cellCount} cells.`);
|
|
514
414
|
}
|
|
515
|
-
|
|
516
|
-
this.
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
if (this._readonly !== readonly) {
|
|
520
|
-
this._readonly = readonly;
|
|
521
|
-
this._notebookPanel?.content.widgets.forEach(cell => {
|
|
522
|
-
cell.syncEditable = true;
|
|
523
|
-
cell.model.sharedModel.setMetadata('editable', !readonly);
|
|
524
|
-
});
|
|
525
|
-
const cells = this._context?.model.cells;
|
|
526
|
-
if (cells) {
|
|
527
|
-
Array.from(cells).forEach(cell => {
|
|
528
|
-
cell.setMetadata('editable', !readonly);
|
|
529
|
-
});
|
|
530
|
-
}
|
|
531
|
-
this._notebookPanel?.content.widgets.forEach(cell => {
|
|
532
|
-
cell.saveEditableState();
|
|
533
|
-
});
|
|
415
|
+
// Get the cell at the specified index
|
|
416
|
+
const cellModel = this._notebook.model?.cells.get(index);
|
|
417
|
+
if (!cellModel) {
|
|
418
|
+
throw new Error(`Cell at index ${index} not found.`);
|
|
534
419
|
}
|
|
420
|
+
// Store old source before updating
|
|
421
|
+
const oldSource = cellModel.sharedModel.getSource();
|
|
422
|
+
// Update the cell source
|
|
423
|
+
cellModel.sharedModel.setSource(source);
|
|
424
|
+
// Generate diff (matches MCP server behavior)
|
|
425
|
+
const patch = Diff.createPatch(`cell_${index}`, oldSource, source, 'before', 'after', { context: 3 });
|
|
426
|
+
return patch;
|
|
535
427
|
}
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
428
|
+
/**
|
|
429
|
+
* Get a cell's content by index or active cell (aligned with getCell tool and MCP Server).
|
|
430
|
+
*
|
|
431
|
+
* @param index - Optional cell index (0-based). If not provided, returns active cell.
|
|
432
|
+
* @param includeOutputs - Whether to include cell outputs (default: true)
|
|
433
|
+
* @returns Cell data or undefined if not found
|
|
434
|
+
*/
|
|
435
|
+
getCell(index, includeOutputs = true) {
|
|
436
|
+
if (index !== undefined) {
|
|
437
|
+
// Get cell at specific index
|
|
438
|
+
const cells = this.getCells();
|
|
439
|
+
const cell = cells[index];
|
|
440
|
+
if (!cell)
|
|
441
|
+
return undefined;
|
|
442
|
+
// Get execution count for code cells
|
|
443
|
+
const cellModel = this._notebook.model?.cells.get(index);
|
|
444
|
+
const execution_count = cellModel?.type === 'code'
|
|
445
|
+
? (cellModel.executionCount ?? null)
|
|
446
|
+
: null;
|
|
447
|
+
return {
|
|
448
|
+
type: cell.type,
|
|
449
|
+
source: cell.source,
|
|
450
|
+
execution_count,
|
|
451
|
+
outputs: includeOutputs ? cell.outputs : undefined,
|
|
452
|
+
};
|
|
453
|
+
}
|
|
454
|
+
else {
|
|
455
|
+
// Get active cell
|
|
456
|
+
const activeCell = this._notebook.activeCell;
|
|
457
|
+
if (!activeCell)
|
|
458
|
+
return undefined;
|
|
459
|
+
const execution_count = activeCell.model.type === 'code'
|
|
460
|
+
? (activeCell.model.executionCount ?? null)
|
|
461
|
+
: null;
|
|
462
|
+
return {
|
|
463
|
+
type: activeCell.model.type,
|
|
464
|
+
source: activeCell.model.sharedModel.getSource(),
|
|
465
|
+
execution_count,
|
|
466
|
+
outputs: includeOutputs && activeCell.model.type === 'code'
|
|
467
|
+
? activeCell.model.outputs?.toJSON()
|
|
468
|
+
: undefined,
|
|
469
|
+
};
|
|
540
470
|
}
|
|
541
471
|
}
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
472
|
+
/**
|
|
473
|
+
* Run a cell and optionally capture outputs (aligned with runCell tool).
|
|
474
|
+
*
|
|
475
|
+
* @param params - Parameters for cell execution
|
|
476
|
+
* @param params.index - Cell index to run (optional, defaults to active cell)
|
|
477
|
+
* @param params.timeoutSeconds - Timeout in seconds (optional, for future use)
|
|
478
|
+
* @param params.stream - Enable streaming progress (optional, for future use)
|
|
479
|
+
* @param params.progressInterval - Progress update interval (optional, for future use)
|
|
480
|
+
* @returns Promise resolving to execution result with outputs
|
|
481
|
+
*/
|
|
482
|
+
async runCell(params) {
|
|
483
|
+
const { index } = params || {};
|
|
484
|
+
// Note: timeoutSeconds, stream, progressInterval are accepted for future use
|
|
485
|
+
// but timeout/streaming logic is handled at the operation layer
|
|
486
|
+
// Set active cell if index provided
|
|
487
|
+
if (index !== undefined) {
|
|
488
|
+
this.setActiveCell(index);
|
|
489
|
+
}
|
|
490
|
+
const targetIndex = index ?? this._notebook.activeCellIndex;
|
|
491
|
+
if (targetIndex === -1) {
|
|
492
|
+
throw new Error('No active cell to execute');
|
|
493
|
+
}
|
|
494
|
+
// Execute the cell using JupyterLab's NotebookActions
|
|
495
|
+
await NotebookActions.run(this._notebook, this._context.sessionContext);
|
|
496
|
+
// Wait a brief moment for outputs to be available
|
|
497
|
+
await new Promise(resolve => setTimeout(resolve, 100));
|
|
498
|
+
// Capture outputs after execution
|
|
499
|
+
const cellData = this.getCell(targetIndex, true);
|
|
500
|
+
if (!cellData) {
|
|
501
|
+
return {
|
|
502
|
+
execution_count: null,
|
|
503
|
+
outputs: [],
|
|
504
|
+
};
|
|
546
505
|
}
|
|
506
|
+
// Convert outputs to string array (matching MCP format)
|
|
507
|
+
const outputs = [];
|
|
508
|
+
if (cellData.outputs && Array.isArray(cellData.outputs)) {
|
|
509
|
+
for (const output of cellData.outputs) {
|
|
510
|
+
if (typeof output === 'string') {
|
|
511
|
+
outputs.push(output);
|
|
512
|
+
}
|
|
513
|
+
else if (output && typeof output === 'object') {
|
|
514
|
+
// Handle different output types
|
|
515
|
+
const outputObj = output;
|
|
516
|
+
if (outputObj.output_type === 'stream') {
|
|
517
|
+
const text = outputObj.text;
|
|
518
|
+
if (typeof text === 'string') {
|
|
519
|
+
outputs.push(text);
|
|
520
|
+
}
|
|
521
|
+
else if (Array.isArray(text)) {
|
|
522
|
+
outputs.push(text.join(''));
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
else if (outputObj.output_type === 'execute_result' ||
|
|
526
|
+
outputObj.output_type === 'display_data') {
|
|
527
|
+
const data = outputObj.data;
|
|
528
|
+
if (data) {
|
|
529
|
+
// Prefer text/plain output
|
|
530
|
+
if (data['text/plain']) {
|
|
531
|
+
const text = data['text/plain'];
|
|
532
|
+
if (typeof text === 'string') {
|
|
533
|
+
outputs.push(text);
|
|
534
|
+
}
|
|
535
|
+
else if (Array.isArray(text)) {
|
|
536
|
+
outputs.push(text.join(''));
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
else if (outputObj.output_type === 'error') {
|
|
542
|
+
// Format error output
|
|
543
|
+
const ename = outputObj.ename ?? 'Error';
|
|
544
|
+
const evalue = outputObj.evalue ?? '';
|
|
545
|
+
const traceback = outputObj.traceback;
|
|
546
|
+
if (Array.isArray(traceback) && traceback.length > 0) {
|
|
547
|
+
outputs.push(`[ERROR: ${ename}: ${evalue}]\n${traceback.join('\n')}`);
|
|
548
|
+
}
|
|
549
|
+
else {
|
|
550
|
+
outputs.push(`[ERROR: ${ename}: ${evalue}]`);
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
return {
|
|
557
|
+
execution_count: cellData.execution_count,
|
|
558
|
+
outputs,
|
|
559
|
+
};
|
|
547
560
|
}
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
561
|
+
/**
|
|
562
|
+
* Run all cells in the notebook (aligned with runAllCells tool).
|
|
563
|
+
*/
|
|
564
|
+
runAllCells() {
|
|
565
|
+
this._commands.execute(NotebookCommandIds.runAll);
|
|
553
566
|
}
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
567
|
+
/**
|
|
568
|
+
* Clear all outputs from all cells in the notebook.
|
|
569
|
+
*
|
|
570
|
+
* @remarks
|
|
571
|
+
* Removes all execution outputs from all cells. This operation:
|
|
572
|
+
* - Clears outputs but preserves cell source code
|
|
573
|
+
* - Resets execution counts
|
|
574
|
+
* - Cannot be undone
|
|
575
|
+
*/
|
|
576
|
+
clearAllOutputs() {
|
|
577
|
+
NotebookActions.clearAllOutputs(this._notebook);
|
|
578
|
+
}
|
|
579
|
+
/**
|
|
580
|
+
* Execute code directly in the kernel without creating a cell.
|
|
581
|
+
*
|
|
582
|
+
* This method sends code execution requests directly to the kernel,
|
|
583
|
+
* bypassing the notebook cell model. Useful for:
|
|
584
|
+
* - Variable inspection
|
|
585
|
+
* - Environment setup
|
|
586
|
+
* - Background tasks
|
|
587
|
+
* - Tool introspection
|
|
588
|
+
*
|
|
589
|
+
* @param code - Code to execute
|
|
590
|
+
* @param options - Execution options
|
|
591
|
+
* @returns Promise with execution result including outputs
|
|
592
|
+
*/
|
|
593
|
+
async executeCode(code, options = {}) {
|
|
594
|
+
const sessionContext = this._panel.sessionContext;
|
|
595
|
+
if (!sessionContext || !sessionContext.session?.kernel) {
|
|
596
|
+
return {
|
|
597
|
+
success: false,
|
|
598
|
+
error: 'No active kernel session',
|
|
599
|
+
};
|
|
600
|
+
}
|
|
601
|
+
const kernel = sessionContext.session.kernel;
|
|
602
|
+
try {
|
|
603
|
+
const future = kernel.requestExecute({
|
|
604
|
+
code,
|
|
605
|
+
stop_on_error: true, // Internal default: stop on error
|
|
606
|
+
store_history: false, // Internal default: don't store in history
|
|
607
|
+
silent: false, // Internal default: not silent (show outputs)
|
|
608
|
+
allow_stdin: false,
|
|
609
|
+
});
|
|
610
|
+
const outputs = [];
|
|
611
|
+
let executionCount;
|
|
612
|
+
// Collect outputs
|
|
613
|
+
future.onIOPub = msg => {
|
|
614
|
+
const msgType = msg.header.msg_type;
|
|
615
|
+
if (msgType === 'stream') {
|
|
616
|
+
outputs.push({
|
|
617
|
+
type: 'stream',
|
|
618
|
+
content: msg.content,
|
|
573
619
|
});
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
620
|
+
}
|
|
621
|
+
else if (msgType === 'execute_result') {
|
|
622
|
+
outputs.push({
|
|
623
|
+
type: 'execute_result',
|
|
624
|
+
content: msg.content,
|
|
625
|
+
});
|
|
626
|
+
executionCount = msg.content.execution_count;
|
|
627
|
+
}
|
|
628
|
+
else if (msgType === 'display_data') {
|
|
629
|
+
outputs.push({
|
|
630
|
+
type: 'display_data',
|
|
631
|
+
content: msg.content,
|
|
632
|
+
});
|
|
633
|
+
}
|
|
634
|
+
else if (msgType === 'error') {
|
|
635
|
+
outputs.push({
|
|
636
|
+
type: 'error',
|
|
637
|
+
content: msg.content,
|
|
638
|
+
});
|
|
639
|
+
}
|
|
640
|
+
};
|
|
641
|
+
// Handle timeout if specified (default: 30 seconds, max: 60)
|
|
642
|
+
const timeoutMs = (options.timeout ?? 30) * 1000;
|
|
643
|
+
const executionPromise = future.done;
|
|
644
|
+
const timeoutPromise = new Promise((_, reject) => {
|
|
645
|
+
setTimeout(() => {
|
|
646
|
+
reject(new Error(`Execution timeout after ${options.timeout ?? 30} seconds`));
|
|
647
|
+
}, timeoutMs);
|
|
648
|
+
});
|
|
649
|
+
try {
|
|
650
|
+
await Promise.race([executionPromise, timeoutPromise]);
|
|
584
651
|
}
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
const notebook = this._notebookPanel.content;
|
|
590
|
-
const model = this._notebookPanel.context.model;
|
|
591
|
-
const newIndex = notebook.activeCell ? notebook.activeCellIndex : 0;
|
|
592
|
-
model.sharedModel.insertCell(newIndex, {
|
|
593
|
-
cell_type: notebook.notebookConfig.defaultCell,
|
|
594
|
-
source,
|
|
595
|
-
metadata: notebook.notebookConfig.defaultCell === 'code'
|
|
596
|
-
? {
|
|
597
|
-
// This is an empty cell created by user, thus is trusted
|
|
598
|
-
trusted: true,
|
|
652
|
+
catch (timeoutError) {
|
|
653
|
+
// Interrupt kernel on timeout
|
|
654
|
+
try {
|
|
655
|
+
await kernel.interrupt();
|
|
599
656
|
}
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
// Make the newly inserted cell active.
|
|
603
|
-
notebook.activeCellIndex = newIndex;
|
|
604
|
-
notebook.deselectAll();
|
|
605
|
-
};
|
|
606
|
-
insertBelow = (source) => {
|
|
607
|
-
const notebook = this._notebookPanel.content;
|
|
608
|
-
const model = this._notebookPanel.context.model;
|
|
609
|
-
const newIndex = notebook.activeCell ? notebook.activeCellIndex + 1 : 0;
|
|
610
|
-
model.sharedModel.insertCell(newIndex, {
|
|
611
|
-
cell_type: notebook.notebookConfig.defaultCell,
|
|
612
|
-
source,
|
|
613
|
-
metadata: notebook.notebookConfig.defaultCell === 'code'
|
|
614
|
-
? {
|
|
615
|
-
// This is an empty cell created by user, thus is trusted.
|
|
616
|
-
trusted: true,
|
|
657
|
+
catch (interruptError) {
|
|
658
|
+
console.error('Failed to interrupt kernel:', interruptError);
|
|
617
659
|
}
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
660
|
+
return {
|
|
661
|
+
success: false,
|
|
662
|
+
error: `Execution exceeded ${options.timeout ?? 30} seconds and was interrupted`,
|
|
663
|
+
outputs,
|
|
664
|
+
};
|
|
665
|
+
}
|
|
666
|
+
return {
|
|
667
|
+
success: true,
|
|
668
|
+
outputs,
|
|
669
|
+
executionCount,
|
|
670
|
+
};
|
|
671
|
+
}
|
|
672
|
+
catch (error) {
|
|
673
|
+
return {
|
|
674
|
+
success: false,
|
|
675
|
+
error: error instanceof Error ? error.message : String(error),
|
|
676
|
+
};
|
|
677
|
+
}
|
|
678
|
+
}
|
|
679
|
+
/**
|
|
680
|
+
* Dispose of the adapter.
|
|
681
|
+
*/
|
|
682
|
+
dispose() {
|
|
683
|
+
// Clean up any resources if needed
|
|
684
|
+
// The panel, notebook, and context are managed by NotebookBase
|
|
685
|
+
}
|
|
630
686
|
}
|
|
631
687
|
export default NotebookAdapter;
|
|
632
688
|
//# sourceMappingURL=NotebookAdapter.js.map
|