@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.
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  CurationArtifactType
4
- } from "./chunk-I5ZF2OVL.js";
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;
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  ChatModels
4
- } from "./chunk-I5ZF2OVL.js";
4
+ } from "./chunk-VWH4PFPB.js";
5
5
  import {
6
6
  DEFAULT_SANDBOX_CONFIG
7
7
  } from "./chunk-4BIBE3J7.js";
@@ -7,11 +7,11 @@ import {
7
7
  getSettingsMap,
8
8
  getSettingsValue,
9
9
  secureParameters
10
- } from "./chunk-KGAK226I.js";
10
+ } from "./chunk-AWG7GGY5.js";
11
11
  import {
12
12
  KnowledgeType,
13
13
  SupportedFabFileMimeTypes
14
- } from "./chunk-I5ZF2OVL.js";
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-I5ZF2OVL.js";
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-XACIOJZ7.js";
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-KGAK226I.js";
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-524RAWPN.js";
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-I5ZF2OVL.js";
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-KGAK226I.js";
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-I5ZF2OVL.js";
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.56",
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.1",
122
- "@bike4mind/common": "2.70.1",
123
- "@bike4mind/mcp": "1.33.15",
124
- "@bike4mind/services": "2.64.3",
125
- "@bike4mind/utils": "2.15.9",
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: "bf6c3f4e7997e0ab0796c64ccd6b46d6d1fce954"
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: z11.enum(["read_file", "list_directory", "run_tool"]),
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: z11.enum(["read_file", "list_directory", "run_tool"]),
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-KGAK226I.js";
9
+ } from "./chunk-AWG7GGY5.js";
10
10
  import {
11
11
  ApiKeyType,
12
12
  MementoTier,
13
13
  isSupportedEmbeddingModel
14
- } from "./chunk-I5ZF2OVL.js";
14
+ } from "./chunk-VWH4PFPB.js";
15
15
 
16
16
  // ../../b4m-core/packages/services/dist/src/apiKeyService/get.js
17
17
  import { z } from "zod";
@@ -3,7 +3,7 @@ import {
3
3
  fetchLatestVersion,
4
4
  forceCheckForUpdate,
5
5
  package_default
6
- } from "../chunk-5UDVBQZ7.js";
6
+ } from "../chunk-TYXGSRCJ.js";
7
7
 
8
8
  // src/commands/doctorCommand.ts
9
9
  import { execSync } from "child_process";
@@ -36,20 +36,20 @@ import {
36
36
  isReadOnlyTool,
37
37
  loadContextFiles,
38
38
  setWebSocketToolExecutor
39
- } from "../chunk-SA2GRZGG.js";
39
+ } from "../chunk-O55VX62E.js";
40
40
  import "../chunk-BDQBOLYG.js";
41
- import "../chunk-XACIOJZ7.js";
41
+ import "../chunk-YKQNMQX5.js";
42
42
  import "../chunk-GQGOWACU.js";
43
- import "../chunk-VILQBYE6.js";
44
- import "../chunk-S27A7SCI.js";
45
- import "../chunk-KGAK226I.js";
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-524RAWPN.js";
52
- import "../chunk-I5ZF2OVL.js";
51
+ } from "../chunk-3JJYLK4C.js";
52
+ import "../chunk-VWH4PFPB.js";
53
53
  import {
54
54
  DEFAULT_SANDBOX_CONFIG
55
55
  } from "../chunk-4BIBE3J7.js";
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  ConfigStore
4
- } from "../chunk-524RAWPN.js";
5
- import "../chunk-I5ZF2OVL.js";
4
+ } from "../chunk-3JJYLK4C.js";
5
+ import "../chunk-VWH4PFPB.js";
6
6
  import "../chunk-4BIBE3J7.js";
7
7
 
8
8
  // src/commands/mcpCommand.ts
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  forceCheckForUpdate,
4
4
  package_default
5
- } from "../chunk-5UDVBQZ7.js";
5
+ } from "../chunk-TYXGSRCJ.js";
6
6
 
7
7
  // src/commands/updateCommand.ts
8
8
  import { execSync } from "child_process";
@@ -2,10 +2,10 @@
2
2
  import {
3
3
  createFabFile,
4
4
  createFabFileSchema
5
- } from "./chunk-S27A7SCI.js";
6
- import "./chunk-KGAK226I.js";
5
+ } from "./chunk-67YAACDQ.js";
6
+ import "./chunk-AWG7GGY5.js";
7
7
  import "./chunk-PFBYGCOW.js";
8
- import "./chunk-I5ZF2OVL.js";
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-SA2GRZGG.js";
49
+ } from "./chunk-O55VX62E.js";
50
50
  import "./chunk-BDQBOLYG.js";
51
- import "./chunk-XACIOJZ7.js";
51
+ import "./chunk-YKQNMQX5.js";
52
52
  import "./chunk-GQGOWACU.js";
53
- import "./chunk-VILQBYE6.js";
54
- import "./chunk-S27A7SCI.js";
53
+ import "./chunk-RIFFSKKB.js";
54
+ import "./chunk-67YAACDQ.js";
55
55
  import {
56
56
  OllamaBackend
57
- } from "./chunk-KGAK226I.js";
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-524RAWPN.js";
63
+ } from "./chunk-3JJYLK4C.js";
64
64
  import {
65
65
  checkForUpdate,
66
66
  package_default
67
- } from "./chunk-5UDVBQZ7.js";
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
- } from "./chunk-I5ZF2OVL.js";
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
  }
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  CurationArtifactType
4
- } from "./chunk-I5ZF2OVL.js";
4
+ } from "./chunk-VWH4PFPB.js";
5
5
 
6
6
  // ../../b4m-core/packages/services/dist/src/notebookCurationService/llmMarkdownGenerator.js
7
7
  var DEFAULT_OPTIONS = {
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  CurationArtifactType
4
- } from "./chunk-I5ZF2OVL.js";
4
+ } from "./chunk-VWH4PFPB.js";
5
5
 
6
6
  // ../../b4m-core/packages/services/dist/src/notebookCurationService/markdownGenerator.js
7
7
  var DEFAULT_OPTIONS = {
@@ -2,10 +2,10 @@
2
2
  import {
3
3
  findMostSimilarMemento,
4
4
  getRelevantMementos
5
- } from "./chunk-XACIOJZ7.js";
6
- import "./chunk-KGAK226I.js";
5
+ } from "./chunk-YKQNMQX5.js";
6
+ import "./chunk-AWG7GGY5.js";
7
7
  import "./chunk-PFBYGCOW.js";
8
- import "./chunk-I5ZF2OVL.js";
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-I5ZF2OVL.js";
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-KGAK226I.js";
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-I5ZF2OVL.js";
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-VILQBYE6.js";
6
- import "./chunk-KGAK226I.js";
5
+ } from "./chunk-RIFFSKKB.js";
6
+ import "./chunk-AWG7GGY5.js";
7
7
  import "./chunk-PFBYGCOW.js";
8
- import "./chunk-I5ZF2OVL.js";
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.56",
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.1",
119
- "@bike4mind/common": "2.70.1",
120
- "@bike4mind/mcp": "1.33.15",
121
- "@bike4mind/services": "2.64.3",
122
- "@bike4mind/utils": "2.15.9",
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": "bf6c3f4e7997e0ab0796c64ccd6b46d6d1fce954"
139
+ "gitHead": "b5aabe927ab8e991be795c9a1e998f921eaf3452"
140
140
  }