Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
ffe0958
chore(dep): Update deepnote database integrations package
tkislan Mar 9, 2026
3bb72eb
Reformat code
tkislan Mar 9, 2026
5148b03
Merge branch 'main' into tk/update-deepnote-database-integrations
tkislan Mar 9, 2026
d5f67f6
chore(runtime-core): Add deepnote runtime-core dependency, and use it…
tkislan Mar 10, 2026
ff6d44f
feat: Add Agent block visualization support
tkislan Mar 11, 2026
957fdcd
Add a dummy agent block execution handler
tkislan Mar 12, 2026
9fbe622
feat(agent-block): Integrate deepnote runtime-core to execute Agent b…
tkislan Mar 13, 2026
46f9a4c
feat(agent-cell): Enhance executeAgentCell with options for custom ex…
tkislan Mar 14, 2026
58e653d
feat(ephemeral-cells): Introduce isEphemeralCell utility and enhance …
tkislan Mar 16, 2026
401681c
Merge remote-tracking branch 'origin/main' into tk/deepnote-runtime-core
tkislan Mar 16, 2026
6f7b4aa
Refactor Deepnote server management to utilize a new mock child proce…
tkislan Mar 16, 2026
7d8ee86
Fix eslint error
tkislan Mar 16, 2026
9c4151a
Enhance Deepnote server stopping logic to handle missing project context
tkislan Mar 17, 2026
347a809
Refactor Deepnote server management to use fileKey instead of serverKey
tkislan Mar 17, 2026
5eb2c17
Refactor DeepnoteServerStarter to remove port allocation logic
tkislan Mar 17, 2026
3740df1
Enhance DeepnoteServerStarter with output tracking and error reportin…
tkislan Mar 17, 2026
06a0367
Update error handling in DeepnoteServerStarter to improve diagnostics
tkislan Mar 17, 2026
1e7cb07
Reformat code
tkislan Mar 17, 2026
4f0248d
Merge branch 'main' into tk/deepnote-runtime-core
tkislan Mar 18, 2026
9757a05
Merge remote-tracking branch 'origin/tk/deepnote-runtime-core' into t…
tkislan Mar 18, 2026
75d0220
Enhance agent cell execution handling and status bar provider
tkislan Mar 18, 2026
f7bec65
Add Agent OpenAI API key extension configuration
tkislan Mar 18, 2026
ea715e7
Implement OpenAI API key management in Deepnote
tkislan Mar 18, 2026
197dd44
Merge branch 'main' into tk/deepnote-agent-block
tkislan Jul 31, 2026
3b2b950
fix(agent-block): adapt agent cell execution to runtime-core 0.4.0 API
tkislan Jul 31, 2026
a010e07
fix(agent-block): reject boolean max-iteration metadata
tkislan Jul 31, 2026
cbbf91c
Add hubot to cspell config
tkislan Jul 31, 2026
cdc2a46
fix(agent-block): type the markdown-it renderer hook instead of using…
tkislan Jul 31, 2026
2567e38
fix(agent-block): address pre-merge review findings
tkislan Aug 3, 2026
33f95f4
Update code comment
tkislan Aug 3, 2026
2027341
fix(agent-block): correct controller, cleanup, timeout and integratio…
tkislan Aug 3, 2026
4b55d47
test(agent-block): move isAgentCell tests alongside their source
tkislan Aug 4, 2026
c1c9db2
test(agent-block): add an E2E test for the agent tool loop
tkislan Aug 4, 2026
4c897f5
test(agent-block): scope the mock server to the attempt, not the suite
tkislan Aug 4, 2026
8339146
test(agent-block): script the mock in the test, release it around eac…
tkislan Aug 4, 2026
eb2a868
fix(e2e): make the mocha root hooks actually run
tkislan Aug 4, 2026
84c3ced
fix(agent-block): clear the previous run before the batch executes
tkislan Aug 5, 2026
604d90c
fix(build): keep runtime-core out of the web bundle
tkislan Aug 5, 2026
b7f9ac7
refactor(agent-block): tighten PR code per engineering standards
tkislan Aug 5, 2026
53398c4
refactor(agent-block): split OpenAI key commands from status bar
tkislan Aug 5, 2026
d6338dc
fix(agent-block): keep ephemeral cells when the watcher reads back ou…
tkislan Aug 5, 2026
c9f7c60
test(agent-block): pin the streamed transcript rendering in E2E
tkislan Aug 5, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .github/workflows/e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,10 @@ jobs:
- name: Install the Python extension into the test instance
run: npm run setup:e2e:deps

- name: Pre-download the mock LLM server
# aimock is npx-only (not in lockfile), so setup-node never restores ~/.npm/_npx.
run: npm run setup:e2e:mock

