@bike4mind/cli 0.2.56 → 0.2.57-feat-jupyter-interoperability-roadmap.21458
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/dist/{artifactExtractor-ABHS5PT3.js → artifactExtractor-GTMSICU4.js} +1 -1
- package/dist/{chunk-524RAWPN.js → chunk-3JJYLK4C.js} +1 -1
- package/dist/{chunk-S27A7SCI.js → chunk-67YAACDQ.js} +2 -2
- package/dist/{chunk-KGAK226I.js → chunk-AWG7GGY5.js} +1 -1
- package/dist/{chunk-SA2GRZGG.js → chunk-O55VX62E.js} +244 -4
- package/dist/{chunk-VILQBYE6.js → chunk-RIFFSKKB.js} +2 -2
- package/dist/{chunk-5UDVBQZ7.js → chunk-TYXGSRCJ.js} +7 -7
- package/dist/{chunk-I5ZF2OVL.js → chunk-VWH4PFPB.js} +124 -3
- package/dist/{chunk-XACIOJZ7.js → chunk-YKQNMQX5.js} +2 -2
- package/dist/commands/doctorCommand.js +1 -1
- package/dist/commands/headlessCommand.js +7 -7
- package/dist/commands/mcpCommand.js +2 -2
- package/dist/commands/updateCommand.js +1 -1
- package/dist/{create-72N2ZGVO.js → create-3EHSR6G6.js} +3 -3
- package/dist/index.js +359 -9
- package/dist/{llmMarkdownGenerator-2NOW6PWQ.js → llmMarkdownGenerator-IJTR5Q4D.js} +1 -1
- package/dist/{markdownGenerator-4P3ZQHNH.js → markdownGenerator-HCAWT5AN.js} +1 -1
- package/dist/{mementoService-H35TY4ZN.js → mementoService-FFOGSHGY.js} +3 -3
- package/dist/{src-NQXGURIE.js → src-FESQ52E6.js} +17 -1
- package/dist/{src-2BN3ALZD.js → src-SXD7R5WA.js} +2 -2
- package/dist/{subtractCredits-XRG2QRZG.js → subtractCredits-PATASZEG.js} +3 -3
- package/package.json +7 -7
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
CurationArtifactType
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-VWH4PFPB.js";
|
|
5
5
|
|
|
6
6
|
// ../../b4m-core/packages/services/dist/src/notebookCurationService/artifactExtractor.js
|
|
7
7
|
var ARTIFACT_TAG_REGEX = /<artifact\s+(.*?)>([\s\S]*?)<\/artifact>/gi;
|
|
@@ -7,11 +7,11 @@ import {
|
|
|
7
7
|
getSettingsMap,
|
|
8
8
|
getSettingsValue,
|
|
9
9
|
secureParameters
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-AWG7GGY5.js";
|
|
11
11
|
import {
|
|
12
12
|
KnowledgeType,
|
|
13
13
|
SupportedFabFileMimeTypes
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-VWH4PFPB.js";
|
|
15
15
|
|
|
16
16
|
// ../../b4m-core/packages/services/dist/src/fabFileService/create.js
|
|
17
17
|
import { z } from "zod";
|
|
@@ -20,7 +20,7 @@ import {
|
|
|
20
20
|
extractSnippetMeta,
|
|
21
21
|
isGPTImageModel,
|
|
22
22
|
settingsMap
|
|
23
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-VWH4PFPB.js";
|
|
24
24
|
|
|
25
25
|
// ../../b4m-core/packages/utils/dist/src/storage/S3Storage.js
|
|
26
26
|
import { S3Client, PutObjectCommand, DeleteObjectCommand, GetObjectCommand, HeadObjectCommand } from "@aws-sdk/client-s3";
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
getOpenWeatherKey,
|
|
5
5
|
getSerperKey,
|
|
6
6
|
getWolframAlphaKey
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-YKQNMQX5.js";
|
|
8
8
|
import {
|
|
9
9
|
BFLImageService,
|
|
10
10
|
BaseStorage,
|
|
@@ -16,14 +16,14 @@ import {
|
|
|
16
16
|
OpenAIBackend,
|
|
17
17
|
OpenAIImageService,
|
|
18
18
|
XAIImageService
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-AWG7GGY5.js";
|
|
20
20
|
import {
|
|
21
21
|
Logger
|
|
22
22
|
} from "./chunk-PFBYGCOW.js";
|
|
23
23
|
import {
|
|
24
24
|
ConfigStore,
|
|
25
25
|
logger
|
|
26
|
-
} from "./chunk-
|
|
26
|
+
} from "./chunk-3JJYLK4C.js";
|
|
27
27
|
import {
|
|
28
28
|
ALERT_THRESHOLDS,
|
|
29
29
|
AiEvents,
|
|
@@ -84,7 +84,7 @@ import {
|
|
|
84
84
|
getViewById,
|
|
85
85
|
resolveNavigationIntents,
|
|
86
86
|
sanitizeTelemetryError
|
|
87
|
-
} from "./chunk-
|
|
87
|
+
} from "./chunk-VWH4PFPB.js";
|
|
88
88
|
|
|
89
89
|
// src/utils/fileSearch.ts
|
|
90
90
|
import * as fs from "fs";
|
|
@@ -11981,6 +11981,244 @@ BLOCKED OPERATIONS:
|
|
|
11981
11981
|
})
|
|
11982
11982
|
};
|
|
11983
11983
|
|
|
11984
|
+
// ../../b4m-core/packages/services/dist/src/llm/tools/implementation/jupyterNotebook/notebookStructure.js
|
|
11985
|
+
var KERNEL_CONFIGS = {
|
|
11986
|
+
python3: {
|
|
11987
|
+
display_name: "Python 3",
|
|
11988
|
+
language: "python",
|
|
11989
|
+
language_info: {
|
|
11990
|
+
name: "python",
|
|
11991
|
+
version: "3.10",
|
|
11992
|
+
mimetype: "text/x-python",
|
|
11993
|
+
file_extension: ".py",
|
|
11994
|
+
codemirror_mode: { name: "ipython", version: 3 },
|
|
11995
|
+
pygments_lexer: "ipython3",
|
|
11996
|
+
nbconvert_exporter: "python"
|
|
11997
|
+
}
|
|
11998
|
+
},
|
|
11999
|
+
python: {
|
|
12000
|
+
display_name: "Python",
|
|
12001
|
+
language: "python",
|
|
12002
|
+
language_info: {
|
|
12003
|
+
name: "python",
|
|
12004
|
+
version: "3.10",
|
|
12005
|
+
mimetype: "text/x-python",
|
|
12006
|
+
file_extension: ".py",
|
|
12007
|
+
codemirror_mode: { name: "ipython", version: 3 },
|
|
12008
|
+
pygments_lexer: "ipython3",
|
|
12009
|
+
nbconvert_exporter: "python"
|
|
12010
|
+
}
|
|
12011
|
+
},
|
|
12012
|
+
ir: {
|
|
12013
|
+
display_name: "R",
|
|
12014
|
+
language: "R",
|
|
12015
|
+
language_info: {
|
|
12016
|
+
name: "R",
|
|
12017
|
+
version: "4.3",
|
|
12018
|
+
mimetype: "text/x-r-source",
|
|
12019
|
+
file_extension: ".r",
|
|
12020
|
+
codemirror_mode: "r"
|
|
12021
|
+
}
|
|
12022
|
+
},
|
|
12023
|
+
"julia-1.9": {
|
|
12024
|
+
display_name: "Julia 1.9",
|
|
12025
|
+
language: "julia",
|
|
12026
|
+
language_info: {
|
|
12027
|
+
name: "julia",
|
|
12028
|
+
version: "1.9",
|
|
12029
|
+
mimetype: "application/julia",
|
|
12030
|
+
file_extension: ".jl"
|
|
12031
|
+
}
|
|
12032
|
+
},
|
|
12033
|
+
"julia-1.10": {
|
|
12034
|
+
display_name: "Julia 1.10",
|
|
12035
|
+
language: "julia",
|
|
12036
|
+
language_info: {
|
|
12037
|
+
name: "julia",
|
|
12038
|
+
version: "1.10",
|
|
12039
|
+
mimetype: "application/julia",
|
|
12040
|
+
file_extension: ".jl"
|
|
12041
|
+
}
|
|
12042
|
+
}
|
|
12043
|
+
};
|
|
12044
|
+
function createEmptyNotebook(kernelName = "python3") {
|
|
12045
|
+
const config = KERNEL_CONFIGS[kernelName] ?? KERNEL_CONFIGS["python3"];
|
|
12046
|
+
return {
|
|
12047
|
+
nbformat: 4,
|
|
12048
|
+
nbformat_minor: 5,
|
|
12049
|
+
metadata: {
|
|
12050
|
+
kernelspec: {
|
|
12051
|
+
name: kernelName,
|
|
12052
|
+
display_name: config.display_name,
|
|
12053
|
+
language: config.language
|
|
12054
|
+
},
|
|
12055
|
+
language_info: config.language_info
|
|
12056
|
+
},
|
|
12057
|
+
cells: []
|
|
12058
|
+
};
|
|
12059
|
+
}
|
|
12060
|
+
function generateCellId() {
|
|
12061
|
+
const chars = "abcdefghijklmnopqrstuvwxyz0123456789";
|
|
12062
|
+
let id = "";
|
|
12063
|
+
for (let i = 0; i < 8; i++) {
|
|
12064
|
+
id += chars.charAt(Math.floor(Math.random() * chars.length));
|
|
12065
|
+
}
|
|
12066
|
+
return id;
|
|
12067
|
+
}
|
|
12068
|
+
function normalizeSource(source) {
|
|
12069
|
+
const lines = source.split("\n");
|
|
12070
|
+
return lines.map((line, index) => index < lines.length - 1 ? line + "\n" : line);
|
|
12071
|
+
}
|
|
12072
|
+
function addCodeCell(notebook, code, metadata = {}) {
|
|
12073
|
+
notebook.cells.push({
|
|
12074
|
+
cell_type: "code",
|
|
12075
|
+
id: generateCellId(),
|
|
12076
|
+
source: normalizeSource(code),
|
|
12077
|
+
metadata,
|
|
12078
|
+
outputs: [],
|
|
12079
|
+
execution_count: null
|
|
12080
|
+
});
|
|
12081
|
+
}
|
|
12082
|
+
function addMarkdownCell(notebook, markdown, metadata = {}) {
|
|
12083
|
+
notebook.cells.push({
|
|
12084
|
+
cell_type: "markdown",
|
|
12085
|
+
id: generateCellId(),
|
|
12086
|
+
source: normalizeSource(markdown),
|
|
12087
|
+
metadata
|
|
12088
|
+
});
|
|
12089
|
+
}
|
|
12090
|
+
function serializeNotebook(notebook) {
|
|
12091
|
+
return JSON.stringify(notebook, null, 1);
|
|
12092
|
+
}
|
|
12093
|
+
|
|
12094
|
+
// ../../b4m-core/packages/services/dist/src/llm/tools/implementation/jupyterNotebook/index.js
|
|
12095
|
+
var NOTEBOOK_GENERATION_PROMPT = `You are an expert data scientist generating a Jupyter notebook.
|
|
12096
|
+
|
|
12097
|
+
Create a well-structured notebook that:
|
|
12098
|
+
1. Starts with a markdown cell explaining the analysis objective
|
|
12099
|
+
2. Includes necessary imports in the first code cell
|
|
12100
|
+
3. Loads and explores the data
|
|
12101
|
+
4. Performs the requested analysis
|
|
12102
|
+
5. Visualizes results where appropriate
|
|
12103
|
+
6. Ends with a summary markdown cell
|
|
12104
|
+
|
|
12105
|
+
Guidelines:
|
|
12106
|
+
- Use pandas for data manipulation
|
|
12107
|
+
- Use matplotlib/seaborn for basic visualizations
|
|
12108
|
+
- Use plotly for interactive charts if requested
|
|
12109
|
+
- Include comments explaining key steps
|
|
12110
|
+
- Handle potential errors gracefully
|
|
12111
|
+
- Print intermediate results for debugging
|
|
12112
|
+
|
|
12113
|
+
Return the notebook content as a JSON object with this structure:
|
|
12114
|
+
{
|
|
12115
|
+
"title": "Notebook title",
|
|
12116
|
+
"cells": [
|
|
12117
|
+
{ "type": "markdown", "content": "# Title\\n\\nDescription..." },
|
|
12118
|
+
{ "type": "code", "content": "import pandas as pd\\nimport numpy as np" },
|
|
12119
|
+
...
|
|
12120
|
+
]
|
|
12121
|
+
}`;
|
|
12122
|
+
function parseNotebookResponse(response) {
|
|
12123
|
+
const jsonMatch = response.match(/\{[\s\S]*\}/);
|
|
12124
|
+
if (!jsonMatch) {
|
|
12125
|
+
throw new Error("Failed to parse notebook structure from LLM response");
|
|
12126
|
+
}
|
|
12127
|
+
try {
|
|
12128
|
+
const parsed = JSON.parse(jsonMatch[0]);
|
|
12129
|
+
if (!parsed.cells || !Array.isArray(parsed.cells)) {
|
|
12130
|
+
throw new Error("Invalid notebook structure: missing cells array");
|
|
12131
|
+
}
|
|
12132
|
+
return parsed;
|
|
12133
|
+
} catch (e) {
|
|
12134
|
+
throw new Error(`Failed to parse notebook JSON: ${e instanceof Error ? e.message : String(e)}`);
|
|
12135
|
+
}
|
|
12136
|
+
}
|
|
12137
|
+
function buildNotebook(response, kernelName, metadata) {
|
|
12138
|
+
const notebook = createEmptyNotebook(kernelName);
|
|
12139
|
+
notebook.metadata.title = response.title;
|
|
12140
|
+
notebook.metadata.b4m_metadata = {
|
|
12141
|
+
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
12142
|
+
...metadata
|
|
12143
|
+
};
|
|
12144
|
+
for (const cell of response.cells) {
|
|
12145
|
+
if (cell.type === "markdown") {
|
|
12146
|
+
addMarkdownCell(notebook, cell.content);
|
|
12147
|
+
} else if (cell.type === "code") {
|
|
12148
|
+
addCodeCell(notebook, cell.content);
|
|
12149
|
+
}
|
|
12150
|
+
}
|
|
12151
|
+
return notebook;
|
|
12152
|
+
}
|
|
12153
|
+
var jupyterNotebookTool = {
|
|
12154
|
+
name: "generate_jupyter_notebook",
|
|
12155
|
+
implementation: (context) => ({
|
|
12156
|
+
toolFn: async (value) => {
|
|
12157
|
+
const params = value;
|
|
12158
|
+
const { analysisDescription, dataSource, outputFormat, kernelName, title } = params;
|
|
12159
|
+
if (!analysisDescription) {
|
|
12160
|
+
throw new Error("analysisDescription is required");
|
|
12161
|
+
}
|
|
12162
|
+
const userPrompt = `Generate a Jupyter notebook for the following analysis:
|
|
12163
|
+
|
|
12164
|
+
**Analysis Description:** ${analysisDescription}
|
|
12165
|
+
${dataSource ? `**Data Source:** ${dataSource}` : ""}
|
|
12166
|
+
${outputFormat ? `**Output Format:** ${outputFormat}` : ""}
|
|
12167
|
+
${title ? `**Notebook Title:** ${title}` : ""}
|
|
12168
|
+
|
|
12169
|
+
Please generate a complete, well-structured notebook that performs this analysis.`;
|
|
12170
|
+
context.logger.info("[JupyterNotebook] Generating notebook structure via LLM...");
|
|
12171
|
+
let responseText = "";
|
|
12172
|
+
await context.llm.complete(context.model ?? "gpt-4", [
|
|
12173
|
+
{ role: "system", content: NOTEBOOK_GENERATION_PROMPT },
|
|
12174
|
+
{ role: "user", content: userPrompt }
|
|
12175
|
+
], { maxTokens: 4e3, temperature: 0.7 }, async (texts) => {
|
|
12176
|
+
responseText = texts.filter((t) => t !== null && t !== void 0).join("");
|
|
12177
|
+
});
|
|
12178
|
+
if (!responseText) {
|
|
12179
|
+
throw new Error("LLM returned empty response");
|
|
12180
|
+
}
|
|
12181
|
+
const parsedResponse = parseNotebookResponse(responseText);
|
|
12182
|
+
const notebook = buildNotebook(parsedResponse, kernelName || "python3", {
|
|
12183
|
+
analysisDescription
|
|
12184
|
+
});
|
|
12185
|
+
context.logger.info(`[JupyterNotebook] Generated notebook with ${notebook.cells.length} cells`);
|
|
12186
|
+
return serializeNotebook(notebook);
|
|
12187
|
+
},
|
|
12188
|
+
toolSchema: {
|
|
12189
|
+
name: "generate_jupyter_notebook",
|
|
12190
|
+
description: `Generate a Jupyter notebook for data analysis. The notebook will be created with Python code cells that can be executed locally via the Keep command system. Use this tool when the user wants to perform data analysis, create visualizations, or work with datasets.`,
|
|
12191
|
+
parameters: {
|
|
12192
|
+
type: "object",
|
|
12193
|
+
properties: {
|
|
12194
|
+
analysisDescription: {
|
|
12195
|
+
type: "string",
|
|
12196
|
+
description: "Detailed description of the analysis to perform. Be specific about what calculations, visualizations, or insights are needed."
|
|
12197
|
+
},
|
|
12198
|
+
dataSource: {
|
|
12199
|
+
type: "string",
|
|
12200
|
+
description: 'Description of the data source. Can be a file path (e.g., "~/data/sales.csv"), URL, or description of inline data.'
|
|
12201
|
+
},
|
|
12202
|
+
outputFormat: {
|
|
12203
|
+
type: "string",
|
|
12204
|
+
enum: ["table", "chart", "both"],
|
|
12205
|
+
description: 'Preferred output format for results. "table" for tabular data, "chart" for visualizations, "both" for both.'
|
|
12206
|
+
},
|
|
12207
|
+
kernelName: {
|
|
12208
|
+
type: "string",
|
|
12209
|
+
description: 'Jupyter kernel to use. Defaults to "python3". Other options depend on what kernels are installed locally.'
|
|
12210
|
+
},
|
|
12211
|
+
title: {
|
|
12212
|
+
type: "string",
|
|
12213
|
+
description: "Optional title for the notebook."
|
|
12214
|
+
}
|
|
12215
|
+
},
|
|
12216
|
+
required: ["analysisDescription"]
|
|
12217
|
+
}
|
|
12218
|
+
}
|
|
12219
|
+
})
|
|
12220
|
+
};
|
|
12221
|
+
|
|
11984
12222
|
// ../../b4m-core/packages/services/dist/src/llm/tools/implementation/excelGeneration/index.js
|
|
11985
12223
|
import ExcelJS from "exceljs";
|
|
11986
12224
|
import { v4 as uuidv47 } from "uuid";
|
|
@@ -13841,6 +14079,8 @@ var b4mTools = {
|
|
|
13841
14079
|
quantum_formulate: quantumFormulateTool,
|
|
13842
14080
|
// Navigation tool
|
|
13843
14081
|
navigate_view: navigateViewTool,
|
|
14082
|
+
// Jupyter notebook generation
|
|
14083
|
+
generate_jupyter_notebook: jupyterNotebookTool,
|
|
13844
14084
|
// Excel generation
|
|
13845
14085
|
excel_generation: excelGenerationTool
|
|
13846
14086
|
};
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import {
|
|
3
3
|
BadRequestError,
|
|
4
4
|
secureParameters
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-AWG7GGY5.js";
|
|
6
6
|
import {
|
|
7
7
|
CompletionApiUsageTransaction,
|
|
8
8
|
GenericCreditDeductTransaction,
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
ToolUsageTransaction,
|
|
14
14
|
TransferCreditTransaction,
|
|
15
15
|
VideoGenerationUsageTransaction
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-VWH4PFPB.js";
|
|
17
17
|
|
|
18
18
|
// ../../b4m-core/packages/services/dist/src/creditService/subtractCredits.js
|
|
19
19
|
import { z } from "zod";
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// package.json
|
|
4
4
|
var package_default = {
|
|
5
5
|
name: "@bike4mind/cli",
|
|
6
|
-
version: "0.2.
|
|
6
|
+
version: "0.2.57-feat-jupyter-interoperability-roadmap.21458+b5aabe927",
|
|
7
7
|
type: "module",
|
|
8
8
|
description: "Interactive CLI tool for Bike4Mind with ReAct agents",
|
|
9
9
|
license: "UNLICENSED",
|
|
@@ -118,11 +118,11 @@ var package_default = {
|
|
|
118
118
|
zustand: "^4.5.4"
|
|
119
119
|
},
|
|
120
120
|
devDependencies: {
|
|
121
|
-
"@bike4mind/agents": "0.2.
|
|
122
|
-
"@bike4mind/common": "2.70.
|
|
123
|
-
"@bike4mind/mcp": "1.33.
|
|
124
|
-
"@bike4mind/services": "2.64.
|
|
125
|
-
"@bike4mind/utils": "2.15.
|
|
121
|
+
"@bike4mind/agents": "0.2.2-feat-jupyter-interoperability-roadmap.21458+b5aabe927",
|
|
122
|
+
"@bike4mind/common": "2.70.2-feat-jupyter-interoperability-roadmap.21458+b5aabe927",
|
|
123
|
+
"@bike4mind/mcp": "1.33.16-feat-jupyter-interoperability-roadmap.21458+b5aabe927",
|
|
124
|
+
"@bike4mind/services": "2.64.4-feat-jupyter-interoperability-roadmap.21458+b5aabe927",
|
|
125
|
+
"@bike4mind/utils": "2.15.10-feat-jupyter-interoperability-roadmap.21458+b5aabe927",
|
|
126
126
|
"@types/better-sqlite3": "^7.6.13",
|
|
127
127
|
"@types/jsonwebtoken": "^9.0.4",
|
|
128
128
|
"@types/node": "^22.9.0",
|
|
@@ -139,7 +139,7 @@ var package_default = {
|
|
|
139
139
|
optionalDependencies: {
|
|
140
140
|
"@vscode/ripgrep": "^1.17.1"
|
|
141
141
|
},
|
|
142
|
-
gitHead: "
|
|
142
|
+
gitHead: "b5aabe927ab8e991be795c9a1e998f921eaf3452"
|
|
143
143
|
};
|
|
144
144
|
|
|
145
145
|
// src/utils/updateChecker.ts
|
|
@@ -338,6 +338,8 @@ var b4mLLMTools = z5.enum([
|
|
|
338
338
|
"quantum_formulate",
|
|
339
339
|
// Navigation tool
|
|
340
340
|
"navigate_view",
|
|
341
|
+
// Jupyter notebook generation
|
|
342
|
+
"generate_jupyter_notebook",
|
|
341
343
|
// Excel generation
|
|
342
344
|
"excel_generation"
|
|
343
345
|
]);
|
|
@@ -1820,16 +1822,26 @@ var CliToolResponseAction = z11.object({
|
|
|
1820
1822
|
content: z11.unknown().optional(),
|
|
1821
1823
|
error: z11.string().optional()
|
|
1822
1824
|
});
|
|
1825
|
+
var KeepCommandType = z11.enum([
|
|
1826
|
+
"read_file",
|
|
1827
|
+
"list_directory",
|
|
1828
|
+
"run_tool",
|
|
1829
|
+
// Jupyter kernel commands
|
|
1830
|
+
"jupyter_start_kernel",
|
|
1831
|
+
"jupyter_execute_cell",
|
|
1832
|
+
"jupyter_stop_kernel",
|
|
1833
|
+
"jupyter_get_kernelspecs"
|
|
1834
|
+
]);
|
|
1823
1835
|
var KeepCommandRequestAction = z11.object({
|
|
1824
1836
|
action: z11.literal("keep_command_request"),
|
|
1825
1837
|
accessToken: z11.string().optional(),
|
|
1826
|
-
commandType:
|
|
1838
|
+
commandType: KeepCommandType,
|
|
1827
1839
|
params: z11.record(z11.string(), z11.unknown()),
|
|
1828
1840
|
requestId: z11.string()
|
|
1829
1841
|
});
|
|
1830
1842
|
var KeepCommandAction = z11.object({
|
|
1831
1843
|
action: z11.literal("keep_command"),
|
|
1832
|
-
commandType:
|
|
1844
|
+
commandType: KeepCommandType,
|
|
1833
1845
|
params: z11.record(z11.string(), z11.unknown()),
|
|
1834
1846
|
requestId: z11.string(),
|
|
1835
1847
|
originConnectionId: z11.string()
|
|
@@ -1849,6 +1861,59 @@ var KeepCommandResultAction = z11.object({
|
|
|
1849
1861
|
result: z11.unknown().optional(),
|
|
1850
1862
|
error: z11.string().optional()
|
|
1851
1863
|
});
|
|
1864
|
+
var JupyterCellOutputAction = z11.object({
|
|
1865
|
+
action: z11.literal("jupyter_cell_output"),
|
|
1866
|
+
requestId: z11.string(),
|
|
1867
|
+
sessionId: z11.string(),
|
|
1868
|
+
jupyterSessionId: z11.string(),
|
|
1869
|
+
cellIndex: z11.number(),
|
|
1870
|
+
outputType: z11.enum(["stream", "execute_result", "display_data", "error"]),
|
|
1871
|
+
content: z11.object({
|
|
1872
|
+
text: z11.string().optional(),
|
|
1873
|
+
name: z11.string().optional(),
|
|
1874
|
+
// stdout, stderr for stream outputs
|
|
1875
|
+
data: z11.record(z11.string(), z11.unknown()).optional(),
|
|
1876
|
+
// MIME type → data for rich outputs
|
|
1877
|
+
ename: z11.string().optional(),
|
|
1878
|
+
// Error name
|
|
1879
|
+
evalue: z11.string().optional(),
|
|
1880
|
+
// Error value
|
|
1881
|
+
traceback: z11.array(z11.string()).optional()
|
|
1882
|
+
}),
|
|
1883
|
+
executionCount: z11.number().nullable().optional(),
|
|
1884
|
+
isComplete: z11.boolean()
|
|
1885
|
+
});
|
|
1886
|
+
var JupyterNotebookProgressAction = z11.object({
|
|
1887
|
+
action: z11.literal("jupyter_notebook_progress"),
|
|
1888
|
+
questId: z11.string(),
|
|
1889
|
+
sessionId: z11.string(),
|
|
1890
|
+
status: z11.enum([
|
|
1891
|
+
"generating",
|
|
1892
|
+
// LLM generating notebook
|
|
1893
|
+
"kernel_starting",
|
|
1894
|
+
// Starting Jupyter kernel
|
|
1895
|
+
"executing",
|
|
1896
|
+
// Executing cells
|
|
1897
|
+
"cell_complete",
|
|
1898
|
+
// A cell finished executing
|
|
1899
|
+
"error",
|
|
1900
|
+
// Cell execution error
|
|
1901
|
+
"retrying",
|
|
1902
|
+
// Retrying failed cell with LLM fix
|
|
1903
|
+
"completed",
|
|
1904
|
+
// All cells executed successfully
|
|
1905
|
+
"failed"
|
|
1906
|
+
// Notebook execution failed after retries
|
|
1907
|
+
]),
|
|
1908
|
+
cellIndex: z11.number().optional(),
|
|
1909
|
+
totalCells: z11.number().optional(),
|
|
1910
|
+
currentCellCode: z11.string().optional(),
|
|
1911
|
+
output: z11.unknown().optional(),
|
|
1912
|
+
error: z11.string().optional(),
|
|
1913
|
+
notebookPath: z11.string().optional(),
|
|
1914
|
+
fabFileId: z11.string().optional()
|
|
1915
|
+
// Set when notebook is saved
|
|
1916
|
+
});
|
|
1852
1917
|
var TilePositionSchema = z11.object({ x: z11.number(), y: z11.number() });
|
|
1853
1918
|
var SceneCommandSchema = z11.discriminatedUnion("type", [
|
|
1854
1919
|
z11.object({
|
|
@@ -1985,7 +2050,8 @@ var MessageDataToServer = z11.discriminatedUnion("action", [
|
|
|
1985
2050
|
CliToolRequestAction,
|
|
1986
2051
|
KeepCommandRequestAction,
|
|
1987
2052
|
KeepCommandResponseAction,
|
|
1988
|
-
TavernSceneCommandRequestAction
|
|
2053
|
+
TavernSceneCommandRequestAction,
|
|
2054
|
+
JupyterCellOutputAction
|
|
1989
2055
|
]);
|
|
1990
2056
|
var MessageDataToClient = z11.discriminatedUnion("action", [
|
|
1991
2057
|
DataSubscriptionUpdateAction,
|
|
@@ -2020,6 +2086,7 @@ var MessageDataToClient = z11.discriminatedUnion("action", [
|
|
|
2020
2086
|
KeepCommandResultAction,
|
|
2021
2087
|
TavernSceneBroadcastAction,
|
|
2022
2088
|
TavernHeartbeatLogAction,
|
|
2089
|
+
JupyterNotebookProgressAction,
|
|
2023
2090
|
DataLakeBatchProgressAction
|
|
2024
2091
|
]);
|
|
2025
2092
|
|
|
@@ -6262,6 +6329,52 @@ function getDataLakeTags(userTags, dynamicDataLakes) {
|
|
|
6262
6329
|
return getAccessibleDataLakes(userTags, dynamicDataLakes).map((dl) => dl.datalakeTag);
|
|
6263
6330
|
}
|
|
6264
6331
|
|
|
6332
|
+
// ../../b4m-core/packages/common/dist/src/constants/jupyter.js
|
|
6333
|
+
var ALLOWED_JUPYTER_KERNELS = [
|
|
6334
|
+
"python3",
|
|
6335
|
+
"python",
|
|
6336
|
+
"python2",
|
|
6337
|
+
"ir",
|
|
6338
|
+
// R kernel
|
|
6339
|
+
"julia-1.9",
|
|
6340
|
+
"julia-1.10",
|
|
6341
|
+
"julia"
|
|
6342
|
+
];
|
|
6343
|
+
var ALLOWED_KERNELS_SET = new Set(ALLOWED_JUPYTER_KERNELS);
|
|
6344
|
+
function isAllowedJupyterKernel(kernelName) {
|
|
6345
|
+
return ALLOWED_KERNELS_SET.has(kernelName);
|
|
6346
|
+
}
|
|
6347
|
+
function getAllowedKernelsList() {
|
|
6348
|
+
return ALLOWED_JUPYTER_KERNELS.join(", ");
|
|
6349
|
+
}
|
|
6350
|
+
function validateJupyterKernelName(kernelName) {
|
|
6351
|
+
if (!kernelName || typeof kernelName !== "string") {
|
|
6352
|
+
return { valid: false, error: "Kernel name is required" };
|
|
6353
|
+
}
|
|
6354
|
+
if (!isAllowedJupyterKernel(kernelName)) {
|
|
6355
|
+
return {
|
|
6356
|
+
valid: false,
|
|
6357
|
+
error: `Invalid kernel: '${kernelName}'. Allowed kernels: ${getAllowedKernelsList()}`
|
|
6358
|
+
};
|
|
6359
|
+
}
|
|
6360
|
+
return { valid: true };
|
|
6361
|
+
}
|
|
6362
|
+
function validateNotebookPath(path, requireIpynbExtension = false) {
|
|
6363
|
+
if (!path || typeof path !== "string") {
|
|
6364
|
+
return { valid: false, error: "Notebook path is required" };
|
|
6365
|
+
}
|
|
6366
|
+
if (path.includes("..") || path.includes("//")) {
|
|
6367
|
+
return { valid: false, error: "Invalid notebook path: path traversal not allowed" };
|
|
6368
|
+
}
|
|
6369
|
+
if (/[\x00-\x1f]/.test(path)) {
|
|
6370
|
+
return { valid: false, error: "Invalid notebook path: contains control characters" };
|
|
6371
|
+
}
|
|
6372
|
+
if (requireIpynbExtension && !path.endsWith(".ipynb")) {
|
|
6373
|
+
return { valid: false, error: "Invalid notebook path: must end with .ipynb" };
|
|
6374
|
+
}
|
|
6375
|
+
return { valid: true };
|
|
6376
|
+
}
|
|
6377
|
+
|
|
6265
6378
|
// ../../b4m-core/packages/common/dist/src/llm.js
|
|
6266
6379
|
import { z as z29 } from "zod";
|
|
6267
6380
|
var DashboardParamsSchema = z29.object({
|
|
@@ -11892,10 +12005,13 @@ export {
|
|
|
11892
12005
|
CliCompletionDoneAction,
|
|
11893
12006
|
CliCompletionErrorAction,
|
|
11894
12007
|
CliToolResponseAction,
|
|
12008
|
+
KeepCommandType,
|
|
11895
12009
|
KeepCommandRequestAction,
|
|
11896
12010
|
KeepCommandAction,
|
|
11897
12011
|
KeepCommandResponseAction,
|
|
11898
12012
|
KeepCommandResultAction,
|
|
12013
|
+
JupyterCellOutputAction,
|
|
12014
|
+
JupyterNotebookProgressAction,
|
|
11899
12015
|
TavernSceneCommandRequestAction,
|
|
11900
12016
|
TavernSceneBroadcastAction,
|
|
11901
12017
|
TavernHeartbeatLogAction,
|
|
@@ -12101,6 +12217,11 @@ export {
|
|
|
12101
12217
|
DATA_LAKES,
|
|
12102
12218
|
getAccessibleDataLakes,
|
|
12103
12219
|
getDataLakeTags,
|
|
12220
|
+
ALLOWED_JUPYTER_KERNELS,
|
|
12221
|
+
isAllowedJupyterKernel,
|
|
12222
|
+
getAllowedKernelsList,
|
|
12223
|
+
validateJupyterKernelName,
|
|
12224
|
+
validateNotebookPath,
|
|
12104
12225
|
DashboardParamsSchema,
|
|
12105
12226
|
QuestMasterParamsSchema,
|
|
12106
12227
|
ResearchModeConfigurationSchema,
|
|
@@ -6,12 +6,12 @@ import {
|
|
|
6
6
|
getSettingsByNames,
|
|
7
7
|
obfuscateApiKey,
|
|
8
8
|
secureParameters
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-AWG7GGY5.js";
|
|
10
10
|
import {
|
|
11
11
|
ApiKeyType,
|
|
12
12
|
MementoTier,
|
|
13
13
|
isSupportedEmbeddingModel
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-VWH4PFPB.js";
|
|
15
15
|
|
|
16
16
|
// ../../b4m-core/packages/services/dist/src/apiKeyService/get.js
|
|
17
17
|
import { z } from "zod";
|
|
@@ -36,20 +36,20 @@ import {
|
|
|
36
36
|
isReadOnlyTool,
|
|
37
37
|
loadContextFiles,
|
|
38
38
|
setWebSocketToolExecutor
|
|
39
|
-
} from "../chunk-
|
|
39
|
+
} from "../chunk-O55VX62E.js";
|
|
40
40
|
import "../chunk-BDQBOLYG.js";
|
|
41
|
-
import "../chunk-
|
|
41
|
+
import "../chunk-YKQNMQX5.js";
|
|
42
42
|
import "../chunk-GQGOWACU.js";
|
|
43
|
-
import "../chunk-
|
|
44
|
-
import "../chunk-
|
|
45
|
-
import "../chunk-
|
|
43
|
+
import "../chunk-RIFFSKKB.js";
|
|
44
|
+
import "../chunk-67YAACDQ.js";
|
|
45
|
+
import "../chunk-AWG7GGY5.js";
|
|
46
46
|
import "../chunk-PFBYGCOW.js";
|
|
47
47
|
import "../chunk-BPFEGDC7.js";
|
|
48
48
|
import {
|
|
49
49
|
ConfigStore,
|
|
50
50
|
logger
|
|
51
|
-
} from "../chunk-
|
|
52
|
-
import "../chunk-
|
|
51
|
+
} from "../chunk-3JJYLK4C.js";
|
|
52
|
+
import "../chunk-VWH4PFPB.js";
|
|
53
53
|
import {
|
|
54
54
|
DEFAULT_SANDBOX_CONFIG
|
|
55
55
|
} from "../chunk-4BIBE3J7.js";
|
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
import {
|
|
3
3
|
createFabFile,
|
|
4
4
|
createFabFileSchema
|
|
5
|
-
} from "./chunk-
|
|
6
|
-
import "./chunk-
|
|
5
|
+
} from "./chunk-67YAACDQ.js";
|
|
6
|
+
import "./chunk-AWG7GGY5.js";
|
|
7
7
|
import "./chunk-PFBYGCOW.js";
|
|
8
|
-
import "./chunk-
|
|
8
|
+
import "./chunk-VWH4PFPB.js";
|
|
9
9
|
export {
|
|
10
10
|
createFabFile,
|
|
11
11
|
createFabFileSchema
|
package/dist/index.js
CHANGED
|
@@ -46,33 +46,35 @@ import {
|
|
|
46
46
|
setWebSocketToolExecutor,
|
|
47
47
|
substituteArguments,
|
|
48
48
|
warmFileCache
|
|
49
|
-
} from "./chunk-
|
|
49
|
+
} from "./chunk-O55VX62E.js";
|
|
50
50
|
import "./chunk-BDQBOLYG.js";
|
|
51
|
-
import "./chunk-
|
|
51
|
+
import "./chunk-YKQNMQX5.js";
|
|
52
52
|
import "./chunk-GQGOWACU.js";
|
|
53
|
-
import "./chunk-
|
|
54
|
-
import "./chunk-
|
|
53
|
+
import "./chunk-RIFFSKKB.js";
|
|
54
|
+
import "./chunk-67YAACDQ.js";
|
|
55
55
|
import {
|
|
56
56
|
OllamaBackend
|
|
57
|
-
} from "./chunk-
|
|
57
|
+
} from "./chunk-AWG7GGY5.js";
|
|
58
58
|
import "./chunk-PFBYGCOW.js";
|
|
59
59
|
import "./chunk-BPFEGDC7.js";
|
|
60
60
|
import {
|
|
61
61
|
ConfigStore,
|
|
62
62
|
logger
|
|
63
|
-
} from "./chunk-
|
|
63
|
+
} from "./chunk-3JJYLK4C.js";
|
|
64
64
|
import {
|
|
65
65
|
checkForUpdate,
|
|
66
66
|
package_default
|
|
67
|
-
} from "./chunk-
|
|
67
|
+
} from "./chunk-TYXGSRCJ.js";
|
|
68
68
|
import {
|
|
69
69
|
selectActiveBackgroundAgents,
|
|
70
70
|
useCliStore
|
|
71
71
|
} from "./chunk-G2LYCVZJ.js";
|
|
72
72
|
import {
|
|
73
73
|
CREDIT_DEDUCT_TRANSACTION_TYPES,
|
|
74
|
-
ChatModels
|
|
75
|
-
|
|
74
|
+
ChatModels,
|
|
75
|
+
validateJupyterKernelName,
|
|
76
|
+
validateNotebookPath
|
|
77
|
+
} from "./chunk-VWH4PFPB.js";
|
|
76
78
|
import "./chunk-4BIBE3J7.js";
|
|
77
79
|
|
|
78
80
|
// src/index.tsx
|
|
@@ -2484,6 +2486,305 @@ var MessageBuilder = class {
|
|
|
2484
2486
|
}
|
|
2485
2487
|
};
|
|
2486
2488
|
|
|
2489
|
+
// src/utils/jupyterClient.ts
|
|
2490
|
+
import WebSocket from "ws";
|
|
2491
|
+
var JupyterClientError = class extends Error {
|
|
2492
|
+
constructor(message, statusCode, response) {
|
|
2493
|
+
super(message);
|
|
2494
|
+
this.statusCode = statusCode;
|
|
2495
|
+
this.response = response;
|
|
2496
|
+
this.name = "JupyterClientError";
|
|
2497
|
+
}
|
|
2498
|
+
};
|
|
2499
|
+
function validateServerUrl(url) {
|
|
2500
|
+
if (!url || typeof url !== "string") {
|
|
2501
|
+
throw new JupyterClientError("Server URL is required");
|
|
2502
|
+
}
|
|
2503
|
+
let parsed;
|
|
2504
|
+
try {
|
|
2505
|
+
parsed = new URL(url);
|
|
2506
|
+
} catch {
|
|
2507
|
+
throw new JupyterClientError(`Invalid server URL: ${url}`);
|
|
2508
|
+
}
|
|
2509
|
+
if (!["http:", "https:"].includes(parsed.protocol)) {
|
|
2510
|
+
throw new JupyterClientError(`Invalid protocol: ${parsed.protocol}. Only http and https are allowed`);
|
|
2511
|
+
}
|
|
2512
|
+
}
|
|
2513
|
+
function validateNotebookPath2(path3) {
|
|
2514
|
+
const result = validateNotebookPath(path3);
|
|
2515
|
+
if (!result.valid) {
|
|
2516
|
+
throw new JupyterClientError(result.error || "Invalid notebook path");
|
|
2517
|
+
}
|
|
2518
|
+
}
|
|
2519
|
+
function validateKernelName(name) {
|
|
2520
|
+
const result = validateJupyterKernelName(name);
|
|
2521
|
+
if (!result.valid) {
|
|
2522
|
+
throw new JupyterClientError(result.error || "Invalid kernel name");
|
|
2523
|
+
}
|
|
2524
|
+
}
|
|
2525
|
+
var JupyterClient = class {
|
|
2526
|
+
constructor(config) {
|
|
2527
|
+
validateServerUrl(config.serverUrl);
|
|
2528
|
+
this.serverUrl = config.serverUrl.replace(/\/$/, "");
|
|
2529
|
+
this.token = config.token;
|
|
2530
|
+
}
|
|
2531
|
+
getHeaders() {
|
|
2532
|
+
const headers = {
|
|
2533
|
+
"Content-Type": "application/json"
|
|
2534
|
+
};
|
|
2535
|
+
if (this.token) {
|
|
2536
|
+
headers["Authorization"] = `token ${this.token}`;
|
|
2537
|
+
}
|
|
2538
|
+
return headers;
|
|
2539
|
+
}
|
|
2540
|
+
async request(method, path3, body) {
|
|
2541
|
+
const url = `${this.serverUrl}${path3}`;
|
|
2542
|
+
const options = {
|
|
2543
|
+
method,
|
|
2544
|
+
headers: this.getHeaders()
|
|
2545
|
+
};
|
|
2546
|
+
if (body) {
|
|
2547
|
+
options.body = JSON.stringify(body);
|
|
2548
|
+
}
|
|
2549
|
+
const response = await fetch(url, options);
|
|
2550
|
+
if (!response.ok) {
|
|
2551
|
+
let errorBody;
|
|
2552
|
+
try {
|
|
2553
|
+
errorBody = await response.json();
|
|
2554
|
+
} catch {
|
|
2555
|
+
errorBody = await response.text();
|
|
2556
|
+
}
|
|
2557
|
+
throw new JupyterClientError(
|
|
2558
|
+
`Jupyter API error: ${response.status} ${response.statusText}`,
|
|
2559
|
+
response.status,
|
|
2560
|
+
errorBody
|
|
2561
|
+
);
|
|
2562
|
+
}
|
|
2563
|
+
if (response.status === 204) {
|
|
2564
|
+
return {};
|
|
2565
|
+
}
|
|
2566
|
+
return response.json();
|
|
2567
|
+
}
|
|
2568
|
+
/**
|
|
2569
|
+
* Check if the Jupyter server is running and accessible
|
|
2570
|
+
*/
|
|
2571
|
+
async checkStatus() {
|
|
2572
|
+
return this.request("GET", "/api/status");
|
|
2573
|
+
}
|
|
2574
|
+
/**
|
|
2575
|
+
* Get available kernel specifications
|
|
2576
|
+
*/
|
|
2577
|
+
async getKernelSpecs() {
|
|
2578
|
+
return this.request("GET", "/api/kernelspecs");
|
|
2579
|
+
}
|
|
2580
|
+
/**
|
|
2581
|
+
* List all active sessions
|
|
2582
|
+
*/
|
|
2583
|
+
async listSessions() {
|
|
2584
|
+
return this.request("GET", "/api/sessions");
|
|
2585
|
+
}
|
|
2586
|
+
/**
|
|
2587
|
+
* Start a new kernel session for a notebook
|
|
2588
|
+
*/
|
|
2589
|
+
async startSession(notebookPath, kernelName) {
|
|
2590
|
+
validateNotebookPath2(notebookPath);
|
|
2591
|
+
const kernel = kernelName || "python3";
|
|
2592
|
+
validateKernelName(kernel);
|
|
2593
|
+
return this.request("POST", "/api/sessions", {
|
|
2594
|
+
path: notebookPath,
|
|
2595
|
+
type: "notebook",
|
|
2596
|
+
name: notebookPath.split("/").pop() || "Untitled",
|
|
2597
|
+
kernel: {
|
|
2598
|
+
name: kernel
|
|
2599
|
+
}
|
|
2600
|
+
});
|
|
2601
|
+
}
|
|
2602
|
+
/**
|
|
2603
|
+
* Get a session by ID
|
|
2604
|
+
*/
|
|
2605
|
+
async getSession(sessionId) {
|
|
2606
|
+
return this.request("GET", `/api/sessions/${sessionId}`);
|
|
2607
|
+
}
|
|
2608
|
+
/**
|
|
2609
|
+
* Stop a kernel session
|
|
2610
|
+
*/
|
|
2611
|
+
async stopSession(sessionId) {
|
|
2612
|
+
await this.request("DELETE", `/api/sessions/${sessionId}`);
|
|
2613
|
+
}
|
|
2614
|
+
/**
|
|
2615
|
+
* Get WebSocket URL for kernel channels
|
|
2616
|
+
*/
|
|
2617
|
+
getKernelWebSocketUrl(kernelId) {
|
|
2618
|
+
const httpUrl = new URL(this.serverUrl);
|
|
2619
|
+
const wsProtocol = httpUrl.protocol === "https:" ? "wss:" : "ws:";
|
|
2620
|
+
const wsUrl = `${wsProtocol}//${httpUrl.host}/api/kernels/${kernelId}/channels`;
|
|
2621
|
+
if (this.token) {
|
|
2622
|
+
return `${wsUrl}?token=${this.token}`;
|
|
2623
|
+
}
|
|
2624
|
+
return wsUrl;
|
|
2625
|
+
}
|
|
2626
|
+
/**
|
|
2627
|
+
* Generate a unique message ID for Jupyter protocol
|
|
2628
|
+
*/
|
|
2629
|
+
generateMsgId() {
|
|
2630
|
+
return `${Date.now()}-${Math.random().toString(36).substring(2, 11)}`;
|
|
2631
|
+
}
|
|
2632
|
+
/**
|
|
2633
|
+
* Execute code in a kernel using the Jupyter WebSocket protocol.
|
|
2634
|
+
*
|
|
2635
|
+
* Connects to the kernel's channels WebSocket, sends an execute_request,
|
|
2636
|
+
* and collects outputs until the kernel returns to idle state.
|
|
2637
|
+
*
|
|
2638
|
+
* @param kernelId - The kernel ID to execute code in
|
|
2639
|
+
* @param code - The code to execute
|
|
2640
|
+
* @param timeoutMs - Execution timeout in milliseconds (default: 30000)
|
|
2641
|
+
*/
|
|
2642
|
+
async executeCell(kernelId, code, timeoutMs = 3e4) {
|
|
2643
|
+
const wsUrl = this.getKernelWebSocketUrl(kernelId);
|
|
2644
|
+
const msgId = this.generateMsgId();
|
|
2645
|
+
return new Promise((resolve, reject) => {
|
|
2646
|
+
const outputs = [];
|
|
2647
|
+
let executionCount = null;
|
|
2648
|
+
let hasError = false;
|
|
2649
|
+
let errorInfo;
|
|
2650
|
+
const ws = new WebSocket(wsUrl);
|
|
2651
|
+
const timeoutHandle = setTimeout(() => {
|
|
2652
|
+
cleanup();
|
|
2653
|
+
reject(new JupyterClientError(`Cell execution timed out after ${timeoutMs}ms`));
|
|
2654
|
+
}, timeoutMs);
|
|
2655
|
+
const cleanup = () => {
|
|
2656
|
+
clearTimeout(timeoutHandle);
|
|
2657
|
+
if (ws.readyState === WebSocket.OPEN || ws.readyState === WebSocket.CONNECTING) {
|
|
2658
|
+
ws.close();
|
|
2659
|
+
}
|
|
2660
|
+
};
|
|
2661
|
+
ws.on("error", (err) => {
|
|
2662
|
+
cleanup();
|
|
2663
|
+
reject(new JupyterClientError(`WebSocket error: ${err.message}`));
|
|
2664
|
+
});
|
|
2665
|
+
ws.on("open", () => {
|
|
2666
|
+
const executeRequest = {
|
|
2667
|
+
header: {
|
|
2668
|
+
msg_id: msgId,
|
|
2669
|
+
msg_type: "execute_request",
|
|
2670
|
+
username: "b4m-cli",
|
|
2671
|
+
session: this.generateMsgId(),
|
|
2672
|
+
date: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2673
|
+
version: "5.3"
|
|
2674
|
+
},
|
|
2675
|
+
parent_header: {},
|
|
2676
|
+
metadata: {},
|
|
2677
|
+
content: {
|
|
2678
|
+
code,
|
|
2679
|
+
silent: false,
|
|
2680
|
+
store_history: true,
|
|
2681
|
+
user_expressions: {},
|
|
2682
|
+
allow_stdin: false,
|
|
2683
|
+
stop_on_error: true
|
|
2684
|
+
},
|
|
2685
|
+
buffers: [],
|
|
2686
|
+
channel: "shell"
|
|
2687
|
+
};
|
|
2688
|
+
ws.send(JSON.stringify(executeRequest));
|
|
2689
|
+
});
|
|
2690
|
+
ws.on("message", (data) => {
|
|
2691
|
+
try {
|
|
2692
|
+
const msg = JSON.parse(data.toString());
|
|
2693
|
+
if (msg.parent_header?.msg_id !== msgId) {
|
|
2694
|
+
return;
|
|
2695
|
+
}
|
|
2696
|
+
const msgType = msg.header?.msg_type || msg.msg_type;
|
|
2697
|
+
switch (msgType) {
|
|
2698
|
+
case "stream":
|
|
2699
|
+
outputs.push({
|
|
2700
|
+
output_type: "stream",
|
|
2701
|
+
name: msg.content.name,
|
|
2702
|
+
text: msg.content.text
|
|
2703
|
+
});
|
|
2704
|
+
break;
|
|
2705
|
+
case "execute_result":
|
|
2706
|
+
executionCount = msg.content.execution_count;
|
|
2707
|
+
outputs.push({
|
|
2708
|
+
output_type: "execute_result",
|
|
2709
|
+
data: msg.content.data,
|
|
2710
|
+
execution_count: msg.content.execution_count,
|
|
2711
|
+
metadata: msg.content.metadata
|
|
2712
|
+
});
|
|
2713
|
+
break;
|
|
2714
|
+
case "display_data":
|
|
2715
|
+
outputs.push({
|
|
2716
|
+
output_type: "display_data",
|
|
2717
|
+
data: msg.content.data,
|
|
2718
|
+
metadata: msg.content.metadata
|
|
2719
|
+
});
|
|
2720
|
+
break;
|
|
2721
|
+
case "error":
|
|
2722
|
+
hasError = true;
|
|
2723
|
+
errorInfo = {
|
|
2724
|
+
ename: msg.content.ename,
|
|
2725
|
+
evalue: msg.content.evalue,
|
|
2726
|
+
traceback: msg.content.traceback
|
|
2727
|
+
};
|
|
2728
|
+
outputs.push({
|
|
2729
|
+
output_type: "error",
|
|
2730
|
+
ename: msg.content.ename,
|
|
2731
|
+
evalue: msg.content.evalue,
|
|
2732
|
+
traceback: msg.content.traceback
|
|
2733
|
+
});
|
|
2734
|
+
break;
|
|
2735
|
+
case "execute_reply":
|
|
2736
|
+
if (msg.content.status === "ok" || msg.content.status === "error") {
|
|
2737
|
+
if (msg.content.execution_count !== void 0) {
|
|
2738
|
+
executionCount = msg.content.execution_count;
|
|
2739
|
+
}
|
|
2740
|
+
cleanup();
|
|
2741
|
+
resolve({
|
|
2742
|
+
success: !hasError,
|
|
2743
|
+
outputs,
|
|
2744
|
+
executionCount,
|
|
2745
|
+
error: errorInfo
|
|
2746
|
+
});
|
|
2747
|
+
}
|
|
2748
|
+
break;
|
|
2749
|
+
case "status":
|
|
2750
|
+
break;
|
|
2751
|
+
}
|
|
2752
|
+
} catch {
|
|
2753
|
+
}
|
|
2754
|
+
});
|
|
2755
|
+
ws.on("close", () => {
|
|
2756
|
+
clearTimeout(timeoutHandle);
|
|
2757
|
+
});
|
|
2758
|
+
});
|
|
2759
|
+
}
|
|
2760
|
+
/**
|
|
2761
|
+
* @deprecated Use executeCell instead. This method exists for backwards compatibility.
|
|
2762
|
+
*/
|
|
2763
|
+
async executeCode(kernelId, code) {
|
|
2764
|
+
return this.executeCell(kernelId, code);
|
|
2765
|
+
}
|
|
2766
|
+
/**
|
|
2767
|
+
* Interrupt a running kernel
|
|
2768
|
+
*/
|
|
2769
|
+
async interruptKernel(kernelId) {
|
|
2770
|
+
await this.request("POST", `/api/kernels/${kernelId}/interrupt`);
|
|
2771
|
+
}
|
|
2772
|
+
/**
|
|
2773
|
+
* Restart a kernel
|
|
2774
|
+
*/
|
|
2775
|
+
async restartKernel(kernelId) {
|
|
2776
|
+
return this.request("POST", `/api/kernels/${kernelId}/restart`);
|
|
2777
|
+
}
|
|
2778
|
+
};
|
|
2779
|
+
function createJupyterClientFromEnv() {
|
|
2780
|
+
const serverUrl = process.env.JUPYTER_SERVER_URL;
|
|
2781
|
+
const token = process.env.JUPYTER_TOKEN;
|
|
2782
|
+
if (!serverUrl) {
|
|
2783
|
+
return null;
|
|
2784
|
+
}
|
|
2785
|
+
return new JupyterClient({ serverUrl, token });
|
|
2786
|
+
}
|
|
2787
|
+
|
|
2487
2788
|
// src/llm/NotifyingLlmBackend.ts
|
|
2488
2789
|
var NotifyingLlmBackend = class {
|
|
2489
2790
|
constructor(inner, backgroundManager) {
|
|
@@ -2689,6 +2990,15 @@ process.on("warning", (warning) => {
|
|
|
2689
2990
|
}
|
|
2690
2991
|
console.warn(warning);
|
|
2691
2992
|
});
|
|
2993
|
+
function getRequiredJupyterClient() {
|
|
2994
|
+
const client = createJupyterClientFromEnv();
|
|
2995
|
+
if (!client) {
|
|
2996
|
+
throw new Error(
|
|
2997
|
+
"Jupyter not configured. Set JUPYTER_SERVER_URL and optionally JUPYTER_TOKEN environment variables."
|
|
2998
|
+
);
|
|
2999
|
+
}
|
|
3000
|
+
return client;
|
|
3001
|
+
}
|
|
2692
3002
|
var exitTimestamp = null;
|
|
2693
3003
|
var EXIT_TIMEOUT_MS = 2e3;
|
|
2694
3004
|
var usageCache = null;
|
|
@@ -2924,6 +3234,46 @@ function CliApp() {
|
|
|
2924
3234
|
result = entries.map((e) => ({ name: e.name, isDirectory: e.isDirectory() }));
|
|
2925
3235
|
break;
|
|
2926
3236
|
}
|
|
3237
|
+
// Jupyter kernel commands
|
|
3238
|
+
case "jupyter_get_kernelspecs": {
|
|
3239
|
+
logger.info("[Keep] Getting Jupyter kernel specs");
|
|
3240
|
+
result = await getRequiredJupyterClient().getKernelSpecs();
|
|
3241
|
+
break;
|
|
3242
|
+
}
|
|
3243
|
+
case "jupyter_start_kernel": {
|
|
3244
|
+
const notebookPath = params.notebookPath;
|
|
3245
|
+
const kernelName = params.kernelName;
|
|
3246
|
+
logger.info(`[Keep] Starting Jupyter kernel for: ${notebookPath}`);
|
|
3247
|
+
result = await getRequiredJupyterClient().startSession(notebookPath, kernelName);
|
|
3248
|
+
break;
|
|
3249
|
+
}
|
|
3250
|
+
case "jupyter_stop_kernel": {
|
|
3251
|
+
const sessionId = params.sessionId;
|
|
3252
|
+
if (!sessionId) throw new Error("Missing required param: sessionId");
|
|
3253
|
+
logger.info(`[Keep] Stopping Jupyter session: ${sessionId}`);
|
|
3254
|
+
await getRequiredJupyterClient().stopSession(sessionId);
|
|
3255
|
+
result = { success: true, sessionId };
|
|
3256
|
+
break;
|
|
3257
|
+
}
|
|
3258
|
+
case "jupyter_execute_cell": {
|
|
3259
|
+
const code = params.code;
|
|
3260
|
+
const kernelId = params.kernelId;
|
|
3261
|
+
const timeoutMs = params.timeoutMs || 3e4;
|
|
3262
|
+
if (!code) throw new Error("Missing required param: code");
|
|
3263
|
+
if (!kernelId) throw new Error("Missing required param: kernelId");
|
|
3264
|
+
logger.info(`[Keep] Executing cell (kernel: ${kernelId}, code length: ${code.length})`);
|
|
3265
|
+
const cellResult = await getRequiredJupyterClient().executeCell(kernelId, code, timeoutMs);
|
|
3266
|
+
logger.info(
|
|
3267
|
+
`[Keep] Cell execution ${cellResult.success ? "succeeded" : "failed"} (outputs: ${cellResult.outputs.length}, execution_count: ${cellResult.executionCount})`
|
|
3268
|
+
);
|
|
3269
|
+
result = {
|
|
3270
|
+
success: cellResult.success,
|
|
3271
|
+
outputs: cellResult.outputs,
|
|
3272
|
+
executionCount: cellResult.executionCount,
|
|
3273
|
+
error: cellResult.error
|
|
3274
|
+
};
|
|
3275
|
+
break;
|
|
3276
|
+
}
|
|
2927
3277
|
default:
|
|
2928
3278
|
throw new Error(`Unknown command type: ${commandType}`);
|
|
2929
3279
|
}
|
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
import {
|
|
3
3
|
findMostSimilarMemento,
|
|
4
4
|
getRelevantMementos
|
|
5
|
-
} from "./chunk-
|
|
6
|
-
import "./chunk-
|
|
5
|
+
} from "./chunk-YKQNMQX5.js";
|
|
6
|
+
import "./chunk-AWG7GGY5.js";
|
|
7
7
|
import "./chunk-PFBYGCOW.js";
|
|
8
|
-
import "./chunk-
|
|
8
|
+
import "./chunk-VWH4PFPB.js";
|
|
9
9
|
export {
|
|
10
10
|
findMostSimilarMemento,
|
|
11
11
|
getRelevantMementos
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
ALERT_THRESHOLDS,
|
|
4
|
+
ALLOWED_JUPYTER_KERNELS,
|
|
4
5
|
ALL_IMAGE_MODELS,
|
|
5
6
|
ALL_IMAGE_SIZES,
|
|
6
7
|
ANOMALY_THRESHOLDS,
|
|
@@ -160,10 +161,13 @@ import {
|
|
|
160
161
|
JIRA_PROJECT_KEY_RE,
|
|
161
162
|
JiraApi,
|
|
162
163
|
JiraWebhookDeliveryStatus,
|
|
164
|
+
JupyterCellOutputAction,
|
|
165
|
+
JupyterNotebookProgressAction,
|
|
163
166
|
KeepCommandAction,
|
|
164
167
|
KeepCommandRequestAction,
|
|
165
168
|
KeepCommandResponseAction,
|
|
166
169
|
KeepCommandResultAction,
|
|
170
|
+
KeepCommandType,
|
|
167
171
|
KnowledgeType,
|
|
168
172
|
LEGACY_IMAGE_MODEL_MAP,
|
|
169
173
|
LIVEOPS_TRIAGE_RESULT_VALIDATION_LIMITS,
|
|
@@ -451,6 +455,7 @@ import {
|
|
|
451
455
|
generateAnonymousSessionId,
|
|
452
456
|
generateFullManifest,
|
|
453
457
|
getAccessibleDataLakes,
|
|
458
|
+
getAllowedKernelsList,
|
|
454
459
|
getArtifactMimeType,
|
|
455
460
|
getArtifactTypeInfo,
|
|
456
461
|
getAtlassianConfig,
|
|
@@ -470,6 +475,7 @@ import {
|
|
|
470
475
|
getWebsiteUrl,
|
|
471
476
|
groupShareSchema,
|
|
472
477
|
hasRateLimitInfo,
|
|
478
|
+
isAllowedJupyterKernel,
|
|
473
479
|
isArtifact,
|
|
474
480
|
isCommentWebhookEvent,
|
|
475
481
|
isCreditHolder,
|
|
@@ -524,11 +530,13 @@ import {
|
|
|
524
530
|
validateArtifactTitle,
|
|
525
531
|
validateBaseArtifact,
|
|
526
532
|
validateHtmlArtifactV2,
|
|
533
|
+
validateJupyterKernelName,
|
|
527
534
|
validateLatticeEntity,
|
|
528
535
|
validateLatticeModel,
|
|
529
536
|
validateLatticeParsedIntent,
|
|
530
537
|
validateLatticeRule,
|
|
531
538
|
validateMermaidArtifactV2,
|
|
539
|
+
validateNotebookPath,
|
|
532
540
|
validatePassword,
|
|
533
541
|
validatePasswordServer,
|
|
534
542
|
validatePythonArtifactV2,
|
|
@@ -537,9 +545,10 @@ import {
|
|
|
537
545
|
validateReactArtifactV2,
|
|
538
546
|
validateSvgArtifactV2,
|
|
539
547
|
wikiMarkupToAdf
|
|
540
|
-
} from "./chunk-
|
|
548
|
+
} from "./chunk-VWH4PFPB.js";
|
|
541
549
|
export {
|
|
542
550
|
ALERT_THRESHOLDS,
|
|
551
|
+
ALLOWED_JUPYTER_KERNELS,
|
|
543
552
|
ALL_IMAGE_MODELS,
|
|
544
553
|
ALL_IMAGE_SIZES,
|
|
545
554
|
ANOMALY_THRESHOLDS,
|
|
@@ -700,10 +709,13 @@ export {
|
|
|
700
709
|
JIRA_PROJECT_KEY_RE,
|
|
701
710
|
JiraApi,
|
|
702
711
|
JiraWebhookDeliveryStatus,
|
|
712
|
+
JupyterCellOutputAction,
|
|
713
|
+
JupyterNotebookProgressAction,
|
|
703
714
|
KeepCommandAction,
|
|
704
715
|
KeepCommandRequestAction,
|
|
705
716
|
KeepCommandResponseAction,
|
|
706
717
|
KeepCommandResultAction,
|
|
718
|
+
KeepCommandType,
|
|
707
719
|
KnowledgeType,
|
|
708
720
|
LEGACY_IMAGE_MODEL_MAP,
|
|
709
721
|
LIVEOPS_TRIAGE_RESULT_VALIDATION_LIMITS,
|
|
@@ -992,6 +1004,7 @@ export {
|
|
|
992
1004
|
generateAnonymousSessionId,
|
|
993
1005
|
generateFullManifest,
|
|
994
1006
|
getAccessibleDataLakes,
|
|
1007
|
+
getAllowedKernelsList,
|
|
995
1008
|
getArtifactMimeType,
|
|
996
1009
|
getArtifactTypeInfo,
|
|
997
1010
|
getAtlassianConfig,
|
|
@@ -1011,6 +1024,7 @@ export {
|
|
|
1011
1024
|
getWebsiteUrl,
|
|
1012
1025
|
groupShareSchema,
|
|
1013
1026
|
hasRateLimitInfo,
|
|
1027
|
+
isAllowedJupyterKernel,
|
|
1014
1028
|
isArtifact,
|
|
1015
1029
|
isCommentWebhookEvent,
|
|
1016
1030
|
isCreditHolder,
|
|
@@ -1065,11 +1079,13 @@ export {
|
|
|
1065
1079
|
validateArtifactTitle,
|
|
1066
1080
|
validateBaseArtifact,
|
|
1067
1081
|
validateHtmlArtifactV2,
|
|
1082
|
+
validateJupyterKernelName,
|
|
1068
1083
|
validateLatticeEntity,
|
|
1069
1084
|
validateLatticeModel,
|
|
1070
1085
|
validateLatticeParsedIntent,
|
|
1071
1086
|
validateLatticeRule,
|
|
1072
1087
|
validateMermaidArtifactV2,
|
|
1088
|
+
validateNotebookPath,
|
|
1073
1089
|
validatePassword,
|
|
1074
1090
|
validatePasswordServer,
|
|
1075
1091
|
validatePythonArtifactV2,
|
|
@@ -143,7 +143,7 @@ import {
|
|
|
143
143
|
validateUrlForFetch,
|
|
144
144
|
warmUpSettingsCache,
|
|
145
145
|
withRetry
|
|
146
|
-
} from "./chunk-
|
|
146
|
+
} from "./chunk-AWG7GGY5.js";
|
|
147
147
|
import {
|
|
148
148
|
Logger,
|
|
149
149
|
NotificationDeduplicator,
|
|
@@ -156,7 +156,7 @@ import {
|
|
|
156
156
|
buildRateLimitLogEntry,
|
|
157
157
|
isNearLimit,
|
|
158
158
|
parseRateLimitHeaders
|
|
159
|
-
} from "./chunk-
|
|
159
|
+
} from "./chunk-VWH4PFPB.js";
|
|
160
160
|
export {
|
|
161
161
|
AIVideoService,
|
|
162
162
|
AWSBackend,
|
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
import {
|
|
3
3
|
SubtractCreditsSchema,
|
|
4
4
|
subtractCredits
|
|
5
|
-
} from "./chunk-
|
|
6
|
-
import "./chunk-
|
|
5
|
+
} from "./chunk-RIFFSKKB.js";
|
|
6
|
+
import "./chunk-AWG7GGY5.js";
|
|
7
7
|
import "./chunk-PFBYGCOW.js";
|
|
8
|
-
import "./chunk-
|
|
8
|
+
import "./chunk-VWH4PFPB.js";
|
|
9
9
|
export {
|
|
10
10
|
SubtractCreditsSchema,
|
|
11
11
|
subtractCredits
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bike4mind/cli",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.57-feat-jupyter-interoperability-roadmap.21458+b5aabe927",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Interactive CLI tool for Bike4Mind with ReAct agents",
|
|
6
6
|
"license": "UNLICENSED",
|
|
@@ -115,11 +115,11 @@
|
|
|
115
115
|
"zustand": "^4.5.4"
|
|
116
116
|
},
|
|
117
117
|
"devDependencies": {
|
|
118
|
-
"@bike4mind/agents": "0.2.
|
|
119
|
-
"@bike4mind/common": "2.70.
|
|
120
|
-
"@bike4mind/mcp": "1.33.
|
|
121
|
-
"@bike4mind/services": "2.64.
|
|
122
|
-
"@bike4mind/utils": "2.15.
|
|
118
|
+
"@bike4mind/agents": "0.2.2-feat-jupyter-interoperability-roadmap.21458+b5aabe927",
|
|
119
|
+
"@bike4mind/common": "2.70.2-feat-jupyter-interoperability-roadmap.21458+b5aabe927",
|
|
120
|
+
"@bike4mind/mcp": "1.33.16-feat-jupyter-interoperability-roadmap.21458+b5aabe927",
|
|
121
|
+
"@bike4mind/services": "2.64.4-feat-jupyter-interoperability-roadmap.21458+b5aabe927",
|
|
122
|
+
"@bike4mind/utils": "2.15.10-feat-jupyter-interoperability-roadmap.21458+b5aabe927",
|
|
123
123
|
"@types/better-sqlite3": "^7.6.13",
|
|
124
124
|
"@types/jsonwebtoken": "^9.0.4",
|
|
125
125
|
"@types/node": "^22.9.0",
|
|
@@ -136,5 +136,5 @@
|
|
|
136
136
|
"optionalDependencies": {
|
|
137
137
|
"@vscode/ripgrep": "^1.17.1"
|
|
138
138
|
},
|
|
139
|
-
"gitHead": "
|
|
139
|
+
"gitHead": "b5aabe927ab8e991be795c9a1e998f921eaf3452"
|
|
140
140
|
}
|