- name: Cache pip wheel downloads
# Provisioning the Deepnote environment pip-installs the toolkit dependency tree into a
# fresh venv on first kernel connect — the bulk of the E2E runtime. Caching pip's wheel
Expand Down
3 changes: 2 additions & 1 deletion build/esbuild/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@ const commonExternals = [
const webExternals = [
...commonExternals,
'canvas', // Native module used by vega for server-side rendering, not needed in browser
'mathjax-electron' // Uses Node.js path module, MathJax rendering handled differently in browser
'mathjax-electron', // Uses Node.js path module, MathJax rendering handled differently in browser
'@deepnote/runtime-core' // Node built-ins (net, child_process); agent blocks run on desktop only
];
const desktopExternals = [...commonExternals, ...deskTopNodeModulesToExternalize];
const bundleConfig = getBundleConfiguration();
Expand Down
1 change: 1 addition & 0 deletions cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
"evalue",
"findstr",
"getsitepackages",
"hubot",
"IMAGENAME",
"ipykernel",
"ipynb",
Expand Down
13 changes: 12 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,16 @@
"title": "%deepnote.command.manageAccessToKernels%",
"category": "Jupyter"
},
{
"command": "deepnote.setOpenAiApiKey",
"title": "%deepnote.command.setOpenAiApiKey%",
"category": "Deepnote"
},
{
"command": "deepnote.clearOpenAiApiKey",
"title": "%deepnote.command.clearOpenAiApiKey%",
"category": "Deepnote"
},
{
"command": "dataScience.ClearUserProviderJupyterServerCache",
"title": "%deepnote.command.dataScience.clearUserProviderJupyterServerCache.title%",
Expand Down Expand Up @@ -2660,7 +2670,8 @@
"compile-e2e-watch": "tsc -p ./test/e2e/tsconfig.json --watch",
"setup:e2e:vscode": "extest get-vscode -c max && extest get-chromedriver -c max",
"setup:e2e:deps": "extest install-from-marketplace ms-python.python -e .test-extensions",
"setup:e2e": "npm run setup:e2e:vscode && npm run setup:e2e:deps",
"setup:e2e:mock": "npx -y -p @copilotkit/aimock@1.37.4 llmock --help",
"setup:e2e": "npm run setup:e2e:vscode && npm run setup:e2e:deps && npm run setup:e2e:mock",
"test:e2e": "extest setup-and-run \"./out/e2e/suite/*.e2e.test.js\" -c max -o ./test/e2e/settings.json -e .test-extensions -m ./test/e2e/.mocharc.js -i",
"test:e2e:prebuilt": "extest run-tests \"./out/e2e/suite/*.e2e.test.js\" -c max -o ./test/e2e/settings.json -e .test-extensions -m ./test/e2e/.mocharc.js",
"test:unittests": "mocha --config ./build/.mocha.unittests.js.json ./out/**/*.unit.test.js",
Expand Down
2 changes: 2 additions & 0 deletions package.nls.json
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,8 @@
"deepnote.command.deepnote.openOutlineView.title": "Show Table Of Contents (Outline View)",
"deepnote.command.deepnote.openOutlineView.shorttitle": "Outline",
"deepnote.command.manageAccessToKernels": "Manage Access To Jupyter Kernels",
"deepnote.command.setOpenAiApiKey": "Set OpenAI API Key",
"deepnote.command.clearOpenAiApiKey": "Clear OpenAI API Key",
"deepnote.commandPalette.deepnote.replayPylanceLog.title": "Replay Pylance Log",
"deepnote.notebookRenderer.IPyWidget.displayName": "Jupyter IPyWidget Renderer",
"deepnote.notebookRenderer.Error.displayName": "Jupyter Error Renderer",
Expand Down
44 changes: 38 additions & 6 deletions src/notebooks/controllers/vscodeNotebookController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ import { RemoteKernelReconnectBusyIndicator } from './remoteKernelReconnectBusyI
import { IConnectionDisplayData, IConnectionDisplayDataProvider, IVSCodeNotebookController } from './types';
import { notebookPathToDeepnoteProjectFilePath } from '../../platform/deepnote/deepnoteProjectUtils';
import { DEEPNOTE_NOTEBOOK_TYPE, IDeepnoteKernelAutoSelector } from '../../kernels/deepnote/types';
import { executeAgentCell, removeEphemeralCellsForAgentBlocks } from '../deepnote/agentCellExecutionHandler';
import { isAgentCell } from '../deepnote/dataConversionUtils';

/**
* Our implementation of the VSCode Notebook Controller. Called by VS code to execute cells in a notebook. Also displayed
Expand Down Expand Up @@ -624,18 +626,48 @@ export class VSCodeNotebookController implements Disposable, IVSCodeNotebookCont
if (!this.cellQueue.has(doc)) {
return;
}
const queuedCells = this.cellQueue.get(doc) || [];
// Clear before await so agent-driven re-entrant runs start with an empty queue.
this.cellQueue.delete(doc);

const cellsToExecute = await removeEphemeralCellsForAgentBlocks(doc, queuedCells);

let pendingKernelCells: NotebookCell[] = [];

for (const cell of cellsToExecute) {
if (!isAgentCell(cell)) {
pendingKernelCells.push(cell);
continue;
}

await this.executeKernelCells(doc, pendingKernelCells);
pendingKernelCells = [];

logger.trace(`Executing agent cell ${cell.index} for ${getDisplayPath(doc.uri)} without kernel`);
await executeAgentCell(cell, this.controller).catch(noop);
}

await this.executeKernelCells(doc, pendingKernelCells);
}

private async executeKernelCells(doc: NotebookDocument, cells: NotebookCell[]) {
// Start execution now (from the user's point of view)
// Creating these execution objects marks the cell as queued for execution (vscode will update cell UI).
type CellExec = { cell: NotebookCell; exec: NotebookCellExecution };
const cellExecs: CellExec[] = (this.cellQueue.get(doc) || []).map((cell) => {

// Stale cell handles report index -1; createNotebookCellExecution would abort the batch.
const kernelCells = cells.filter((cell) => cell.index >= 0);

if (kernelCells.length === 0) {
return;
}

const cellExecs: CellExec[] = kernelCells.map((cell) => {
const exec = this.createCellExecutionIfNecessary(cell, new KernelController(this.controller));
return { cell, exec };
});
this.cellQueue.delete(doc);
const firstCell = cellExecs.length ? cellExecs[0].cell : undefined;
if (!firstCell) {
return;
}

const firstCell = cellExecs[0].cell;

logger.trace(`Execute Notebook ${getDisplayPath(doc.uri)}. Step 1`);

Expand Down
Loading
Loading