mito-ai 0.1.43__py3-none-any.whl → 0.1.45__py3-none-any.whl
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.
Potentially problematic release.
This version of mito-ai might be problematic. Click here for more details.
- mito_ai/__init__.py +3 -3
- mito_ai/_version.py +1 -1
- mito_ai/anthropic_client.py +2 -3
- mito_ai/{app_builder → app_deploy}/__init__.py +1 -1
- mito_ai/app_deploy/app_deploy_utils.py +25 -0
- mito_ai/{app_builder → app_deploy}/handlers.py +48 -40
- mito_ai/{app_builder → app_deploy}/models.py +17 -14
- mito_ai/app_manager/handlers.py +33 -0
- mito_ai/app_manager/models.py +15 -1
- mito_ai/completions/handlers.py +40 -1
- mito_ai/completions/models.py +5 -1
- mito_ai/completions/prompt_builders/agent_system_message.py +6 -4
- mito_ai/completions/prompt_builders/prompt_constants.py +22 -4
- mito_ai/completions/providers.py +5 -11
- mito_ai/streamlit_conversion/streamlit_agent_handler.py +6 -3
- mito_ai/streamlit_conversion/streamlit_utils.py +15 -7
- mito_ai/streamlit_conversion/validate_streamlit_app.py +34 -25
- mito_ai/streamlit_preview/handlers.py +49 -70
- mito_ai/streamlit_preview/utils.py +41 -0
- mito_ai/tests/deploy_app/test_app_deploy_utils.py +71 -0
- mito_ai/tests/providers/test_anthropic_client.py +2 -2
- mito_ai/tests/streamlit_conversion/test_streamlit_agent_handler.py +0 -84
- mito_ai/tests/streamlit_conversion/test_validate_streamlit_app.py +0 -15
- mito_ai/tests/streamlit_preview/test_streamlit_preview_handler.py +88 -0
- mito_ai/tests/streamlit_preview/test_streamlit_preview_manager.py +4 -1
- mito_ai/tests/utils/test_anthropic_utils.py +4 -4
- mito_ai/utils/anthropic_utils.py +11 -19
- mito_ai/utils/telemetry_utils.py +15 -5
- {mito_ai-0.1.43.data → mito_ai-0.1.45.data}/data/share/jupyter/labextensions/mito_ai/build_log.json +100 -100
- {mito_ai-0.1.43.data → mito_ai-0.1.45.data}/data/share/jupyter/labextensions/mito_ai/package.json +2 -2
- {mito_ai-0.1.43.data → mito_ai-0.1.45.data}/data/share/jupyter/labextensions/mito_ai/schemas/mito_ai/package.json.orig +1 -1
- {mito_ai-0.1.43.data → mito_ai-0.1.45.data}/data/share/jupyter/labextensions/mito_ai/schemas/mito_ai/toolbar-buttons.json +0 -5
- mito_ai-0.1.43.data/data/share/jupyter/labextensions/mito_ai/static/lib_index_js.81703ac2bc645e5c2fc2.js → mito_ai-0.1.45.data/data/share/jupyter/labextensions/mito_ai/static/lib_index_js.0c3368195d954d2ed033.js +1729 -790
- mito_ai-0.1.45.data/data/share/jupyter/labextensions/mito_ai/static/lib_index_js.0c3368195d954d2ed033.js.map +1 -0
- mito_ai-0.1.43.data/data/share/jupyter/labextensions/mito_ai/static/remoteEntry.502aef26f0416fab7435.js → mito_ai-0.1.45.data/data/share/jupyter/labextensions/mito_ai/static/remoteEntry.684f82575fcc2e3b350c.js +17 -17
- mito_ai-0.1.43.data/data/share/jupyter/labextensions/mito_ai/static/remoteEntry.502aef26f0416fab7435.js.map → mito_ai-0.1.45.data/data/share/jupyter/labextensions/mito_ai/static/remoteEntry.684f82575fcc2e3b350c.js.map +1 -1
- {mito_ai-0.1.43.dist-info → mito_ai-0.1.45.dist-info}/METADATA +2 -2
- {mito_ai-0.1.43.dist-info → mito_ai-0.1.45.dist-info}/RECORD +61 -57
- mito_ai-0.1.43.data/data/share/jupyter/labextensions/mito_ai/static/lib_index_js.81703ac2bc645e5c2fc2.js.map +0 -1
- {mito_ai-0.1.43.data → mito_ai-0.1.45.data}/data/etc/jupyter/jupyter_server_config.d/mito_ai.json +0 -0
- {mito_ai-0.1.43.data → mito_ai-0.1.45.data}/data/share/jupyter/labextensions/mito_ai/static/node_modules_process_browser_js.4b128e94d31a81ebd209.js +0 -0
- {mito_ai-0.1.43.data → mito_ai-0.1.45.data}/data/share/jupyter/labextensions/mito_ai/static/node_modules_process_browser_js.4b128e94d31a81ebd209.js.map +0 -0
- {mito_ai-0.1.43.data → mito_ai-0.1.45.data}/data/share/jupyter/labextensions/mito_ai/static/style.js +0 -0
- {mito_ai-0.1.43.data → mito_ai-0.1.45.data}/data/share/jupyter/labextensions/mito_ai/static/style_index_js.5876024bb17dbd6a3ee6.js +0 -0
- {mito_ai-0.1.43.data → mito_ai-0.1.45.data}/data/share/jupyter/labextensions/mito_ai/static/style_index_js.5876024bb17dbd6a3ee6.js.map +0 -0
- {mito_ai-0.1.43.data → mito_ai-0.1.45.data}/data/share/jupyter/labextensions/mito_ai/static/vendors-node_modules_aws-amplify_auth_dist_esm_providers_cognito_apis_signOut_mjs-node_module-75790d.688c25857e7b81b1740f.js +0 -0
- {mito_ai-0.1.43.data → mito_ai-0.1.45.data}/data/share/jupyter/labextensions/mito_ai/static/vendors-node_modules_aws-amplify_auth_dist_esm_providers_cognito_apis_signOut_mjs-node_module-75790d.688c25857e7b81b1740f.js.map +0 -0
- {mito_ai-0.1.43.data → mito_ai-0.1.45.data}/data/share/jupyter/labextensions/mito_ai/static/vendors-node_modules_aws-amplify_auth_dist_esm_providers_cognito_tokenProvider_tokenProvider_-72f1c8.a917210f057fcfe224ad.js +0 -0
- {mito_ai-0.1.43.data → mito_ai-0.1.45.data}/data/share/jupyter/labextensions/mito_ai/static/vendors-node_modules_aws-amplify_auth_dist_esm_providers_cognito_tokenProvider_tokenProvider_-72f1c8.a917210f057fcfe224ad.js.map +0 -0
- {mito_ai-0.1.43.data → mito_ai-0.1.45.data}/data/share/jupyter/labextensions/mito_ai/static/vendors-node_modules_aws-amplify_dist_esm_index_mjs.6bac1a8c4cc93f15f6b7.js +0 -0
- {mito_ai-0.1.43.data → mito_ai-0.1.45.data}/data/share/jupyter/labextensions/mito_ai/static/vendors-node_modules_aws-amplify_dist_esm_index_mjs.6bac1a8c4cc93f15f6b7.js.map +0 -0
- {mito_ai-0.1.43.data → mito_ai-0.1.45.data}/data/share/jupyter/labextensions/mito_ai/static/vendors-node_modules_aws-amplify_ui-react_dist_esm_index_mjs.4fcecd65bef9e9847609.js +0 -0
- {mito_ai-0.1.43.data → mito_ai-0.1.45.data}/data/share/jupyter/labextensions/mito_ai/static/vendors-node_modules_aws-amplify_ui-react_dist_esm_index_mjs.4fcecd65bef9e9847609.js.map +0 -0
- {mito_ai-0.1.43.data → mito_ai-0.1.45.data}/data/share/jupyter/labextensions/mito_ai/static/vendors-node_modules_react-dom_client_js-node_modules_aws-amplify_ui-react_dist_styles_css.b43d4249e4d3dac9ad7b.js +0 -0
- {mito_ai-0.1.43.data → mito_ai-0.1.45.data}/data/share/jupyter/labextensions/mito_ai/static/vendors-node_modules_react-dom_client_js-node_modules_aws-amplify_ui-react_dist_styles_css.b43d4249e4d3dac9ad7b.js.map +0 -0
- {mito_ai-0.1.43.data → mito_ai-0.1.45.data}/data/share/jupyter/labextensions/mito_ai/static/vendors-node_modules_semver_index_js.3f6754ac5116d47de76b.js +0 -0
- {mito_ai-0.1.43.data → mito_ai-0.1.45.data}/data/share/jupyter/labextensions/mito_ai/static/vendors-node_modules_semver_index_js.3f6754ac5116d47de76b.js.map +0 -0
- {mito_ai-0.1.43.data → mito_ai-0.1.45.data}/data/share/jupyter/labextensions/mito_ai/static/vendors-node_modules_vscode-diff_dist_index_js.ea55f1f9346638aafbcf.js +0 -0
- {mito_ai-0.1.43.data → mito_ai-0.1.45.data}/data/share/jupyter/labextensions/mito_ai/static/vendors-node_modules_vscode-diff_dist_index_js.ea55f1f9346638aafbcf.js.map +0 -0
- {mito_ai-0.1.43.dist-info → mito_ai-0.1.45.dist-info}/WHEEL +0 -0
- {mito_ai-0.1.43.dist-info → mito_ai-0.1.45.dist-info}/entry_points.txt +0 -0
- {mito_ai-0.1.43.dist-info → mito_ai-0.1.45.dist-info}/licenses/LICENSE +0 -0
|
@@ -213,9 +213,10 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
213
213
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
214
214
|
/* harmony export */ ChatHistoryManager: () => (/* binding */ ChatHistoryManager)
|
|
215
215
|
/* harmony export */ });
|
|
216
|
-
/* harmony import */ var
|
|
217
|
-
/* harmony import */ var
|
|
218
|
-
/* harmony import */ var
|
|
216
|
+
/* harmony import */ var _utils_notebook__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../utils/notebook */ "./lib/utils/notebook.js");
|
|
217
|
+
/* harmony import */ var _utils_strings__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../utils/strings */ "./lib/utils/strings.js");
|
|
218
|
+
/* harmony import */ var _utils_user__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../utils/user */ "./lib/utils/user.js");
|
|
219
|
+
/* harmony import */ var _validationUtils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./validationUtils */ "./lib/Extensions/AiChat/validationUtils.js");
|
|
219
220
|
/*
|
|
220
221
|
* Copyright (c) Saga Inc.
|
|
221
222
|
* Distributed under the terms of the GNU Affero General Public License v3.0 License.
|
|
@@ -223,6 +224,7 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
223
224
|
|
|
224
225
|
|
|
225
226
|
|
|
227
|
+
|
|
226
228
|
/*
|
|
227
229
|
The ChatHistoryManager is responsible for managing the AI chat history.
|
|
228
230
|
|
|
@@ -271,6 +273,11 @@ class ChatHistoryManager {
|
|
|
271
273
|
this._allAssumptions.clear();
|
|
272
274
|
this.displayOptimizedChatHistory.forEach(item => {
|
|
273
275
|
var _a;
|
|
276
|
+
// Validate the agent response if it exists
|
|
277
|
+
if (item.agentResponse !== undefined) {
|
|
278
|
+
item.agentResponse = (0,_validationUtils__WEBPACK_IMPORTED_MODULE_0__.validateAndCorrectAgentResponse)(item.agentResponse);
|
|
279
|
+
}
|
|
280
|
+
// Process the assumptions
|
|
274
281
|
if ((_a = item.agentResponse) === null || _a === void 0 ? void 0 : _a.analysis_assumptions) {
|
|
275
282
|
item.agentResponse.analysis_assumptions.forEach(assumption => {
|
|
276
283
|
this._allAssumptions.add(assumption);
|
|
@@ -308,12 +315,13 @@ class ChatHistoryManager {
|
|
|
308
315
|
});
|
|
309
316
|
}
|
|
310
317
|
async addChatInputMessage(input, activeThreadId, messageIndex, additionalContext) {
|
|
311
|
-
const activeCellCode = (0,
|
|
312
|
-
const activeCellID = (0,
|
|
318
|
+
const activeCellCode = (0,_utils_notebook__WEBPACK_IMPORTED_MODULE_1__.getActiveCellCode)(this.notebookTracker) || '';
|
|
319
|
+
const activeCellID = (0,_utils_notebook__WEBPACK_IMPORTED_MODULE_1__.getActiveCellID)(this.notebookTracker) || '';
|
|
320
|
+
const activeNotebookContext = this.contextManager.getActiveNotebookContext();
|
|
313
321
|
const chatMessageMetadata = {
|
|
314
322
|
promptType: 'chat',
|
|
315
|
-
variables:
|
|
316
|
-
files:
|
|
323
|
+
variables: (activeNotebookContext === null || activeNotebookContext === void 0 ? void 0 : activeNotebookContext.variables) || [],
|
|
324
|
+
files: (activeNotebookContext === null || activeNotebookContext === void 0 ? void 0 : activeNotebookContext.files) || [],
|
|
317
325
|
activeCellCode: activeCellCode,
|
|
318
326
|
activeCellId: activeCellID,
|
|
319
327
|
input: input,
|
|
@@ -330,16 +338,17 @@ class ChatHistoryManager {
|
|
|
330
338
|
});
|
|
331
339
|
return chatMessageMetadata;
|
|
332
340
|
}
|
|
333
|
-
addAgentExecutionMessage(activeThreadId, input, additionalContext) {
|
|
334
|
-
const aiOptimizedCells = (0,
|
|
341
|
+
addAgentExecutionMessage(activeThreadId, notebookPanel, input, additionalContext) {
|
|
342
|
+
const aiOptimizedCells = (0,_utils_notebook__WEBPACK_IMPORTED_MODULE_1__.getAIOptimizedCellsInNotebookPanel)(notebookPanel);
|
|
343
|
+
const notebookContext = this.contextManager.getNotebookContext(notebookPanel.id);
|
|
335
344
|
const agentExecutionMetadata = {
|
|
336
345
|
promptType: 'agent:execution',
|
|
337
|
-
variables:
|
|
338
|
-
files:
|
|
346
|
+
variables: (notebookContext === null || notebookContext === void 0 ? void 0 : notebookContext.variables) || [],
|
|
347
|
+
files: (notebookContext === null || notebookContext === void 0 ? void 0 : notebookContext.files) || [],
|
|
339
348
|
aiOptimizedCells: aiOptimizedCells,
|
|
340
349
|
input: input || '',
|
|
341
350
|
threadId: activeThreadId,
|
|
342
|
-
isChromeBrowser: (0,
|
|
351
|
+
isChromeBrowser: (0,_utils_user__WEBPACK_IMPORTED_MODULE_2__.isChromeBasedBrowser)(),
|
|
343
352
|
additionalContext: additionalContext
|
|
344
353
|
};
|
|
345
354
|
// We use this function in two ways:
|
|
@@ -364,16 +373,14 @@ class ChatHistoryManager {
|
|
|
364
373
|
});
|
|
365
374
|
return agentExecutionMetadata;
|
|
366
375
|
}
|
|
367
|
-
dropMessagesStartingAtIndex(index) {
|
|
368
|
-
this.displayOptimizedChatHistory.splice(index);
|
|
369
|
-
}
|
|
370
376
|
addSmartDebugMessage(activeThreadId, errorMessage) {
|
|
371
|
-
const activeCellID = (0,
|
|
372
|
-
const activeCellCode = (0,
|
|
377
|
+
const activeCellID = (0,_utils_notebook__WEBPACK_IMPORTED_MODULE_1__.getActiveCellID)(this.notebookTracker) || '';
|
|
378
|
+
const activeCellCode = (0,_utils_notebook__WEBPACK_IMPORTED_MODULE_1__.getCellCodeByID)(this.notebookTracker, activeCellID) || '';
|
|
379
|
+
const activeNotebookContext = this.contextManager.getActiveNotebookContext();
|
|
373
380
|
const smartDebugMetadata = {
|
|
374
381
|
promptType: 'smartDebug',
|
|
375
|
-
variables:
|
|
376
|
-
files:
|
|
382
|
+
variables: (activeNotebookContext === null || activeNotebookContext === void 0 ? void 0 : activeNotebookContext.variables) || [],
|
|
383
|
+
files: (activeNotebookContext === null || activeNotebookContext === void 0 ? void 0 : activeNotebookContext.files) || [],
|
|
377
384
|
activeCellCode: activeCellCode,
|
|
378
385
|
activeCellId: activeCellID,
|
|
379
386
|
errorMessage: errorMessage,
|
|
@@ -387,18 +394,19 @@ class ChatHistoryManager {
|
|
|
387
394
|
});
|
|
388
395
|
return smartDebugMetadata;
|
|
389
396
|
}
|
|
390
|
-
addAgentSmartDebugMessage(activeThreadId, errorMessage) {
|
|
391
|
-
const activeCellID = (0,
|
|
392
|
-
const activeCellCode = (0,
|
|
397
|
+
addAgentSmartDebugMessage(activeThreadId, errorMessage, notebookPanel) {
|
|
398
|
+
const activeCellID = (0,_utils_notebook__WEBPACK_IMPORTED_MODULE_1__.getActiveCellIDInNotebookPanel)(notebookPanel);
|
|
399
|
+
const activeCellCode = (0,_utils_notebook__WEBPACK_IMPORTED_MODULE_1__.getCellCodeByIDInNotebookPanel)(notebookPanel, activeCellID);
|
|
400
|
+
const notebookContext = this.contextManager.getNotebookContext(notebookPanel.id);
|
|
393
401
|
const agentSmartDebugMetadata = {
|
|
394
402
|
promptType: 'agent:autoErrorFixup',
|
|
395
|
-
aiOptimizedCells: (0,
|
|
396
|
-
variables:
|
|
397
|
-
files:
|
|
403
|
+
aiOptimizedCells: (0,_utils_notebook__WEBPACK_IMPORTED_MODULE_1__.getAIOptimizedCellsInNotebookPanel)(notebookPanel),
|
|
404
|
+
variables: (notebookContext === null || notebookContext === void 0 ? void 0 : notebookContext.variables) || [],
|
|
405
|
+
files: (notebookContext === null || notebookContext === void 0 ? void 0 : notebookContext.files) || [],
|
|
398
406
|
errorMessage: errorMessage,
|
|
399
407
|
error_message_producing_code_cell_id: activeCellID || '',
|
|
400
408
|
threadId: activeThreadId,
|
|
401
|
-
isChromeBrowser: (0,
|
|
409
|
+
isChromeBrowser: (0,_utils_user__WEBPACK_IMPORTED_MODULE_2__.isChromeBasedBrowser)()
|
|
402
410
|
};
|
|
403
411
|
this.displayOptimizedChatHistory.push({
|
|
404
412
|
message: getDisplayedOptimizedUserMessage(errorMessage, activeCellCode),
|
|
@@ -409,11 +417,12 @@ class ChatHistoryManager {
|
|
|
409
417
|
return agentSmartDebugMetadata;
|
|
410
418
|
}
|
|
411
419
|
addExplainCodeMessage(activeThreadId) {
|
|
412
|
-
const activeCellID = (0,
|
|
413
|
-
const activeCellCode = (0,
|
|
420
|
+
const activeCellID = (0,_utils_notebook__WEBPACK_IMPORTED_MODULE_1__.getActiveCellID)(this.notebookTracker);
|
|
421
|
+
const activeCellCode = (0,_utils_notebook__WEBPACK_IMPORTED_MODULE_1__.getCellCodeByID)(this.notebookTracker, activeCellID);
|
|
422
|
+
const activeNotebookContext = this.contextManager.getActiveNotebookContext();
|
|
414
423
|
const codeExplainMetadata = {
|
|
415
424
|
promptType: 'codeExplain',
|
|
416
|
-
variables:
|
|
425
|
+
variables: (activeNotebookContext === null || activeNotebookContext === void 0 ? void 0 : activeNotebookContext.variables) || [],
|
|
417
426
|
activeCellCode,
|
|
418
427
|
threadId: activeThreadId
|
|
419
428
|
};
|
|
@@ -440,7 +449,7 @@ class ChatHistoryManager {
|
|
|
440
449
|
else {
|
|
441
450
|
type = 'openai message';
|
|
442
451
|
}
|
|
443
|
-
const activeCellID = (0,
|
|
452
|
+
const activeCellID = (0,_utils_notebook__WEBPACK_IMPORTED_MODULE_1__.getActiveCellID)(this.notebookTracker);
|
|
444
453
|
this.displayOptimizedChatHistory.push({
|
|
445
454
|
message: aiMessage,
|
|
446
455
|
type: type,
|
|
@@ -467,13 +476,14 @@ class ChatHistoryManager {
|
|
|
467
476
|
}
|
|
468
477
|
addAIMessageFromAgentResponse(agentResponse) {
|
|
469
478
|
var _a;
|
|
479
|
+
agentResponse = (0,_validationUtils__WEBPACK_IMPORTED_MODULE_0__.validateAndCorrectAgentResponse)(agentResponse);
|
|
470
480
|
let content = agentResponse.message;
|
|
471
481
|
if (agentResponse.type === 'cell_update') {
|
|
472
482
|
// For cell_update messages, we want to display the code the agent wrote along with
|
|
473
483
|
// the message it sent. For all other agent responses, we ignore all other fields
|
|
474
484
|
// and just display the message.
|
|
475
485
|
const code = (_a = agentResponse.cell_update) === null || _a === void 0 ? void 0 : _a.code;
|
|
476
|
-
const codeWithMarkdownFormatting = (0,
|
|
486
|
+
const codeWithMarkdownFormatting = (0,_utils_strings__WEBPACK_IMPORTED_MODULE_3__.addMarkdownCodeFormatting)(code);
|
|
477
487
|
if (codeWithMarkdownFormatting !== undefined) {
|
|
478
488
|
content = content + '\n\n' + codeWithMarkdownFormatting;
|
|
479
489
|
}
|
|
@@ -489,6 +499,9 @@ class ChatHistoryManager {
|
|
|
489
499
|
agentResponse: this.deduplicateAssumptions(agentResponse)
|
|
490
500
|
});
|
|
491
501
|
}
|
|
502
|
+
dropMessagesStartingAtIndex(index) {
|
|
503
|
+
this.displayOptimizedChatHistory.splice(index);
|
|
504
|
+
}
|
|
492
505
|
}
|
|
493
506
|
const getDisplayedOptimizedUserMessage = (input, activeCellCode, messageToAgent = false) => {
|
|
494
507
|
// Don't include the active cell code if it is an agent planning message
|
|
@@ -686,7 +699,29 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
686
699
|
|
|
687
700
|
|
|
688
701
|
|
|
689
|
-
const
|
|
702
|
+
const priortizeByType = (options, maxPerType) => {
|
|
703
|
+
/*
|
|
704
|
+
Makes sure that some of each type are displayed at the top of the dropdown so
|
|
705
|
+
users can easily see what types of options are available to them.
|
|
706
|
+
*/
|
|
707
|
+
const typeCounts = {};
|
|
708
|
+
const prioritizedOptions = [];
|
|
709
|
+
const extraOptions = [];
|
|
710
|
+
for (const option of options) {
|
|
711
|
+
const type = option.type;
|
|
712
|
+
const currentCount = typeCounts[type] || 0;
|
|
713
|
+
if (currentCount < maxPerType) {
|
|
714
|
+
prioritizedOptions.push(option);
|
|
715
|
+
typeCounts[type] = currentCount + 1;
|
|
716
|
+
}
|
|
717
|
+
else {
|
|
718
|
+
extraOptions.push(option);
|
|
719
|
+
}
|
|
720
|
+
}
|
|
721
|
+
// Return prioritized options first, then extras at the bottom
|
|
722
|
+
return [...prioritizedOptions, ...extraOptions];
|
|
723
|
+
};
|
|
724
|
+
const ChatDropdown = ({ options, onSelect, filterText, isDropdownFromButton = false, onFilterChange, onClose, }) => {
|
|
690
725
|
const [selectedIndex, setSelectedIndex] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(0);
|
|
691
726
|
const [localFilterText, setLocalFilterText] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(filterText);
|
|
692
727
|
const searchInputRef = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(null);
|
|
@@ -761,7 +796,7 @@ const ChatDropdown = ({ options, onSelect, filterText, maxDropdownItems = 10, is
|
|
|
761
796
|
variable: variable
|
|
762
797
|
})),
|
|
763
798
|
];
|
|
764
|
-
|
|
799
|
+
let searchFilteredOptions = allOptions.filter((option) => {
|
|
765
800
|
if (option.type === 'variable') {
|
|
766
801
|
return option.variable.variable_name.toLowerCase().includes(effectiveFilterText.toLowerCase()) &&
|
|
767
802
|
option.variable.type !== "<class 'module'>" &&
|
|
@@ -777,7 +812,12 @@ const ChatDropdown = ({ options, onSelect, filterText, maxDropdownItems = 10, is
|
|
|
777
812
|
else {
|
|
778
813
|
return option.rule.toLowerCase().includes(effectiveFilterText.toLowerCase());
|
|
779
814
|
}
|
|
780
|
-
})
|
|
815
|
+
});
|
|
816
|
+
// If user is searching (has filter text), show all matches
|
|
817
|
+
// Otherwise, show only 3 of each type by default
|
|
818
|
+
if (effectiveFilterText.trim() === '') {
|
|
819
|
+
searchFilteredOptions = priortizeByType(searchFilteredOptions, 3);
|
|
820
|
+
}
|
|
781
821
|
(0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
|
|
782
822
|
setSelectedIndex(0);
|
|
783
823
|
}, [options, rules, effectiveFilterText]);
|
|
@@ -786,18 +826,18 @@ const ChatDropdown = ({ options, onSelect, filterText, maxDropdownItems = 10, is
|
|
|
786
826
|
case 'ArrowDown':
|
|
787
827
|
case 'Down':
|
|
788
828
|
event.preventDefault();
|
|
789
|
-
setSelectedIndex((prev) => prev <
|
|
829
|
+
setSelectedIndex((prev) => prev < searchFilteredOptions.length - 1 ? prev + 1 : 0);
|
|
790
830
|
break;
|
|
791
831
|
case 'ArrowUp':
|
|
792
832
|
case 'Up':
|
|
793
833
|
event.preventDefault();
|
|
794
|
-
setSelectedIndex((prev) => prev > 0 ? prev - 1 :
|
|
834
|
+
setSelectedIndex((prev) => prev > 0 ? prev - 1 : searchFilteredOptions.length - 1);
|
|
795
835
|
break;
|
|
796
836
|
case 'Enter':
|
|
797
837
|
case 'Return':
|
|
798
838
|
case 'Tab': {
|
|
799
839
|
event.preventDefault();
|
|
800
|
-
const selectedOption =
|
|
840
|
+
const selectedOption = searchFilteredOptions[selectedIndex];
|
|
801
841
|
if (selectedOption !== undefined) {
|
|
802
842
|
if (selectedOption.type === 'variable') {
|
|
803
843
|
onSelect(selectedOption);
|
|
@@ -813,7 +853,7 @@ const ChatDropdown = ({ options, onSelect, filterText, maxDropdownItems = 10, is
|
|
|
813
853
|
(0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
|
|
814
854
|
document.addEventListener('keydown', handleKeyDown);
|
|
815
855
|
return () => document.removeEventListener('keydown', handleKeyDown);
|
|
816
|
-
}, [
|
|
856
|
+
}, [searchFilteredOptions, selectedIndex]);
|
|
817
857
|
// Handle click outside to close dropdown
|
|
818
858
|
(0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
|
|
819
859
|
const handleClickOutside = (event) => {
|
|
@@ -851,8 +891,8 @@ const ChatDropdown = ({ options, onSelect, filterText, maxDropdownItems = 10, is
|
|
|
851
891
|
isDropdownFromButton && (react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { className: "chat-dropdown-search" },
|
|
852
892
|
react__WEBPACK_IMPORTED_MODULE_0___default().createElement("input", { ref: searchInputRef, type: "text", placeholder: "Search variables and rules...", value: localFilterText, onChange: handleSearchInputChange, onKeyDown: handleSearchInputKeyDown, className: "chat-dropdown-search-input" }))),
|
|
853
893
|
react__WEBPACK_IMPORTED_MODULE_0___default().createElement("ul", { className: "chat-dropdown-list", "data-testid": "chat-dropdown-list" },
|
|
854
|
-
|
|
855
|
-
|
|
894
|
+
searchFilteredOptions.length === 0 && (react__WEBPACK_IMPORTED_MODULE_0___default().createElement("li", { className: "chat-dropdown-item", "data-testid": "chat-dropdown-empty-item" }, "No variables found")),
|
|
895
|
+
searchFilteredOptions.map((option, index) => {
|
|
856
896
|
switch (option.type) {
|
|
857
897
|
case 'variable': {
|
|
858
898
|
const uniqueKey = option.variable.parent_df
|
|
@@ -990,7 +1030,6 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
990
1030
|
const ChatInput = ({ app, initialContent, placeholder, onSave, onCancel, isEditing, contextManager, notebookTracker, agentModeEnabled = false, agentExecutionStatus = 'idle', }) => {
|
|
991
1031
|
var _a;
|
|
992
1032
|
const [input, setInput] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(initialContent);
|
|
993
|
-
const [expandedVariables, setExpandedVariables] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)([]);
|
|
994
1033
|
const textAreaRef = react__WEBPACK_IMPORTED_MODULE_0___default().useRef(null);
|
|
995
1034
|
const [activeCellID, setActiveCellID] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)((0,_utils_notebook__WEBPACK_IMPORTED_MODULE_3__.getActiveCellID)(notebookTracker));
|
|
996
1035
|
const activeCellCode = (0,_utils_notebook__WEBPACK_IMPORTED_MODULE_3__.getActiveCellCode)(notebookTracker) || '';
|
|
@@ -1042,9 +1081,10 @@ const ChatInput = ({ app, initialContent, placeholder, onSave, onCancel, isEditi
|
|
|
1042
1081
|
if (!textarea)
|
|
1043
1082
|
return;
|
|
1044
1083
|
textarea.style.minHeight = 'auto';
|
|
1084
|
+
const maxHeight = 350;
|
|
1045
1085
|
textarea.style.height = !textarea.value || resetHeight
|
|
1046
1086
|
? '80px'
|
|
1047
|
-
: `${Math.max(80, textarea.scrollHeight)}px`;
|
|
1087
|
+
: `${Math.min(maxHeight, Math.max(80, textarea.scrollHeight))}px`;
|
|
1048
1088
|
};
|
|
1049
1089
|
(0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
|
|
1050
1090
|
adjustHeight();
|
|
@@ -1175,22 +1215,22 @@ const ChatInput = ({ app, initialContent, placeholder, onSave, onCancel, isEditi
|
|
|
1175
1215
|
});
|
|
1176
1216
|
return result;
|
|
1177
1217
|
};
|
|
1178
|
-
|
|
1179
|
-
|
|
1218
|
+
const getExpandedVarialbes = () => {
|
|
1219
|
+
const activeNotebookContext = contextManager === null || contextManager === void 0 ? void 0 : contextManager.getActiveNotebookContext();
|
|
1180
1220
|
const expandedVariables = [
|
|
1181
1221
|
// Add base variables (excluding DataFrames)
|
|
1182
|
-
...((
|
|
1222
|
+
...((activeNotebookContext === null || activeNotebookContext === void 0 ? void 0 : activeNotebookContext.variables.filter(variable => variable.type !== "pd.DataFrame")) || []),
|
|
1183
1223
|
// Add DataFrames
|
|
1184
|
-
...((
|
|
1224
|
+
...((activeNotebookContext === null || activeNotebookContext === void 0 ? void 0 : activeNotebookContext.variables.filter((variable) => variable.type === "pd.DataFrame")) || []),
|
|
1185
1225
|
// Add series with parent DataFrame references
|
|
1186
|
-
...((
|
|
1226
|
+
...((activeNotebookContext === null || activeNotebookContext === void 0 ? void 0 : activeNotebookContext.variables.filter((variable) => variable.type === "pd.DataFrame").flatMap((df) => Object.entries(df.value).map(([seriesName, _]) => ({
|
|
1187
1227
|
variable_name: seriesName,
|
|
1188
1228
|
type: "col",
|
|
1189
1229
|
value: "replace_me",
|
|
1190
1230
|
parent_df: df.variable_name,
|
|
1191
1231
|
})))) || []),
|
|
1192
1232
|
// Add files
|
|
1193
|
-
...((
|
|
1233
|
+
...((activeNotebookContext === null || activeNotebookContext === void 0 ? void 0 : activeNotebookContext.files.map(file => {
|
|
1194
1234
|
var _a;
|
|
1195
1235
|
return ({
|
|
1196
1236
|
variable_name: file.file_name,
|
|
@@ -1200,8 +1240,8 @@ const ChatInput = ({ app, initialContent, placeholder, onSave, onCancel, isEditi
|
|
|
1200
1240
|
});
|
|
1201
1241
|
})) || [])
|
|
1202
1242
|
];
|
|
1203
|
-
|
|
1204
|
-
}
|
|
1243
|
+
return expandedVariables;
|
|
1244
|
+
};
|
|
1205
1245
|
// Automatically add active cell context when in Chat mode and there's active cell code
|
|
1206
1246
|
(0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
|
|
1207
1247
|
if (!agentModeEnabled) {
|
|
@@ -1223,7 +1263,7 @@ const ChatInput = ({ app, initialContent, placeholder, onSave, onCancel, isEditi
|
|
|
1223
1263
|
}
|
|
1224
1264
|
}
|
|
1225
1265
|
}, [agentModeEnabled, additionalContext, activeCellCode]);
|
|
1226
|
-
return (react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { className: (0,_utils_classNames__WEBPACK_IMPORTED_MODULE_5__.classNames)("chat-input-container") },
|
|
1266
|
+
return (react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { className: (0,_utils_classNames__WEBPACK_IMPORTED_MODULE_5__.classNames)("chat-input-container", { "editing": isEditing }) },
|
|
1227
1267
|
react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { className: 'context-container' },
|
|
1228
1268
|
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_components_DatabaseButton__WEBPACK_IMPORTED_MODULE_6__["default"], { app: app }),
|
|
1229
1269
|
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_components_AttachFileButton__WEBPACK_IMPORTED_MODULE_7__["default"], { onFileUploaded: handleFileUpload, notebookTracker: notebookTracker }),
|
|
@@ -1263,7 +1303,7 @@ const ChatInput = ({ app, initialContent, placeholder, onSave, onCancel, isEditi
|
|
|
1263
1303
|
}
|
|
1264
1304
|
}
|
|
1265
1305
|
} }),
|
|
1266
|
-
isDropdownVisible && (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_ChatDropdown__WEBPACK_IMPORTED_MODULE_9__["default"], { options:
|
|
1306
|
+
isDropdownVisible && (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_ChatDropdown__WEBPACK_IMPORTED_MODULE_9__["default"], { options: getExpandedVarialbes(), onSelect: handleOptionSelect, filterText: dropdownFilter, isDropdownFromButton: isDropdownFromButton, onFilterChange: setDropdownFilter, onClose: handleDropdownClose }))),
|
|
1267
1307
|
isEditing &&
|
|
1268
1308
|
react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { className: "message-edit-buttons" },
|
|
1269
1309
|
react__WEBPACK_IMPORTED_MODULE_0___default().createElement("button", { onClick: () => onSave(input, undefined, mapAdditionalContext()) }, "Save"),
|
|
@@ -1383,11 +1423,11 @@ const ChatMessage = ({ app, message, promptType, agentResponse, messageIndex, mi
|
|
|
1383
1423
|
if (messagePart.length > 14) {
|
|
1384
1424
|
return (react__WEBPACK_IMPORTED_MODULE_0___default().createElement((react__WEBPACK_IMPORTED_MODULE_0___default().Fragment), null,
|
|
1385
1425
|
message.role === 'user' ? (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_UserCodeBlock__WEBPACK_IMPORTED_MODULE_7__["default"], { code: messagePart, renderMimeRegistry: renderMimeRegistry, agentModeEnabled: agentModeEnabled })) : (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_AssistantCodeBlock__WEBPACK_IMPORTED_MODULE_8__["default"], { code: messagePart, codeSummary: (_b = (_a = agentResponse === null || agentResponse === void 0 ? void 0 : agentResponse.cell_update) === null || _a === void 0 ? void 0 : _a.code_summary) !== null && _b !== void 0 ? _b : ((agentResponse === null || agentResponse === void 0 ? void 0 : agentResponse.type) === 'run_all_cells' ? 'Running all cells' : undefined), isCodeComplete: isCodeComplete, renderMimeRegistry: renderMimeRegistry, previewAICode: previewAICode, acceptAICode: acceptAICode, rejectAICode: rejectAICode, isLastAiMessage: isLastAiMessage, codeReviewStatus: codeReviewStatus, agentModeEnabled: agentModeEnabled })),
|
|
1386
|
-
isLastAiMessage && isCodeComplete && codeReviewStatus === 'chatPreview' &&
|
|
1426
|
+
!agentModeEnabled && isLastAiMessage && isCodeComplete && codeReviewStatus === 'chatPreview' &&
|
|
1387
1427
|
react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { className: 'chat-message-buttons' },
|
|
1388
1428
|
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_components_TextAndIconButton__WEBPACK_IMPORTED_MODULE_9__["default"], { onClick: () => { previewAICode(); }, text: 'Overwrite Active Cell', icon: _icons_PlayButtonIcon__WEBPACK_IMPORTED_MODULE_10__["default"], title: 'Write the Ai generated code to the active cell in the jupyter notebook, replacing the current code.', variant: 'gray', width: 'fit-contents' }),
|
|
1389
1429
|
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_components_TextAndIconButton__WEBPACK_IMPORTED_MODULE_9__["default"], { onClick: () => { void (0,_utils_copyToClipboard__WEBPACK_IMPORTED_MODULE_11__["default"])(messagePart); }, text: 'Copy', icon: _icons_CopyIcon__WEBPACK_IMPORTED_MODULE_12__["default"], title: 'Copy the Ai generated code to your clipboard', variant: 'gray', width: 'fit-contents' })),
|
|
1390
|
-
isLastAiMessage && isCodeComplete && codeReviewStatus === 'codeCellPreview' &&
|
|
1430
|
+
!agentModeEnabled && isLastAiMessage && isCodeComplete && codeReviewStatus === 'codeCellPreview' &&
|
|
1391
1431
|
react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { className: 'chat-message-buttons' },
|
|
1392
1432
|
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_components_TextButton__WEBPACK_IMPORTED_MODULE_13__["default"], { onClick: () => { acceptAICode(); }, text: `Accept code ${operatingSystem === 'mac' ? '⌘Y' : 'Ctrl+Y'}`, title: 'Accept the Ai generated code', variant: 'green', width: 'fit-contents' }),
|
|
1393
1433
|
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_components_TextButton__WEBPACK_IMPORTED_MODULE_13__["default"], { onClick: () => { rejectAICode(); }, text: `Reject code ${operatingSystem === 'mac' ? '⌘U' : 'Ctrl+U'}`, title: 'Reject the Ai generated code and revert to the previous version of the code cell', variant: 'red', width: 'fit-contents' })),
|
|
@@ -1468,7 +1508,7 @@ const Citation = ({ citationIndex, cellId, line, notebookTracker }) => {
|
|
|
1468
1508
|
// we set the end line to the start line if only a single line number is provided.
|
|
1469
1509
|
const lineEnd = typeof line === 'number' ? line : line.end;
|
|
1470
1510
|
// Scroll to the cell and highlight the lines
|
|
1471
|
-
(0,_utils_notebook__WEBPACK_IMPORTED_MODULE_2__.scrollToAndHighlightCell)(notebookTracker, cellId, lineStart, lineEnd);
|
|
1511
|
+
(0,_utils_notebook__WEBPACK_IMPORTED_MODULE_2__.scrollToAndHighlightCell)(notebookTracker.currentWidget, cellId, lineStart, lineEnd);
|
|
1472
1512
|
};
|
|
1473
1513
|
return (react__WEBPACK_IMPORTED_MODULE_0___default().createElement("span", { className: "citation-button", onClick: handleClick, title: getLineDisplayText(line) }, citationIndex));
|
|
1474
1514
|
};
|
|
@@ -1958,42 +1998,43 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
1958
1998
|
/* harmony import */ var _jupyterlab_ui_components__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_jupyterlab_ui_components__WEBPACK_IMPORTED_MODULE_2__);
|
|
1959
1999
|
/* harmony import */ var _lumino_coreutils__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @lumino/coreutils */ "webpack/sharing/consume/default/@lumino/coreutils");
|
|
1960
2000
|
/* harmony import */ var _lumino_coreutils__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_lumino_coreutils__WEBPACK_IMPORTED_MODULE_3__);
|
|
1961
|
-
/* harmony import */ var
|
|
1962
|
-
/* harmony import */ var
|
|
1963
|
-
/* harmony import */ var
|
|
1964
|
-
/* harmony import */ var
|
|
1965
|
-
/* harmony import */ var
|
|
1966
|
-
/* harmony import */ var _components_LoadingDots__WEBPACK_IMPORTED_MODULE_31__ = __webpack_require__(/*! ../../components/LoadingDots */ "./lib/components/LoadingDots.js");
|
|
2001
|
+
/* harmony import */ var _commands__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(/*! ../../commands */ "./lib/commands.js");
|
|
2002
|
+
/* harmony import */ var _components_AgentComponents_ErrorFixupToolUI__WEBPACK_IMPORTED_MODULE_30__ = __webpack_require__(/*! ../../components/AgentComponents/ErrorFixupToolUI */ "./lib/components/AgentComponents/ErrorFixupToolUI.js");
|
|
2003
|
+
/* harmony import */ var _components_DropdownMenu__WEBPACK_IMPORTED_MODULE_26__ = __webpack_require__(/*! ../../components/DropdownMenu */ "./lib/components/DropdownMenu.js");
|
|
2004
|
+
/* harmony import */ var _components_IconButton__WEBPACK_IMPORTED_MODULE_24__ = __webpack_require__(/*! ../../components/IconButton */ "./lib/components/IconButton.js");
|
|
2005
|
+
/* harmony import */ var _components_LoadingCircle__WEBPACK_IMPORTED_MODULE_40__ = __webpack_require__(/*! ../../components/LoadingCircle */ "./lib/components/LoadingCircle.js");
|
|
1967
2006
|
/* harmony import */ var _components_ModelSelector__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../../components/ModelSelector */ "./lib/components/ModelSelector.js");
|
|
1968
|
-
/* harmony import */ var
|
|
1969
|
-
/* harmony import */ var
|
|
1970
|
-
/* harmony import */ var
|
|
1971
|
-
/* harmony import */ var
|
|
1972
|
-
/* harmony import */ var
|
|
1973
|
-
/* harmony import */ var
|
|
2007
|
+
/* harmony import */ var _components_NextStepsPills__WEBPACK_IMPORTED_MODULE_37__ = __webpack_require__(/*! ../../components/NextStepsPills */ "./lib/components/NextStepsPills.js");
|
|
2008
|
+
/* harmony import */ var _components_TextAndIconButton__WEBPACK_IMPORTED_MODULE_33__ = __webpack_require__(/*! ../../components/TextAndIconButton */ "./lib/components/TextAndIconButton.js");
|
|
2009
|
+
/* harmony import */ var _components_ToggleButton__WEBPACK_IMPORTED_MODULE_39__ = __webpack_require__(/*! ../../components/ToggleButton */ "./lib/components/ToggleButton.js");
|
|
2010
|
+
/* harmony import */ var _icons__WEBPACK_IMPORTED_MODULE_27__ = __webpack_require__(/*! ../../icons */ "./lib/icons/index.js");
|
|
2011
|
+
/* harmony import */ var _icons_MitoLogo__WEBPACK_IMPORTED_MODULE_28__ = __webpack_require__(/*! ../../icons/MitoLogo */ "./lib/icons/MitoLogo.js");
|
|
2012
|
+
/* harmony import */ var _icons_UndoIcon__WEBPACK_IMPORTED_MODULE_34__ = __webpack_require__(/*! ../../icons/UndoIcon */ "./lib/icons/UndoIcon.js");
|
|
1974
2013
|
/* harmony import */ var _utils_agentActions__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ../../utils/agentActions */ "./lib/utils/agentActions.js");
|
|
1975
2014
|
/* harmony import */ var _utils_blacklistedWords__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ../../utils/blacklistedWords */ "./lib/utils/blacklistedWords.js");
|
|
1976
2015
|
/* harmony import */ var _utils_checkpoint__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ../../utils/checkpoint */ "./lib/utils/checkpoint.js");
|
|
1977
|
-
/* harmony import */ var
|
|
1978
|
-
/* harmony import */ var
|
|
1979
|
-
/* harmony import */ var
|
|
2016
|
+
/* harmony import */ var _utils_chatHistory__WEBPACK_IMPORTED_MODULE_23__ = __webpack_require__(/*! ../../utils/chatHistory */ "./lib/utils/chatHistory.js");
|
|
2017
|
+
/* harmony import */ var _utils_codeDiff__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! ../../utils/codeDiff */ "./lib/utils/codeDiff.js");
|
|
2018
|
+
/* harmony import */ var _utils_notebook__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! ../../utils/notebook */ "./lib/utils/notebook.js");
|
|
2019
|
+
/* harmony import */ var _utils_cellOutput__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ../../utils/cellOutput */ "./lib/utils/cellOutput.js");
|
|
1980
2020
|
/* harmony import */ var _utils_scroll__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../../utils/scroll */ "./lib/utils/scroll.js");
|
|
1981
2021
|
/* harmony import */ var _utils_strings__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ../../utils/strings */ "./lib/utils/strings.js");
|
|
1982
2022
|
/* harmony import */ var _utils_waitForNotebookReady__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../../utils/waitForNotebookReady */ "./lib/utils/waitForNotebookReady.js");
|
|
1983
2023
|
/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./utils */ "./lib/Extensions/AiChat/utils.js");
|
|
1984
|
-
/* harmony import */ var
|
|
2024
|
+
/* harmony import */ var _SettingsManager_SettingsManagerPlugin__WEBPACK_IMPORTED_MODULE_25__ = __webpack_require__(/*! ../SettingsManager/SettingsManagerPlugin */ "./lib/Extensions/SettingsManager/SettingsManagerPlugin.js");
|
|
1985
2025
|
/* harmony import */ var _SettingsManager_profiler_ProfilerPage__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ../SettingsManager/profiler/ProfilerPage */ "./lib/Extensions/SettingsManager/profiler/ProfilerPage.js");
|
|
1986
|
-
/* harmony import */ var
|
|
1987
|
-
/* harmony import */ var
|
|
2026
|
+
/* harmony import */ var _CTACarousel__WEBPACK_IMPORTED_MODULE_29__ = __webpack_require__(/*! ./CTACarousel */ "./lib/Extensions/AiChat/CTACarousel.js");
|
|
2027
|
+
/* harmony import */ var _CodeDiffDisplay__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(/*! ./CodeDiffDisplay */ "./lib/Extensions/AiChat/CodeDiffDisplay.js");
|
|
1988
2028
|
/* harmony import */ var _FirstMessage__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./FirstMessage */ "./lib/Extensions/AiChat/FirstMessage.js");
|
|
1989
|
-
/* harmony import */ var
|
|
1990
|
-
/* harmony import */ var
|
|
1991
|
-
/* harmony import */ var
|
|
1992
|
-
/* harmony import */ var
|
|
2029
|
+
/* harmony import */ var _ChatMessage_ChatInput__WEBPACK_IMPORTED_MODULE_38__ = __webpack_require__(/*! ./ChatMessage/ChatInput */ "./lib/Extensions/AiChat/ChatMessage/ChatInput.js");
|
|
2030
|
+
/* harmony import */ var _ChatMessage_ChatMessage__WEBPACK_IMPORTED_MODULE_31__ = __webpack_require__(/*! ./ChatMessage/ChatMessage */ "./lib/Extensions/AiChat/ChatMessage/ChatMessage.js");
|
|
2031
|
+
/* harmony import */ var _ChatMessage_RevertQuestionnaire__WEBPACK_IMPORTED_MODULE_35__ = __webpack_require__(/*! ./ChatMessage/RevertQuestionnaire */ "./lib/Extensions/AiChat/ChatMessage/RevertQuestionnaire.js");
|
|
2032
|
+
/* harmony import */ var _ChatMessage_ScrollableSuggestions__WEBPACK_IMPORTED_MODULE_36__ = __webpack_require__(/*! ./ChatMessage/ScrollableSuggestions */ "./lib/Extensions/AiChat/ChatMessage/ScrollableSuggestions.js");
|
|
1993
2033
|
/* harmony import */ var _ChatHistoryManager__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./ChatHistoryManager */ "./lib/Extensions/AiChat/ChatHistoryManager.js");
|
|
1994
2034
|
/* harmony import */ var _style_button_css__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../../style/button.css */ "./style/button.css");
|
|
1995
2035
|
/* harmony import */ var _style_ChatTaskpane_css__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../../style/ChatTaskpane.css */ "./style/ChatTaskpane.css");
|
|
1996
2036
|
/* harmony import */ var _style_TextButton_css__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../../style/TextButton.css */ "./style/TextButton.css");
|
|
2037
|
+
/* harmony import */ var _components_LoadingDots__WEBPACK_IMPORTED_MODULE_32__ = __webpack_require__(/*! ../../components/LoadingDots */ "./lib/components/LoadingDots.js");
|
|
1997
2038
|
/*
|
|
1998
2039
|
* Copyright (c) Saga Inc.
|
|
1999
2040
|
* Distributed under the terms of the GNU Affero General Public License v3.0 License.
|
|
@@ -2015,7 +2056,6 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
2015
2056
|
|
|
2016
2057
|
|
|
2017
2058
|
|
|
2018
|
-
|
|
2019
2059
|
// Internal imports - Icons
|
|
2020
2060
|
|
|
2021
2061
|
|
|
@@ -2033,6 +2073,7 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
2033
2073
|
|
|
2034
2074
|
|
|
2035
2075
|
|
|
2076
|
+
|
|
2036
2077
|
// Internal imports - Chat components
|
|
2037
2078
|
|
|
2038
2079
|
|
|
@@ -2046,12 +2087,14 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
2046
2087
|
|
|
2047
2088
|
|
|
2048
2089
|
|
|
2090
|
+
|
|
2049
2091
|
const AGENT_EXECUTION_DEPTH_LIMIT = 20;
|
|
2050
2092
|
const getDefaultChatHistoryManager = (notebookTracker, contextManager) => {
|
|
2051
2093
|
const chatHistoryManager = new _ChatHistoryManager__WEBPACK_IMPORTED_MODULE_7__.ChatHistoryManager(contextManager, notebookTracker);
|
|
2052
2094
|
return chatHistoryManager;
|
|
2053
2095
|
};
|
|
2054
2096
|
const ChatTaskpane = ({ notebookTracker, renderMimeRegistry, contextManager, app, operatingSystem, websocketClient, }) => {
|
|
2097
|
+
var _a;
|
|
2055
2098
|
const [chatHistoryManager, setChatHistoryManager] = (0,react__WEBPACK_IMPORTED_MODULE_1__.useState)(() => getDefaultChatHistoryManager(notebookTracker, contextManager));
|
|
2056
2099
|
const chatHistoryManagerRef = (0,react__WEBPACK_IMPORTED_MODULE_1__.useRef)(chatHistoryManager);
|
|
2057
2100
|
const [loadingAIResponse, setLoadingAIResponse] = (0,react__WEBPACK_IMPORTED_MODULE_1__.useState)(false);
|
|
@@ -2097,11 +2140,14 @@ const ChatTaskpane = ({ notebookTracker, renderMimeRegistry, contextManager, app
|
|
|
2097
2140
|
3. idle: the agent is idle
|
|
2098
2141
|
*/
|
|
2099
2142
|
const [agentExecutionStatus, setAgentExecutionStatus] = (0,react__WEBPACK_IMPORTED_MODULE_1__.useState)('idle');
|
|
2143
|
+
const agentTargetNotebookPanelRef = (0,react__WEBPACK_IMPORTED_MODULE_1__.useRef)(null);
|
|
2100
2144
|
// We use a ref to always access the most up-to-date value during a function's execution. Refs immediately reflect changes,
|
|
2101
2145
|
// unlike state variables, which are captured at the beginning of a function and may not reflect updates made during execution.
|
|
2102
2146
|
const shouldContinueAgentExecution = (0,react__WEBPACK_IMPORTED_MODULE_1__.useRef)(true);
|
|
2103
2147
|
const streamingContentRef = (0,react__WEBPACK_IMPORTED_MODULE_1__.useRef)('');
|
|
2104
2148
|
const streamHandlerRef = (0,react__WEBPACK_IMPORTED_MODULE_1__.useRef)(null);
|
|
2149
|
+
// Track active requests for cancellation
|
|
2150
|
+
const activeRequestControllerRef = (0,react__WEBPACK_IMPORTED_MODULE_1__.useRef)(null);
|
|
2105
2151
|
// State for managing next steps from responses
|
|
2106
2152
|
// If the user hides the next steps, we keep them hidden until they re-open them
|
|
2107
2153
|
const [nextSteps, setNextSteps] = (0,react__WEBPACK_IMPORTED_MODULE_1__.useState)([]);
|
|
@@ -2381,13 +2427,16 @@ const ChatTaskpane = ({ notebookTracker, renderMimeRegistry, contextManager, app
|
|
|
2381
2427
|
await _sendMessageAndSaveResponse(smartDebugCompletionRequest, newChatHistoryManager);
|
|
2382
2428
|
};
|
|
2383
2429
|
const sendAgentSmartDebugMessage = async (errorMessage) => {
|
|
2430
|
+
if (agentTargetNotebookPanelRef.current === null) {
|
|
2431
|
+
return;
|
|
2432
|
+
}
|
|
2384
2433
|
// Step 0: reset the state for a new message
|
|
2385
2434
|
resetForNewMessage();
|
|
2386
2435
|
// Enable follow mode when sending agent debug message (same behavior as other modes)
|
|
2387
2436
|
setAutoScrollFollowMode(true);
|
|
2388
2437
|
// Step 1: Create message metadata
|
|
2389
2438
|
const newChatHistoryManager = getDuplicateChatHistoryManager();
|
|
2390
|
-
const agentSmartDebugMessage = newChatHistoryManager.addAgentSmartDebugMessage(activeThreadIdRef.current, errorMessage);
|
|
2439
|
+
const agentSmartDebugMessage = newChatHistoryManager.addAgentSmartDebugMessage(activeThreadIdRef.current, errorMessage, agentTargetNotebookPanelRef.current);
|
|
2391
2440
|
setChatHistoryManager(newChatHistoryManager);
|
|
2392
2441
|
setLoadingAIResponse(true);
|
|
2393
2442
|
// Step 2: Send the message to the AI
|
|
@@ -2422,17 +2471,21 @@ const ChatTaskpane = ({ notebookTracker, renderMimeRegistry, contextManager, app
|
|
|
2422
2471
|
const sendAgentExecutionMessage = async (input, messageIndex, sendCellIDOutput = undefined, additionalContext) => {
|
|
2423
2472
|
// Step 0: reset the state for a new message
|
|
2424
2473
|
resetForNewMessage();
|
|
2474
|
+
const agentTargetNotebookPanel = agentTargetNotebookPanelRef.current;
|
|
2475
|
+
if (agentTargetNotebookPanel === null) {
|
|
2476
|
+
return;
|
|
2477
|
+
}
|
|
2425
2478
|
// Step 1: Add the user's message to the chat history
|
|
2426
2479
|
const newChatHistoryManager = getDuplicateChatHistoryManager();
|
|
2427
2480
|
if (messageIndex !== undefined) {
|
|
2428
2481
|
// Drop all of the messages starting at the message index
|
|
2429
2482
|
newChatHistoryManager.dropMessagesStartingAtIndex(messageIndex);
|
|
2430
2483
|
}
|
|
2431
|
-
const agentExecutionMetadata = newChatHistoryManager.addAgentExecutionMessage(activeThreadIdRef.current, input, additionalContext);
|
|
2484
|
+
const agentExecutionMetadata = newChatHistoryManager.addAgentExecutionMessage(activeThreadIdRef.current, agentTargetNotebookPanel, input, additionalContext);
|
|
2432
2485
|
if (messageIndex !== undefined) {
|
|
2433
2486
|
agentExecutionMetadata.index = messageIndex;
|
|
2434
2487
|
}
|
|
2435
|
-
agentExecutionMetadata.base64EncodedActiveCellOutput = await (0,_utils__WEBPACK_IMPORTED_MODULE_12__.
|
|
2488
|
+
agentExecutionMetadata.base64EncodedActiveCellOutput = await (0,_utils__WEBPACK_IMPORTED_MODULE_12__.getBase64EncodedCellOutputInNotebook)(agentTargetNotebookPanel, sendCellIDOutput);
|
|
2436
2489
|
setChatHistoryManager(newChatHistoryManager);
|
|
2437
2490
|
setLoadingAIResponse(true);
|
|
2438
2491
|
// Step 2: Send the message to the AI
|
|
@@ -2468,7 +2521,7 @@ const ChatTaskpane = ({ notebookTracker, renderMimeRegistry, contextManager, app
|
|
|
2468
2521
|
// Add the active cell output to the metadata afterwards setting the chatHistoryManager so that
|
|
2469
2522
|
// we don't have to wait on turning the output into a base64 image before we can add the user's message
|
|
2470
2523
|
// to the chat.
|
|
2471
|
-
const activeCellOutput = await (0,
|
|
2524
|
+
const activeCellOutput = await (0,_utils_cellOutput__WEBPACK_IMPORTED_MODULE_13__.getActiveCellOutput)(notebookTracker);
|
|
2472
2525
|
if (activeCellOutput !== undefined) {
|
|
2473
2526
|
chatMessageMetadata.base64EncodedActiveCellOutput = activeCellOutput;
|
|
2474
2527
|
}
|
|
@@ -2492,6 +2545,9 @@ const ChatTaskpane = ({ notebookTracker, renderMimeRegistry, contextManager, app
|
|
|
2492
2545
|
};
|
|
2493
2546
|
const _sendMessageAndSaveResponse = async (completionRequest, newChatHistoryManager) => {
|
|
2494
2547
|
var _a, _b, _c, _d;
|
|
2548
|
+
// Create AbortController for this request
|
|
2549
|
+
const abortController = new AbortController();
|
|
2550
|
+
activeRequestControllerRef.current = abortController;
|
|
2495
2551
|
// Capture the completion request for debugging
|
|
2496
2552
|
(0,_SettingsManager_profiler_ProfilerPage__WEBPACK_IMPORTED_MODULE_14__.captureCompletionRequest)(completionRequest);
|
|
2497
2553
|
if (completionRequest.stream) {
|
|
@@ -2560,7 +2616,15 @@ const ChatTaskpane = ({ notebookTracker, renderMimeRegistry, contextManager, app
|
|
|
2560
2616
|
// NON-STREAMING RESPONSES
|
|
2561
2617
|
// Once we move everything to streaming, we can remove everything in this else block
|
|
2562
2618
|
try {
|
|
2619
|
+
// Check if request was aborted before making the call
|
|
2620
|
+
if (abortController.signal.aborted) {
|
|
2621
|
+
throw new Error('Request aborted');
|
|
2622
|
+
}
|
|
2563
2623
|
const aiResponse = await websocketClient.sendMessage(completionRequest);
|
|
2624
|
+
// Check if request was aborted after receiving response
|
|
2625
|
+
if (abortController.signal.aborted) {
|
|
2626
|
+
throw new Error('Request aborted');
|
|
2627
|
+
}
|
|
2564
2628
|
if (aiResponse.error) {
|
|
2565
2629
|
console.group('Error calling OpenAI API:');
|
|
2566
2630
|
console.error('Title:', aiResponse.error.title);
|
|
@@ -2595,6 +2659,11 @@ const ChatTaskpane = ({ notebookTracker, renderMimeRegistry, contextManager, app
|
|
|
2595
2659
|
}
|
|
2596
2660
|
}
|
|
2597
2661
|
catch (error) {
|
|
2662
|
+
// Check if this was an abort error
|
|
2663
|
+
if (error.message === 'Request aborted') {
|
|
2664
|
+
// Don't show error message for aborted requests
|
|
2665
|
+
return false;
|
|
2666
|
+
}
|
|
2598
2667
|
addAIMessageFromResponseAndUpdateState(error.title ? error.title : `${error}`, 'chat', newChatHistoryManager, false);
|
|
2599
2668
|
addAIMessageFromResponseAndUpdateState(error.hint ? error.hint : `${error}`, completionRequest.metadata.promptType, newChatHistoryManager, true);
|
|
2600
2669
|
}
|
|
@@ -2604,6 +2673,10 @@ const ChatTaskpane = ({ notebookTracker, renderMimeRegistry, contextManager, app
|
|
|
2604
2673
|
setLoadingAIResponse(false);
|
|
2605
2674
|
}
|
|
2606
2675
|
}
|
|
2676
|
+
// Clean up AbortController
|
|
2677
|
+
if (activeRequestControllerRef.current === abortController) {
|
|
2678
|
+
activeRequestControllerRef.current = null;
|
|
2679
|
+
}
|
|
2607
2680
|
return true;
|
|
2608
2681
|
};
|
|
2609
2682
|
const addAIMessageFromResponseAndUpdateState = (messageContent, promptType, chatHistoryManager, mitoAIConnectionError = false, mitoAIConnectionErrorType = null) => {
|
|
@@ -2614,21 +2687,36 @@ const ChatTaskpane = ({ notebookTracker, renderMimeRegistry, contextManager, app
|
|
|
2614
2687
|
chatHistoryManager.addAIMessageFromResponse(messageContent, promptType, mitoAIConnectionError, mitoAIConnectionErrorType);
|
|
2615
2688
|
setChatHistoryManager(chatHistoryManager);
|
|
2616
2689
|
};
|
|
2617
|
-
const markAgentForStopping = () => {
|
|
2618
|
-
// Signal that the agent should stop
|
|
2619
|
-
shouldContinueAgentExecution.current = false;
|
|
2620
|
-
// Update UI to show stopping state
|
|
2621
|
-
setAgentExecutionStatus('stopping');
|
|
2622
|
-
};
|
|
2623
|
-
const finalizeAgentStop = () => {
|
|
2624
|
-
// Notify user that agent has been stopped
|
|
2690
|
+
const markAgentForStopping = async (reason = 'naturalConclusion') => {
|
|
2691
|
+
// Signal that the agent should stop immediately
|
|
2625
2692
|
shouldContinueAgentExecution.current = false;
|
|
2626
|
-
|
|
2627
|
-
addAIMessageFromResponseAndUpdateState("Agent execution stopped. You can continue the conversation or start a new one.", 'chat', newChatHistoryManager);
|
|
2628
|
-
// Reset agent to idle state
|
|
2693
|
+
// Update state/UI
|
|
2629
2694
|
setAgentExecutionStatus('idle');
|
|
2695
|
+
setLoadingAIResponse(false);
|
|
2696
|
+
if (reason === 'userStop') {
|
|
2697
|
+
// Immediately abort any ongoing requests
|
|
2698
|
+
if (activeRequestControllerRef.current) {
|
|
2699
|
+
activeRequestControllerRef.current.abort();
|
|
2700
|
+
activeRequestControllerRef.current = null;
|
|
2701
|
+
}
|
|
2702
|
+
// Add feedback message based on reason
|
|
2703
|
+
const newChatHistoryManager = getDuplicateChatHistoryManager();
|
|
2704
|
+
addAIMessageFromResponseAndUpdateState("Agent stopped by user.", 'chat', newChatHistoryManager);
|
|
2705
|
+
// Send stop message to backend
|
|
2706
|
+
await websocketClient.sendMessage({
|
|
2707
|
+
type: "stop_agent",
|
|
2708
|
+
message_id: _lumino_coreutils__WEBPACK_IMPORTED_MODULE_3__.UUID.uuid4(),
|
|
2709
|
+
metadata: {
|
|
2710
|
+
promptType: "stop_agent",
|
|
2711
|
+
threadId: activeThreadIdRef.current
|
|
2712
|
+
},
|
|
2713
|
+
stream: false
|
|
2714
|
+
});
|
|
2715
|
+
}
|
|
2716
|
+
return;
|
|
2630
2717
|
};
|
|
2631
2718
|
const startAgentExecution = async (input, messageIndex, additionalContext) => {
|
|
2719
|
+
agentTargetNotebookPanelRef.current = notebookTracker.currentWidget;
|
|
2632
2720
|
await (0,_utils_checkpoint__WEBPACK_IMPORTED_MODULE_15__.createCheckpoint)(app, setHasCheckpoint);
|
|
2633
2721
|
setAgentExecutionStatus('working');
|
|
2634
2722
|
// Enable follow mode when user starts agent execution
|
|
@@ -2642,7 +2730,7 @@ const ChatTaskpane = ({ notebookTracker, renderMimeRegistry, contextManager, app
|
|
|
2642
2730
|
while (!isAgentFinished && agentExecutionDepth <= AGENT_EXECUTION_DEPTH_LIMIT) {
|
|
2643
2731
|
// Check if we should continue execution
|
|
2644
2732
|
if (!shouldContinueAgentExecution.current) {
|
|
2645
|
-
|
|
2733
|
+
await markAgentForStopping();
|
|
2646
2734
|
break;
|
|
2647
2735
|
}
|
|
2648
2736
|
// Only the first message sent to the Agent should contain the user's input.
|
|
@@ -2667,31 +2755,40 @@ const ChatTaskpane = ({ notebookTracker, renderMimeRegistry, contextManager, app
|
|
|
2667
2755
|
if (!securityCheck.safe) {
|
|
2668
2756
|
console.error('Security Warning:', securityCheck.reason);
|
|
2669
2757
|
addAIMessageFromResponseAndUpdateState(`I cannot execute this code without your approval because this code did not pass my security checks. ${securityCheck.reason}. For your safety, I am stopping execution of this plan.`, 'agent:execution', chatHistoryManager);
|
|
2670
|
-
|
|
2758
|
+
await markAgentForStopping();
|
|
2671
2759
|
break;
|
|
2672
2760
|
}
|
|
2673
2761
|
}
|
|
2674
2762
|
}
|
|
2675
2763
|
const agentResponse = aiDisplayOptimizedChatItem === null || aiDisplayOptimizedChatItem === void 0 ? void 0 : aiDisplayOptimizedChatItem.agentResponse;
|
|
2764
|
+
if (agentTargetNotebookPanelRef.current === null) {
|
|
2765
|
+
// If the agent target notebook panel is not set, we don't know where to run the code so we stop
|
|
2766
|
+
await markAgentForStopping();
|
|
2767
|
+
isAgentFinished = true;
|
|
2768
|
+
break;
|
|
2769
|
+
}
|
|
2676
2770
|
if (agentResponse === undefined) {
|
|
2677
2771
|
// If the agent response is undefined, we need to send a message to the agent
|
|
2772
|
+
await markAgentForStopping();
|
|
2678
2773
|
isAgentFinished = true;
|
|
2679
2774
|
break;
|
|
2680
2775
|
}
|
|
2681
2776
|
if (agentResponse.type === 'finished_task') {
|
|
2682
2777
|
// If the agent told us that it is finished, we can stop
|
|
2778
|
+
await markAgentForStopping();
|
|
2683
2779
|
isAgentFinished = true;
|
|
2684
2780
|
break;
|
|
2685
2781
|
}
|
|
2686
2782
|
if (agentResponse.type === 'cell_update' && (agentResponse.cell_update === undefined || agentResponse.cell_update === null)) {
|
|
2687
2783
|
// If the agent's response is not formatted correctly, stop. This is for typechecking mostly
|
|
2784
|
+
await markAgentForStopping();
|
|
2688
2785
|
isAgentFinished = true;
|
|
2689
2786
|
break;
|
|
2690
2787
|
}
|
|
2691
2788
|
if (agentResponse.type === 'cell_update' && agentResponse.cell_update) {
|
|
2692
2789
|
// Run the code and handle any errors
|
|
2693
|
-
await (0,_utils_agentActions__WEBPACK_IMPORTED_MODULE_18__.acceptAndRunCellUpdate)(agentResponse.cell_update,
|
|
2694
|
-
const status = await (0,_utils_agentActions__WEBPACK_IMPORTED_MODULE_18__.retryIfExecutionError)(
|
|
2790
|
+
await (0,_utils_agentActions__WEBPACK_IMPORTED_MODULE_18__.acceptAndRunCellUpdate)(agentResponse.cell_update, agentTargetNotebookPanelRef.current);
|
|
2791
|
+
const status = await (0,_utils_agentActions__WEBPACK_IMPORTED_MODULE_18__.retryIfExecutionError)(agentTargetNotebookPanelRef.current, app, sendAgentSmartDebugMessage, shouldContinueAgentExecution, markAgentForStopping, chatHistoryManagerRef);
|
|
2695
2792
|
if (status === 'interupted') {
|
|
2696
2793
|
break;
|
|
2697
2794
|
}
|
|
@@ -2711,12 +2808,12 @@ const ChatTaskpane = ({ notebookTracker, renderMimeRegistry, contextManager, app
|
|
|
2711
2808
|
sendCellIDOutput = agentResponse.get_cell_output_cell_id;
|
|
2712
2809
|
}
|
|
2713
2810
|
if (agentResponse.type === 'run_all_cells') {
|
|
2714
|
-
const result = await (0,_utils_agentActions__WEBPACK_IMPORTED_MODULE_18__.runAllCells)(app,
|
|
2811
|
+
const result = await (0,_utils_agentActions__WEBPACK_IMPORTED_MODULE_18__.runAllCells)(app, agentTargetNotebookPanelRef.current);
|
|
2715
2812
|
// If run_all_cells resulted in an error, handle it through the error fixup process
|
|
2716
2813
|
if (!result.success && result.errorMessage && result.errorCellId) {
|
|
2717
2814
|
// Set the error cell as active so the error retry logic can work with it
|
|
2718
|
-
(0,
|
|
2719
|
-
const status = await (0,_utils_agentActions__WEBPACK_IMPORTED_MODULE_18__.retryIfExecutionError)(
|
|
2815
|
+
(0,_utils_notebook__WEBPACK_IMPORTED_MODULE_19__.setActiveCellByIDInNotebookPanel)(agentTargetNotebookPanelRef.current, result.errorCellId);
|
|
2816
|
+
const status = await (0,_utils_agentActions__WEBPACK_IMPORTED_MODULE_18__.retryIfExecutionError)(agentTargetNotebookPanelRef.current, app, sendAgentSmartDebugMessage, shouldContinueAgentExecution, markAgentForStopping, chatHistoryManagerRef);
|
|
2720
2817
|
if (status === 'interupted') {
|
|
2721
2818
|
break;
|
|
2722
2819
|
}
|
|
@@ -2730,39 +2827,40 @@ const ChatTaskpane = ({ notebookTracker, renderMimeRegistry, contextManager, app
|
|
|
2730
2827
|
if (agentExecutionDepth > AGENT_EXECUTION_DEPTH_LIMIT) {
|
|
2731
2828
|
addAIMessageFromResponseAndUpdateState("Since I've been working for a while now, give my work a review and then tell me how to continue.", 'agent:execution', chatHistoryManager);
|
|
2732
2829
|
}
|
|
2733
|
-
|
|
2830
|
+
// Use markAgentForStopping for natural conclusion to ensure consistent cleanup
|
|
2831
|
+
await markAgentForStopping();
|
|
2734
2832
|
};
|
|
2735
2833
|
const updateCodeDiffStripes = (aiMessage, updateCellID) => {
|
|
2736
2834
|
if (!aiMessage) {
|
|
2737
2835
|
return;
|
|
2738
2836
|
}
|
|
2739
|
-
const updateCellCode = (0,
|
|
2837
|
+
const updateCellCode = (0,_utils_notebook__WEBPACK_IMPORTED_MODULE_19__.getCellCodeByID)(notebookTracker, updateCellID);
|
|
2740
2838
|
if (updateCellID === undefined || updateCellCode === undefined) {
|
|
2741
2839
|
return;
|
|
2742
2840
|
}
|
|
2743
2841
|
// Extract the code from the AI's message and then calculate the code diffs
|
|
2744
2842
|
const aiGeneratedCode = (0,_utils_strings__WEBPACK_IMPORTED_MODULE_16__.getCodeBlockFromMessage)(aiMessage);
|
|
2745
2843
|
const aiGeneratedCodeCleaned = (0,_utils_strings__WEBPACK_IMPORTED_MODULE_16__.removeMarkdownCodeFormatting)(aiGeneratedCode || '');
|
|
2746
|
-
const { unifiedCodeString, unifiedDiffs } = (0,
|
|
2844
|
+
const { unifiedCodeString, unifiedDiffs } = (0,_utils_codeDiff__WEBPACK_IMPORTED_MODULE_20__.getCodeDiffsAndUnifiedCodeString)(updateCellCode, aiGeneratedCodeCleaned);
|
|
2747
2845
|
// Store the code cell ID where we write the code diffs so that we can
|
|
2748
2846
|
// accept or reject the code diffs to the correct cell
|
|
2749
2847
|
cellStateBeforeDiff.current = { codeCellID: updateCellID, code: updateCellCode };
|
|
2750
2848
|
// Temporarily write the unified code string to the active cell so we can display
|
|
2751
2849
|
// the code diffs to the user
|
|
2752
|
-
(0,
|
|
2850
|
+
(0,_utils_notebook__WEBPACK_IMPORTED_MODULE_19__.writeCodeToCellByID)(notebookTracker, unifiedCodeString, updateCellID);
|
|
2753
2851
|
updateCodeCellsExtensions(unifiedDiffs);
|
|
2754
2852
|
// Briefly highlight the code cell to draw the user's attention to it
|
|
2755
|
-
(0,
|
|
2853
|
+
(0,_utils_notebook__WEBPACK_IMPORTED_MODULE_19__.highlightCodeCell)(notebookTracker, updateCellID);
|
|
2756
2854
|
};
|
|
2757
2855
|
const displayOptimizedChatHistory = chatHistoryManager.getDisplayOptimizedHistory();
|
|
2758
2856
|
const previewAICodeToActiveCell = () => {
|
|
2759
2857
|
setCodeReviewStatus('codeCellPreview');
|
|
2760
|
-
const activeCellID = (0,
|
|
2858
|
+
const activeCellID = (0,_utils_notebook__WEBPACK_IMPORTED_MODULE_19__.getActiveCellID)(notebookTracker);
|
|
2761
2859
|
const lastAIDisplayMessage = chatHistoryManagerRef.current.getLastAIDisplayOptimizedChatItem();
|
|
2762
2860
|
if (activeCellID === undefined || lastAIDisplayMessage === undefined) {
|
|
2763
2861
|
return;
|
|
2764
2862
|
}
|
|
2765
|
-
(0,
|
|
2863
|
+
(0,_utils_notebook__WEBPACK_IMPORTED_MODULE_19__.scrollToCell)(notebookTracker.currentWidget, activeCellID, undefined, 'end');
|
|
2766
2864
|
updateCodeDiffStripes(lastAIDisplayMessage.message, activeCellID);
|
|
2767
2865
|
updateCellToolbarButtons();
|
|
2768
2866
|
};
|
|
@@ -2781,10 +2879,10 @@ const ChatTaskpane = ({ notebookTracker, renderMimeRegistry, contextManager, app
|
|
|
2781
2879
|
// Write to the cell that has the code diffs
|
|
2782
2880
|
writeCodeToCellAndTurnOffDiffs(aiGeneratedCode, targetCellID);
|
|
2783
2881
|
// Focus on the active cell after the code is written
|
|
2784
|
-
const targetCell = (0,
|
|
2882
|
+
const targetCell = (0,_utils_notebook__WEBPACK_IMPORTED_MODULE_19__.getCellByID)(notebookTracker, targetCellID);
|
|
2785
2883
|
if (targetCell) {
|
|
2786
2884
|
// Make the target cell the active cell
|
|
2787
|
-
(0,
|
|
2885
|
+
(0,_utils_notebook__WEBPACK_IMPORTED_MODULE_19__.setActiveCellByID)(notebookTracker, targetCellID);
|
|
2788
2886
|
// Focus on the active cell
|
|
2789
2887
|
targetCell.activate();
|
|
2790
2888
|
}
|
|
@@ -2810,7 +2908,7 @@ const ChatTaskpane = ({ notebookTracker, renderMimeRegistry, contextManager, app
|
|
|
2810
2908
|
updateCodeCellsExtensions(undefined);
|
|
2811
2909
|
cellStateBeforeDiff.current = undefined;
|
|
2812
2910
|
if (codeCellID !== undefined) {
|
|
2813
|
-
(0,
|
|
2911
|
+
(0,_utils_notebook__WEBPACK_IMPORTED_MODULE_19__.writeCodeToCellByID)(notebookTracker, code, codeCellID);
|
|
2814
2912
|
updateCellToolbarButtons();
|
|
2815
2913
|
}
|
|
2816
2914
|
};
|
|
@@ -2821,17 +2919,17 @@ const ChatTaskpane = ({ notebookTracker, renderMimeRegistry, contextManager, app
|
|
|
2821
2919
|
the first time we create the chat. Registering the command when it is already created causes
|
|
2822
2920
|
errors.
|
|
2823
2921
|
*/
|
|
2824
|
-
app.commands.addCommand(
|
|
2922
|
+
app.commands.addCommand(_commands__WEBPACK_IMPORTED_MODULE_21__.COMMAND_MITO_AI_PREVIEW_LATEST_CODE, {
|
|
2825
2923
|
execute: () => {
|
|
2826
2924
|
previewAICodeToActiveCell();
|
|
2827
2925
|
}
|
|
2828
2926
|
});
|
|
2829
|
-
app.commands.addCommand(
|
|
2927
|
+
app.commands.addCommand(_commands__WEBPACK_IMPORTED_MODULE_21__.COMMAND_MITO_AI_APPLY_LATEST_CODE, {
|
|
2830
2928
|
execute: () => {
|
|
2831
2929
|
acceptAICode();
|
|
2832
2930
|
}
|
|
2833
2931
|
});
|
|
2834
|
-
app.commands.addCommand(
|
|
2932
|
+
app.commands.addCommand(_commands__WEBPACK_IMPORTED_MODULE_21__.COMMAND_MITO_AI_REJECT_LATEST_CODE, {
|
|
2835
2933
|
execute: () => {
|
|
2836
2934
|
rejectAICode();
|
|
2837
2935
|
}
|
|
@@ -2840,23 +2938,21 @@ const ChatTaskpane = ({ notebookTracker, renderMimeRegistry, contextManager, app
|
|
|
2840
2938
|
Add a new command to the JupyterLab command registry that sends the current chat message.
|
|
2841
2939
|
We use this to automatically send the message when the user adds an error to the chat.
|
|
2842
2940
|
*/
|
|
2843
|
-
app.commands.addCommand(
|
|
2941
|
+
app.commands.addCommand(_commands__WEBPACK_IMPORTED_MODULE_21__.COMMAND_MITO_AI_SEND_DEBUG_ERROR_MESSAGE, {
|
|
2844
2942
|
execute: async (args) => {
|
|
2845
2943
|
if (args === null || args === void 0 ? void 0 : args.input) {
|
|
2846
2944
|
await sendSmartDebugMessage(args.input.toString());
|
|
2847
2945
|
}
|
|
2848
2946
|
}
|
|
2849
2947
|
});
|
|
2850
|
-
app.commands.addCommand(
|
|
2948
|
+
app.commands.addCommand(_commands__WEBPACK_IMPORTED_MODULE_21__.COMMAND_MITO_AI_SEND_EXPLAIN_CODE_MESSAGE, {
|
|
2851
2949
|
execute: async () => {
|
|
2852
2950
|
await sendExplainCodeMessage();
|
|
2853
2951
|
}
|
|
2854
2952
|
});
|
|
2855
|
-
app.commands.addCommand(
|
|
2953
|
+
app.commands.addCommand(_commands__WEBPACK_IMPORTED_MODULE_21__.COMMAND_MITO_AI_SEND_AGENT_MESSAGE, {
|
|
2856
2954
|
execute: async (args) => {
|
|
2857
2955
|
if (args === null || args === void 0 ? void 0 : args.input) {
|
|
2858
|
-
// Make sure we're in agent mode
|
|
2859
|
-
console.log('Setting agent mode to true');
|
|
2860
2956
|
// If its not already in agent mode, start a new chat in agent mode
|
|
2861
2957
|
if (!agentModeEnabledRef.current) {
|
|
2862
2958
|
await startNewChat();
|
|
@@ -2871,7 +2967,7 @@ const ChatTaskpane = ({ notebookTracker, renderMimeRegistry, contextManager, app
|
|
|
2871
2967
|
/*
|
|
2872
2968
|
Register the code cell toolbar buttons for accepting and rejecting code.
|
|
2873
2969
|
*/
|
|
2874
|
-
app.commands.addCommand(
|
|
2970
|
+
app.commands.addCommand(_commands__WEBPACK_IMPORTED_MODULE_21__.COMMAND_MITO_AI_CELL_TOOLBAR_ACCEPT_CODE, {
|
|
2875
2971
|
label: `Accept ${operatingSystem === 'mac' ? '⌘Y' : 'Ctrl+Y'}`,
|
|
2876
2972
|
className: 'text-button-mito-ai button-base button-green',
|
|
2877
2973
|
caption: 'Accept Code',
|
|
@@ -2889,7 +2985,7 @@ const ChatTaskpane = ({ notebookTracker, renderMimeRegistry, contextManager, app
|
|
|
2889
2985
|
}
|
|
2890
2986
|
}
|
|
2891
2987
|
});
|
|
2892
|
-
app.commands.addCommand(
|
|
2988
|
+
app.commands.addCommand(_commands__WEBPACK_IMPORTED_MODULE_21__.COMMAND_MITO_AI_CELL_TOOLBAR_REJECT_CODE, {
|
|
2893
2989
|
label: `Reject ${operatingSystem === 'mac' ? '⌘U' : 'Ctrl+U'}`,
|
|
2894
2990
|
className: 'text-button-mito-ai button-base button-red',
|
|
2895
2991
|
caption: 'Reject Code',
|
|
@@ -2910,13 +3006,13 @@ const ChatTaskpane = ({ notebookTracker, renderMimeRegistry, contextManager, app
|
|
|
2910
3006
|
// Register keyboard shortcuts
|
|
2911
3007
|
const accelYDisposable = app.commands.addKeyBinding({
|
|
2912
3008
|
command: codeReviewStatus === 'chatPreview' ?
|
|
2913
|
-
|
|
2914
|
-
|
|
3009
|
+
_commands__WEBPACK_IMPORTED_MODULE_21__.COMMAND_MITO_AI_PREVIEW_LATEST_CODE :
|
|
3010
|
+
_commands__WEBPACK_IMPORTED_MODULE_21__.COMMAND_MITO_AI_APPLY_LATEST_CODE,
|
|
2915
3011
|
keys: ['Accel Y'],
|
|
2916
3012
|
selector: 'body',
|
|
2917
3013
|
});
|
|
2918
3014
|
const accelDDisposable = app.commands.addKeyBinding({
|
|
2919
|
-
command:
|
|
3015
|
+
command: _commands__WEBPACK_IMPORTED_MODULE_21__.COMMAND_MITO_AI_REJECT_LATEST_CODE,
|
|
2920
3016
|
keys: ['Accel U'],
|
|
2921
3017
|
selector: 'body',
|
|
2922
3018
|
preventDefault: true,
|
|
@@ -2933,8 +3029,8 @@ const ChatTaskpane = ({ notebookTracker, renderMimeRegistry, contextManager, app
|
|
|
2933
3029
|
// Without this, the user needs to take some action, like switching to a different cell
|
|
2934
3030
|
// and then switching back in order for the Jupyter to re-evaluate if it should
|
|
2935
3031
|
// show the toolbar buttons.
|
|
2936
|
-
app.commands.notifyCommandChanged(
|
|
2937
|
-
app.commands.notifyCommandChanged(
|
|
3032
|
+
app.commands.notifyCommandChanged(_commands__WEBPACK_IMPORTED_MODULE_21__.COMMAND_MITO_AI_CELL_TOOLBAR_ACCEPT_CODE);
|
|
3033
|
+
app.commands.notifyCommandChanged(_commands__WEBPACK_IMPORTED_MODULE_21__.COMMAND_MITO_AI_CELL_TOOLBAR_REJECT_CODE);
|
|
2938
3034
|
};
|
|
2939
3035
|
const codeDiffStripesCompartments = react__WEBPACK_IMPORTED_MODULE_1___default().useRef(new Map());
|
|
2940
3036
|
// Function to update the extensions of code cells
|
|
@@ -2962,13 +3058,13 @@ const ChatTaskpane = ({ notebookTracker, renderMimeRegistry, contextManager, app
|
|
|
2962
3058
|
codeDiffStripesCompartments.current.set(cellId, compartment);
|
|
2963
3059
|
// Apply the initial configuration
|
|
2964
3060
|
editorView.dispatch({
|
|
2965
|
-
effects: _codemirror_state__WEBPACK_IMPORTED_MODULE_0__.StateEffect.appendConfig.of(compartment.of(unifiedDiffLines !== undefined && isActiveCodeCell ? (0,
|
|
3061
|
+
effects: _codemirror_state__WEBPACK_IMPORTED_MODULE_0__.StateEffect.appendConfig.of(compartment.of(unifiedDiffLines !== undefined && isActiveCodeCell ? (0,_CodeDiffDisplay__WEBPACK_IMPORTED_MODULE_22__.codeDiffStripesExtension)({ unifiedDiffLines: unifiedDiffLines }) : [])),
|
|
2966
3062
|
});
|
|
2967
3063
|
}
|
|
2968
3064
|
else {
|
|
2969
3065
|
// Reconfigure the compartment
|
|
2970
3066
|
editorView.dispatch({
|
|
2971
|
-
effects: compartment.reconfigure(unifiedDiffLines !== undefined && isActiveCodeCell ? (0,
|
|
3067
|
+
effects: compartment.reconfigure(unifiedDiffLines !== undefined && isActiveCodeCell ? (0,_CodeDiffDisplay__WEBPACK_IMPORTED_MODULE_22__.codeDiffStripesExtension)({ unifiedDiffLines: unifiedDiffLines }) : []),
|
|
2972
3068
|
});
|
|
2973
3069
|
}
|
|
2974
3070
|
}
|
|
@@ -2983,7 +3079,7 @@ const ChatTaskpane = ({ notebookTracker, renderMimeRegistry, contextManager, app
|
|
|
2983
3079
|
// In agent mode, we group consecutive error messages together.
|
|
2984
3080
|
// In chat mode, we display messages individually as they were sent
|
|
2985
3081
|
if (agentModeEnabled) {
|
|
2986
|
-
processedDisplayOptimizedChatHistory = (0,
|
|
3082
|
+
processedDisplayOptimizedChatHistory = (0,_utils_chatHistory__WEBPACK_IMPORTED_MODULE_23__.processChatHistoryForErrorGrouping)(chatHistoryManager.getDisplayOptimizedHistory());
|
|
2987
3083
|
}
|
|
2988
3084
|
else {
|
|
2989
3085
|
processedDisplayOptimizedChatHistory = chatHistoryManager.getDisplayOptimizedHistory();
|
|
@@ -2995,16 +3091,16 @@ const ChatTaskpane = ({ notebookTracker, renderMimeRegistry, contextManager, app
|
|
|
2995
3091
|
return (react__WEBPACK_IMPORTED_MODULE_1___default().createElement("div", { className: "chat-taskpane" },
|
|
2996
3092
|
react__WEBPACK_IMPORTED_MODULE_1___default().createElement("div", { className: "chat-taskpane-header" },
|
|
2997
3093
|
react__WEBPACK_IMPORTED_MODULE_1___default().createElement("div", { className: "chat-taskpane-header-left" },
|
|
2998
|
-
react__WEBPACK_IMPORTED_MODULE_1___default().createElement(
|
|
2999
|
-
void app.commands.execute(
|
|
3094
|
+
react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_components_IconButton__WEBPACK_IMPORTED_MODULE_24__["default"], { icon: react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_jupyterlab_ui_components__WEBPACK_IMPORTED_MODULE_2__.settingsIcon.react, null), title: "Mito AI Settings", onClick: () => {
|
|
3095
|
+
void app.commands.execute(_SettingsManager_SettingsManagerPlugin__WEBPACK_IMPORTED_MODULE_25__.COMMAND_MITO_AI_SETTINGS);
|
|
3000
3096
|
} })),
|
|
3001
3097
|
react__WEBPACK_IMPORTED_MODULE_1___default().createElement("div", { className: "chat-taskpane-header-right" },
|
|
3002
|
-
react__WEBPACK_IMPORTED_MODULE_1___default().createElement(
|
|
3003
|
-
react__WEBPACK_IMPORTED_MODULE_1___default().createElement(
|
|
3098
|
+
react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_components_IconButton__WEBPACK_IMPORTED_MODULE_24__["default"], { icon: react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_jupyterlab_ui_components__WEBPACK_IMPORTED_MODULE_2__.addIcon.react, null), title: "Start New Chat", onClick: async () => { await startNewChat(); } }),
|
|
3099
|
+
react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_components_DropdownMenu__WEBPACK_IMPORTED_MODULE_26__["default"], { trigger: react__WEBPACK_IMPORTED_MODULE_1___default().createElement("button", { className: "icon-button", title: "Chat Threads", onClick: fetchChatThreads },
|
|
3004
3100
|
react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_jupyterlab_ui_components__WEBPACK_IMPORTED_MODULE_2__.historyIcon.react, null)), items: chatThreads.length > 0
|
|
3005
3101
|
? chatThreads.map(thread => ({
|
|
3006
3102
|
label: thread.name,
|
|
3007
|
-
primaryIcon: activeThreadIdRef.current === thread.thread_id ?
|
|
3103
|
+
primaryIcon: activeThreadIdRef.current === thread.thread_id ? _icons__WEBPACK_IMPORTED_MODULE_27__.OpenIndicatorLabIcon.react : undefined,
|
|
3008
3104
|
onClick: () => fetchChatHistoryAndSetActiveThread(thread.thread_id),
|
|
3009
3105
|
secondaryActions: [
|
|
3010
3106
|
{
|
|
@@ -3023,26 +3119,26 @@ const ChatTaskpane = ({ notebookTracker, renderMimeRegistry, contextManager, app
|
|
|
3023
3119
|
displayOptimizedChatHistory.length === 0 &&
|
|
3024
3120
|
react__WEBPACK_IMPORTED_MODULE_1___default().createElement("div", { className: "chat-empty-message" },
|
|
3025
3121
|
react__WEBPACK_IMPORTED_MODULE_1___default().createElement("div", { style: { margin: '0 auto 8px', display: 'block', textAlign: 'center' } },
|
|
3026
|
-
react__WEBPACK_IMPORTED_MODULE_1___default().createElement(
|
|
3122
|
+
react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_icons_MitoLogo__WEBPACK_IMPORTED_MODULE_28__["default"], { width: "60", height: "30" })),
|
|
3027
3123
|
react__WEBPACK_IMPORTED_MODULE_1___default().createElement("span", { style: { display: 'block', textAlign: 'center', fontWeight: 'bold', fontSize: '20px', marginBottom: '15px' } }, "Data Copilot"),
|
|
3028
|
-
react__WEBPACK_IMPORTED_MODULE_1___default().createElement(
|
|
3124
|
+
react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_CTACarousel__WEBPACK_IMPORTED_MODULE_29__["default"], { app: app })),
|
|
3029
3125
|
processedDisplayOptimizedChatHistory.map((displayOptimizedChat, index) => {
|
|
3030
3126
|
if (isGroupedErrorMessages(displayOptimizedChat)) {
|
|
3031
|
-
return (react__WEBPACK_IMPORTED_MODULE_1___default().createElement(
|
|
3127
|
+
return (react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_components_AgentComponents_ErrorFixupToolUI__WEBPACK_IMPORTED_MODULE_30__["default"], { key: index, messages: displayOptimizedChat, renderMimeRegistry: renderMimeRegistry }));
|
|
3032
3128
|
}
|
|
3033
3129
|
else {
|
|
3034
|
-
return (react__WEBPACK_IMPORTED_MODULE_1___default().createElement(
|
|
3130
|
+
return (react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_ChatMessage_ChatMessage__WEBPACK_IMPORTED_MODULE_31__["default"], { key: index, message: displayOptimizedChat.message, promptType: displayOptimizedChat.promptType, agentResponse: displayOptimizedChat.agentResponse, codeCellID: displayOptimizedChat.codeCellID, mitoAIConnectionError: displayOptimizedChat.type === 'connection error', mitoAIConnectionErrorType: displayOptimizedChat.mitoAIConnectionErrorType || null, messageIndex: index, notebookTracker: notebookTracker, renderMimeRegistry: renderMimeRegistry, app: app, isLastAiMessage: index === lastAIMessagesIndex, isLastMessage: index === displayOptimizedChatHistory.length - 1, operatingSystem: operatingSystem, previewAICode: previewAICodeToActiveCell, acceptAICode: acceptAICode, rejectAICode: rejectAICode, onUpdateMessage: handleUpdateMessage, contextManager: contextManager, codeReviewStatus: codeReviewStatus, setNextSteps: setNextSteps, agentModeEnabled: agentModeEnabled, additionalContext: displayOptimizedChat.additionalContext }));
|
|
3035
3131
|
}
|
|
3036
3132
|
}).filter(message => message !== null),
|
|
3037
3133
|
loadingAIResponse &&
|
|
3038
3134
|
react__WEBPACK_IMPORTED_MODULE_1___default().createElement("div", { className: "chat-loading-message" },
|
|
3039
3135
|
"Thinking ",
|
|
3040
|
-
react__WEBPACK_IMPORTED_MODULE_1___default().createElement(
|
|
3136
|
+
react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_components_LoadingDots__WEBPACK_IMPORTED_MODULE_32__["default"], null)),
|
|
3041
3137
|
hasCheckpoint &&
|
|
3042
3138
|
agentModeEnabled &&
|
|
3043
3139
|
agentExecutionStatus === 'idle' &&
|
|
3044
3140
|
displayOptimizedChatHistory.length > 0 && (react__WEBPACK_IMPORTED_MODULE_1___default().createElement("div", { className: 'message message-assistant-chat' },
|
|
3045
|
-
react__WEBPACK_IMPORTED_MODULE_1___default().createElement(
|
|
3141
|
+
react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_components_TextAndIconButton__WEBPACK_IMPORTED_MODULE_33__["default"], { text: "Revert changes", icon: _icons_UndoIcon__WEBPACK_IMPORTED_MODULE_34__["default"], title: "Revert changes", onClick: () => {
|
|
3046
3142
|
void (0,_utils_checkpoint__WEBPACK_IMPORTED_MODULE_15__.restoreCheckpoint)(app, notebookTracker, setHasCheckpoint);
|
|
3047
3143
|
setDisplayedNextStepsIfAvailable(false);
|
|
3048
3144
|
setHasCheckpoint(false);
|
|
@@ -3050,9 +3146,9 @@ const ChatTaskpane = ({ notebookTracker, renderMimeRegistry, contextManager, app
|
|
|
3050
3146
|
(0,_utils_scroll__WEBPACK_IMPORTED_MODULE_11__.scrollToDiv)(chatMessagesRef);
|
|
3051
3147
|
}, variant: "gray", width: "fit-contents", iconPosition: "left" }),
|
|
3052
3148
|
react__WEBPACK_IMPORTED_MODULE_1___default().createElement("p", { className: "text-muted text-sm" }, "Undo the most recent changes made by the agent"))),
|
|
3053
|
-
showRevertQuestionnaire && (react__WEBPACK_IMPORTED_MODULE_1___default().createElement(
|
|
3149
|
+
showRevertQuestionnaire && (react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_ChatMessage_RevertQuestionnaire__WEBPACK_IMPORTED_MODULE_35__["default"], { onDestroy: () => setShowRevertQuestionnaire(false), getDuplicateChatHistoryManager: getDuplicateChatHistoryManager, setChatHistoryManager: setChatHistoryManager }))),
|
|
3054
3150
|
displayOptimizedChatHistory.length === 0 && (react__WEBPACK_IMPORTED_MODULE_1___default().createElement("div", { className: "suggestions-container" },
|
|
3055
|
-
react__WEBPACK_IMPORTED_MODULE_1___default().createElement(
|
|
3151
|
+
react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_ChatMessage_ScrollableSuggestions__WEBPACK_IMPORTED_MODULE_36__["default"], { onSelectSuggestion: (prompt) => {
|
|
3056
3152
|
if (agentModeEnabled) {
|
|
3057
3153
|
void startAgentExecution(prompt);
|
|
3058
3154
|
}
|
|
@@ -3061,15 +3157,15 @@ const ChatTaskpane = ({ notebookTracker, renderMimeRegistry, contextManager, app
|
|
|
3061
3157
|
}
|
|
3062
3158
|
} }))),
|
|
3063
3159
|
react__WEBPACK_IMPORTED_MODULE_1___default().createElement("div", { className: `connected-input-container ${nextSteps.length > 0 ? 'has-next-steps' : ''}` },
|
|
3064
|
-
nextSteps.length > 0 && (react__WEBPACK_IMPORTED_MODULE_1___default().createElement(
|
|
3065
|
-
react__WEBPACK_IMPORTED_MODULE_1___default().createElement(
|
|
3160
|
+
nextSteps.length > 0 && (react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_components_NextStepsPills__WEBPACK_IMPORTED_MODULE_37__["default"], { nextSteps: nextSteps, onSelectNextStep: agentModeEnabled ? startAgentExecution : sendChatInputMessage, displayedNextStepsIfAvailable: displayedNextStepsIfAvailable, setDisplayedNextStepsIfAvailable: setDisplayedNextStepsIfAvailable })),
|
|
3161
|
+
react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_ChatMessage_ChatInput__WEBPACK_IMPORTED_MODULE_38__["default"], { app: app, initialContent: '', placeholder: agentExecutionStatus === 'working' ? `Agent is editing ${(_a = agentTargetNotebookPanelRef.current) === null || _a === void 0 ? void 0 : _a.context.path.split('/').pop()}` :
|
|
3066
3162
|
agentExecutionStatus === 'stopping' ? 'Agent is stopping...' :
|
|
3067
3163
|
agentModeEnabled ? 'Ask agent to do anything' :
|
|
3068
3164
|
displayOptimizedChatHistory.length < 2 ? `Ask question (${operatingSystem === 'mac' ? '⌘' : 'Ctrl'}E), @ to mention`
|
|
3069
3165
|
: `Ask followup (${operatingSystem === 'mac' ? '⌘' : 'Ctrl'}E), @ to mention`, onSave: agentModeEnabled ? startAgentExecution : sendChatInputMessage, onCancel: undefined, isEditing: false, contextManager: contextManager, notebookTracker: notebookTracker, agentModeEnabled: agentModeEnabled, agentExecutionStatus: agentExecutionStatus })),
|
|
3070
3166
|
agentExecutionStatus !== 'working' && agentExecutionStatus !== 'stopping' && (react__WEBPACK_IMPORTED_MODULE_1___default().createElement("div", { className: "chat-controls" },
|
|
3071
3167
|
react__WEBPACK_IMPORTED_MODULE_1___default().createElement("div", { className: "chat-controls-left" },
|
|
3072
|
-
react__WEBPACK_IMPORTED_MODULE_1___default().createElement(
|
|
3168
|
+
react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_components_ToggleButton__WEBPACK_IMPORTED_MODULE_39__["default"], { leftText: "Chat", leftTooltip: "Chat mode suggests an edit to the active cell and let's you decide to accept or reject it.", rightText: "Agent", rightTooltip: "Agent mode writes and executes code until it's finished your request.", isLeftSelected: !agentModeEnabled, onChange: async (isLeftSelected) => {
|
|
3073
3169
|
await startNewChat(); // TODO: delete thread instead of starting new chat
|
|
3074
3170
|
setAgentModeEnabled(!isLeftSelected);
|
|
3075
3171
|
// Clear agent checkpoint when switching modes
|
|
@@ -3103,9 +3199,9 @@ const ChatTaskpane = ({ notebookTracker, renderMimeRegistry, contextManager, app
|
|
|
3103
3199
|
} },
|
|
3104
3200
|
react__WEBPACK_IMPORTED_MODULE_1___default().createElement("span", { className: "submit-text" }, "Submit"),
|
|
3105
3201
|
" \u23CE"))),
|
|
3106
|
-
(agentExecutionStatus === 'working' || agentExecutionStatus === 'stopping') && (react__WEBPACK_IMPORTED_MODULE_1___default().createElement("button", { className: "button-base button-red stop-agent-button", onClick: markAgentForStopping, disabled: agentExecutionStatus === 'stopping', "data-testid": "stop-agent-button" }, agentExecutionStatus === 'stopping' ? (react__WEBPACK_IMPORTED_MODULE_1___default().createElement("div", { className: "stop-agent-button-content" },
|
|
3202
|
+
(agentExecutionStatus === 'working' || agentExecutionStatus === 'stopping') && (react__WEBPACK_IMPORTED_MODULE_1___default().createElement("button", { className: "button-base button-red stop-agent-button", onClick: () => void markAgentForStopping('userStop'), disabled: agentExecutionStatus === 'stopping', "data-testid": "stop-agent-button" }, agentExecutionStatus === 'stopping' ? (react__WEBPACK_IMPORTED_MODULE_1___default().createElement("div", { className: "stop-agent-button-content" },
|
|
3107
3203
|
"Stopping",
|
|
3108
|
-
react__WEBPACK_IMPORTED_MODULE_1___default().createElement(
|
|
3204
|
+
react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_components_LoadingCircle__WEBPACK_IMPORTED_MODULE_40__["default"], null),
|
|
3109
3205
|
" ")) : ('Stop Agent')))));
|
|
3110
3206
|
};
|
|
3111
3207
|
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (ChatTaskpane);
|
|
@@ -3161,7 +3257,7 @@ class ChatWidget extends _jupyterlab_apputils__WEBPACK_IMPORTED_MODULE_1__.React
|
|
|
3161
3257
|
this._lastErrorChanged = new _lumino_signaling__WEBPACK_IMPORTED_MODULE_3__.Signal(this);
|
|
3162
3258
|
// Create the websocket client
|
|
3163
3259
|
this.websocketClient = new _websockets_completions_CompletionsWebsocketClient__WEBPACK_IMPORTED_MODULE_5__.CompletionWebsocketClient({
|
|
3164
|
-
serverSettings: options.app.serviceManager.serverSettings
|
|
3260
|
+
serverSettings: options.app.serviceManager.serverSettings,
|
|
3165
3261
|
});
|
|
3166
3262
|
this.websocketClient.messages.connect(this.onMessage, this);
|
|
3167
3263
|
// Initialize the websocket client
|
|
@@ -3462,9 +3558,11 @@ const IChatTracker = new _lumino_coreutils__WEBPACK_IMPORTED_MODULE_0__.Token('m
|
|
|
3462
3558
|
|
|
3463
3559
|
__webpack_require__.r(__webpack_exports__);
|
|
3464
3560
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
3465
|
-
/* harmony export */ getBase64EncodedCellOutput: () => (/* binding */ getBase64EncodedCellOutput)
|
|
3561
|
+
/* harmony export */ getBase64EncodedCellOutput: () => (/* binding */ getBase64EncodedCellOutput),
|
|
3562
|
+
/* harmony export */ getBase64EncodedCellOutputInNotebook: () => (/* binding */ getBase64EncodedCellOutputInNotebook)
|
|
3466
3563
|
/* harmony export */ });
|
|
3467
3564
|
/* harmony import */ var _utils_notebook__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../utils/notebook */ "./lib/utils/notebook.js");
|
|
3565
|
+
/* harmony import */ var _utils_cellOutput__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../utils/cellOutput */ "./lib/utils/cellOutput.js");
|
|
3468
3566
|
/* harmony import */ var _restAPI_RestAPI__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../restAPI/RestAPI */ "./lib/restAPI/RestAPI.js");
|
|
3469
3567
|
/*
|
|
3470
3568
|
* Copyright (c) Saga Inc.
|
|
@@ -3472,20 +3570,23 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
3472
3570
|
*/
|
|
3473
3571
|
|
|
3474
3572
|
|
|
3573
|
+
|
|
3475
3574
|
const getBase64EncodedCellOutput = async (notebookTracker, cellID) => {
|
|
3476
|
-
|
|
3575
|
+
const notebookPanel = notebookTracker.currentWidget;
|
|
3576
|
+
return getBase64EncodedCellOutputInNotebook(notebookPanel, cellID);
|
|
3577
|
+
};
|
|
3578
|
+
const getBase64EncodedCellOutputInNotebook = async (notebookPanel, cellID) => {
|
|
3579
|
+
if (cellID === undefined || notebookPanel === null) {
|
|
3477
3580
|
return undefined;
|
|
3478
3581
|
}
|
|
3479
|
-
|
|
3480
|
-
const cellIndex = (0,_utils_notebook__WEBPACK_IMPORTED_MODULE_0__.getCellIndexByID)(notebookTracker, cellID);
|
|
3582
|
+
const cellIndex = (0,_utils_notebook__WEBPACK_IMPORTED_MODULE_0__.getCellIndexByIDInNotebookPanel)(notebookPanel, cellID);
|
|
3481
3583
|
if (cellIndex === undefined) {
|
|
3482
3584
|
// Log that the cell id is not part of the notebook
|
|
3483
|
-
console.log(`Cell with id ${cellID} not found in notebook`);
|
|
3585
|
+
console.log(`Cell with id ${cellID} not found in notebook ${notebookPanel.context.path}`);
|
|
3484
3586
|
void (0,_restAPI_RestAPI__WEBPACK_IMPORTED_MODULE_1__.logEvent)('get_cell_output_requested_non_existent_cell');
|
|
3485
3587
|
return undefined;
|
|
3486
3588
|
}
|
|
3487
|
-
(0,
|
|
3488
|
-
const activeCellOutput = await (0,_utils_notebook__WEBPACK_IMPORTED_MODULE_0__.getActiveCellOutput)(notebookTracker);
|
|
3589
|
+
const activeCellOutput = await (0,_utils_cellOutput__WEBPACK_IMPORTED_MODULE_2__.getCellOutputByIDInNotebook)(notebookPanel, cellID);
|
|
3489
3590
|
if (activeCellOutput !== undefined) {
|
|
3490
3591
|
return activeCellOutput;
|
|
3491
3592
|
}
|
|
@@ -3495,20 +3596,86 @@ const getBase64EncodedCellOutput = async (notebookTracker, cellID) => {
|
|
|
3495
3596
|
|
|
3496
3597
|
/***/ }),
|
|
3497
3598
|
|
|
3498
|
-
/***/ "./lib/Extensions/
|
|
3499
|
-
|
|
3500
|
-
!*** ./lib/Extensions/
|
|
3501
|
-
|
|
3599
|
+
/***/ "./lib/Extensions/AiChat/validationUtils.js":
|
|
3600
|
+
/*!**************************************************!*\
|
|
3601
|
+
!*** ./lib/Extensions/AiChat/validationUtils.js ***!
|
|
3602
|
+
\**************************************************/
|
|
3603
|
+
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
3604
|
+
|
|
3605
|
+
__webpack_require__.r(__webpack_exports__);
|
|
3606
|
+
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
3607
|
+
/* harmony export */ validateAndCorrectAgentResponse: () => (/* binding */ validateAndCorrectAgentResponse)
|
|
3608
|
+
/* harmony export */ });
|
|
3609
|
+
/*
|
|
3610
|
+
* Copyright (c) Saga Inc.
|
|
3611
|
+
* Distributed under the terms of the GNU Affero General Public License v3.0 License.
|
|
3612
|
+
*/
|
|
3613
|
+
/**
|
|
3614
|
+
* Validates and corrects an AgentResponse to ensure it adheres to the expected format.
|
|
3615
|
+
* Handles common mistakes like string instead of array, missing fields, etc.
|
|
3616
|
+
*/
|
|
3617
|
+
function validateAndCorrectAgentResponse(agentResponse) {
|
|
3618
|
+
var _a;
|
|
3619
|
+
// Create a copy to avoid mutating the original
|
|
3620
|
+
const correctedResponse = { ...agentResponse };
|
|
3621
|
+
// Ensure type is valid. Default to finished_task if not valid.
|
|
3622
|
+
const validTypes = ['cell_update', 'get_cell_output', 'run_all_cells', 'finished_task'];
|
|
3623
|
+
correctedResponse.type = (correctedResponse.type && validTypes.includes(correctedResponse.type))
|
|
3624
|
+
? correctedResponse.type
|
|
3625
|
+
: 'finished_task';
|
|
3626
|
+
// Ensure message is a string. Default to empty string if not valid.
|
|
3627
|
+
if (!correctedResponse.message || typeof correctedResponse.message !== 'string') {
|
|
3628
|
+
correctedResponse.message = '';
|
|
3629
|
+
}
|
|
3630
|
+
// Correct get_cell_output_cell_id if present
|
|
3631
|
+
const getCellOutputCellIdType = typeof correctedResponse.get_cell_output_cell_id;
|
|
3632
|
+
correctedResponse.get_cell_output_cell_id = getCellOutputCellIdType === 'string' ? correctedResponse.get_cell_output_cell_id : undefined;
|
|
3633
|
+
// Correct next_steps - handle string to array conversion
|
|
3634
|
+
if (correctedResponse.next_steps !== undefined && correctedResponse.next_steps !== null) {
|
|
3635
|
+
correctedResponse.next_steps = correctStringArray(correctedResponse.next_steps);
|
|
3636
|
+
}
|
|
3637
|
+
// Correct analysis_assumptions - handle string to array conversion
|
|
3638
|
+
if (correctedResponse.analysis_assumptions !== undefined && correctedResponse.analysis_assumptions !== null) {
|
|
3639
|
+
correctedResponse.analysis_assumptions = correctStringArray(correctedResponse.analysis_assumptions);
|
|
3640
|
+
// No empty strings in the assumptions
|
|
3641
|
+
correctedResponse.analysis_assumptions = (_a = correctedResponse.analysis_assumptions) === null || _a === void 0 ? void 0 : _a.filter(assumption => assumption.trim() !== '');
|
|
3642
|
+
}
|
|
3643
|
+
// For now we don't validate the cell_update object itself, as this is more complex and has
|
|
3644
|
+
// not caused issues thus far.
|
|
3645
|
+
return correctedResponse;
|
|
3646
|
+
}
|
|
3647
|
+
/**
|
|
3648
|
+
* Corrects a value to be a string array, handling various input formats.
|
|
3649
|
+
* Handles cases where the AI returns a string instead of an array of strings.
|
|
3650
|
+
*/
|
|
3651
|
+
function correctStringArray(value) {
|
|
3652
|
+
// If it's already a valid array of strings, return it
|
|
3653
|
+
if (Array.isArray(value)) {
|
|
3654
|
+
return value;
|
|
3655
|
+
}
|
|
3656
|
+
if (typeof value === 'string') {
|
|
3657
|
+
return [value];
|
|
3658
|
+
}
|
|
3659
|
+
return undefined;
|
|
3660
|
+
}
|
|
3661
|
+
|
|
3662
|
+
|
|
3663
|
+
/***/ }),
|
|
3664
|
+
|
|
3665
|
+
/***/ "./lib/Extensions/AppDeploy/AppDeployPlugin.js":
|
|
3666
|
+
/*!*****************************************************!*\
|
|
3667
|
+
!*** ./lib/Extensions/AppDeploy/AppDeployPlugin.js ***!
|
|
3668
|
+
\*****************************************************/
|
|
3502
3669
|
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
3503
3670
|
|
|
3504
3671
|
__webpack_require__.r(__webpack_exports__);
|
|
3505
3672
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
3506
|
-
/* harmony export */
|
|
3673
|
+
/* harmony export */ IAppDeployService: () => (/* binding */ IAppDeployService),
|
|
3507
3674
|
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
|
|
3508
3675
|
/* harmony export */ });
|
|
3509
3676
|
/* harmony import */ var _lumino_coreutils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @lumino/coreutils */ "webpack/sharing/consume/default/@lumino/coreutils");
|
|
3510
3677
|
/* harmony import */ var _lumino_coreutils__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_lumino_coreutils__WEBPACK_IMPORTED_MODULE_0__);
|
|
3511
|
-
/* harmony import */ var
|
|
3678
|
+
/* harmony import */ var _websockets_appDeploy_appDeployWebsocketClient__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../websockets/appDeploy/appDeployWebsocketClient */ "./lib/websockets/appDeploy/appDeployWebsocketClient.js");
|
|
3512
3679
|
/*
|
|
3513
3680
|
* Copyright (c) Saga Inc.
|
|
3514
3681
|
* Distributed under the terms of the GNU Affero General Public License v3.0 License.
|
|
@@ -3516,49 +3683,49 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
3516
3683
|
|
|
3517
3684
|
|
|
3518
3685
|
/**
|
|
3519
|
-
* The token for the
|
|
3686
|
+
* The token for the AppDeploy service.
|
|
3520
3687
|
*/
|
|
3521
|
-
const
|
|
3688
|
+
const IAppDeployService = new _lumino_coreutils__WEBPACK_IMPORTED_MODULE_0__.Token('mito-ai:IAppDeployService', 'Token for the AppDeploy service that provides access to the websocket client');
|
|
3522
3689
|
/**
|
|
3523
|
-
* Implementation of the
|
|
3690
|
+
* Implementation of the AppDeploy service.
|
|
3524
3691
|
*/
|
|
3525
|
-
class
|
|
3692
|
+
class AppDeployService {
|
|
3526
3693
|
/**
|
|
3527
|
-
* Create a new
|
|
3694
|
+
* Create a new AppDeploy service.
|
|
3528
3695
|
*/
|
|
3529
3696
|
constructor(app) {
|
|
3530
3697
|
// Create the websocket client with the app's server settings
|
|
3531
|
-
this.client = new
|
|
3698
|
+
this.client = new _websockets_appDeploy_appDeployWebsocketClient__WEBPACK_IMPORTED_MODULE_1__.AppDeployWebsocketClient({
|
|
3532
3699
|
serverSettings: app.serviceManager.serverSettings
|
|
3533
3700
|
});
|
|
3534
3701
|
// Initialize the websocket connection in the background
|
|
3535
3702
|
void this.client.initialize().catch(error => {
|
|
3536
|
-
console.error('Failed to initialize
|
|
3703
|
+
console.error('Failed to initialize AppDeploy websocket client:', error);
|
|
3537
3704
|
// We don't need to throw the error since the client will attempt to reconnect when used
|
|
3538
3705
|
});
|
|
3539
3706
|
}
|
|
3540
3707
|
}
|
|
3541
3708
|
/**
|
|
3542
|
-
* The
|
|
3709
|
+
* The AppDeploy plugin that provides the websocket client.
|
|
3543
3710
|
*/
|
|
3544
|
-
const
|
|
3545
|
-
id: 'mito-ai:app-
|
|
3711
|
+
const AppDeployPlugin = {
|
|
3712
|
+
id: 'mito-ai:app-deploy',
|
|
3546
3713
|
autoStart: true,
|
|
3547
|
-
provides:
|
|
3714
|
+
provides: IAppDeployService,
|
|
3548
3715
|
activate: (app) => {
|
|
3549
|
-
console.log('mito-ai:
|
|
3550
|
-
return new
|
|
3716
|
+
console.log('mito-ai: AppDeployPlugin activated');
|
|
3717
|
+
return new AppDeployService(app);
|
|
3551
3718
|
}
|
|
3552
3719
|
};
|
|
3553
|
-
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (
|
|
3720
|
+
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (AppDeployPlugin);
|
|
3554
3721
|
|
|
3555
3722
|
|
|
3556
3723
|
/***/ }),
|
|
3557
3724
|
|
|
3558
|
-
/***/ "./lib/Extensions/
|
|
3559
|
-
|
|
3560
|
-
!*** ./lib/Extensions/
|
|
3561
|
-
|
|
3725
|
+
/***/ "./lib/Extensions/AppDeploy/DeployAppNotification.js":
|
|
3726
|
+
/*!***********************************************************!*\
|
|
3727
|
+
!*** ./lib/Extensions/AppDeploy/DeployAppNotification.js ***!
|
|
3728
|
+
\***********************************************************/
|
|
3562
3729
|
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
3563
3730
|
|
|
3564
3731
|
__webpack_require__.r(__webpack_exports__);
|
|
@@ -3567,51 +3734,92 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
3567
3734
|
/* harmony export */ });
|
|
3568
3735
|
/* harmony import */ var _jupyterlab_apputils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @jupyterlab/apputils */ "webpack/sharing/consume/default/@jupyterlab/apputils");
|
|
3569
3736
|
/* harmony import */ var _jupyterlab_apputils__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_jupyterlab_apputils__WEBPACK_IMPORTED_MODULE_0__);
|
|
3737
|
+
/* harmony import */ var _AppManager_CheckAppStatusAPI__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../AppManager/CheckAppStatusAPI */ "./lib/Extensions/AppManager/CheckAppStatusAPI.js");
|
|
3570
3738
|
/*
|
|
3571
3739
|
* Copyright (c) Saga Inc.
|
|
3572
3740
|
* Distributed under the terms of the GNU Affero General Public License v3.0 License.
|
|
3573
3741
|
*/
|
|
3574
3742
|
|
|
3575
|
-
|
|
3743
|
+
|
|
3744
|
+
const deployAppNotification = (url, appManagerService, notificationId) => {
|
|
3576
3745
|
// Total deployment time in milliseconds (3 minutes = 180000ms)
|
|
3577
3746
|
const totalDeploymentTime = 180000;
|
|
3578
3747
|
// Create an array of deployment steps
|
|
3579
3748
|
const deploymentSteps = [
|
|
3580
|
-
"Step
|
|
3581
|
-
"Step
|
|
3582
|
-
"Step
|
|
3583
|
-
"Step
|
|
3584
|
-
"Step
|
|
3585
|
-
"Step
|
|
3749
|
+
"Step 2/7: Preparing your app...",
|
|
3750
|
+
"Step 3/7: Assembling clouds...",
|
|
3751
|
+
"Step 4/7: Building your app...",
|
|
3752
|
+
"Step 5/7: Configuring network settings...",
|
|
3753
|
+
"Step 6/7: Adding final touches...",
|
|
3754
|
+
"Step 7/7: Running security checks...",
|
|
3586
3755
|
"Deployment complete! Your app is ready."
|
|
3587
3756
|
];
|
|
3588
|
-
// Create initial "in progress" notification to get notificaiton id
|
|
3589
|
-
const notificationId = _jupyterlab_apputils__WEBPACK_IMPORTED_MODULE_0__.Notification.emit(deploymentSteps[0], 'in-progress', {
|
|
3590
|
-
autoClose: false
|
|
3591
|
-
});
|
|
3592
3757
|
// Calculate time between steps (evenly distribute throughout the total deployment time)
|
|
3593
3758
|
const stepInterval = totalDeploymentTime / (deploymentSteps.length - 1);
|
|
3759
|
+
let retryCount = 5;
|
|
3594
3760
|
// Update message at each step interval
|
|
3595
|
-
for (let i =
|
|
3761
|
+
for (let i = 0; i < deploymentSteps.length; i++) {
|
|
3596
3762
|
setTimeout(() => {
|
|
3597
3763
|
const isLastStep = i === deploymentSteps.length - 1;
|
|
3598
|
-
|
|
3599
|
-
|
|
3600
|
-
|
|
3601
|
-
|
|
3602
|
-
|
|
3603
|
-
|
|
3604
|
-
|
|
3605
|
-
|
|
3606
|
-
|
|
3607
|
-
|
|
3608
|
-
|
|
3609
|
-
|
|
3610
|
-
|
|
3764
|
+
if (isLastStep) {
|
|
3765
|
+
const checkUrlAndUpdate = async () => {
|
|
3766
|
+
if (retryCount < 0) {
|
|
3767
|
+
console.log("Retries done");
|
|
3768
|
+
_jupyterlab_apputils__WEBPACK_IMPORTED_MODULE_0__.Notification.update({
|
|
3769
|
+
id: notificationId,
|
|
3770
|
+
message: "Unable to deploy. Your app is not reachable",
|
|
3771
|
+
type: 'warning',
|
|
3772
|
+
autoClose: false
|
|
3773
|
+
});
|
|
3774
|
+
return;
|
|
3775
|
+
}
|
|
3776
|
+
try {
|
|
3777
|
+
console.log("Awaiting response");
|
|
3778
|
+
const urlIsUp = await (0,_AppManager_CheckAppStatusAPI__WEBPACK_IMPORTED_MODULE_1__.checkAppStatus)(url, appManagerService);
|
|
3779
|
+
console.log(`App status check result for ${url}: ${urlIsUp}`);
|
|
3780
|
+
if (urlIsUp) {
|
|
3781
|
+
// Update notification with the button
|
|
3782
|
+
_jupyterlab_apputils__WEBPACK_IMPORTED_MODULE_0__.Notification.update({
|
|
3783
|
+
id: notificationId,
|
|
3784
|
+
message: deploymentSteps[i],
|
|
3785
|
+
type: 'default',
|
|
3786
|
+
autoClose: false,
|
|
3787
|
+
actions: [
|
|
3788
|
+
{
|
|
3789
|
+
label: "Launch Application Now",
|
|
3790
|
+
displayType: 'accent',
|
|
3791
|
+
callback: () => {
|
|
3792
|
+
window.open(url, '_blank');
|
|
3793
|
+
}
|
|
3794
|
+
}
|
|
3795
|
+
]
|
|
3796
|
+
});
|
|
3611
3797
|
}
|
|
3612
|
-
|
|
3613
|
-
|
|
3614
|
-
|
|
3798
|
+
else {
|
|
3799
|
+
// Retry after 30s
|
|
3800
|
+
console.log("In retry for url to be up");
|
|
3801
|
+
retryCount = retryCount - 1;
|
|
3802
|
+
setTimeout(() => void checkUrlAndUpdate(), 30000);
|
|
3803
|
+
}
|
|
3804
|
+
}
|
|
3805
|
+
catch (error) {
|
|
3806
|
+
// Retry after 30s
|
|
3807
|
+
console.error("Error checking app status:", error);
|
|
3808
|
+
retryCount = retryCount - 1;
|
|
3809
|
+
setTimeout(() => void checkUrlAndUpdate(), 30000);
|
|
3810
|
+
}
|
|
3811
|
+
};
|
|
3812
|
+
void checkUrlAndUpdate();
|
|
3813
|
+
}
|
|
3814
|
+
else {
|
|
3815
|
+
// Regular intermediate step
|
|
3816
|
+
_jupyterlab_apputils__WEBPACK_IMPORTED_MODULE_0__.Notification.update({
|
|
3817
|
+
id: notificationId,
|
|
3818
|
+
message: deploymentSteps[i],
|
|
3819
|
+
type: 'in-progress',
|
|
3820
|
+
autoClose: false
|
|
3821
|
+
});
|
|
3822
|
+
}
|
|
3615
3823
|
}, i * stepInterval);
|
|
3616
3824
|
}
|
|
3617
3825
|
};
|
|
@@ -3619,27 +3827,147 @@ const deployAppNotification = (url) => {
|
|
|
3619
3827
|
|
|
3620
3828
|
/***/ }),
|
|
3621
3829
|
|
|
3622
|
-
/***/ "./lib/Extensions/
|
|
3623
|
-
|
|
3624
|
-
!*** ./lib/Extensions/
|
|
3625
|
-
|
|
3830
|
+
/***/ "./lib/Extensions/AppDeploy/DeployFilesSelector.js":
|
|
3831
|
+
/*!*********************************************************!*\
|
|
3832
|
+
!*** ./lib/Extensions/AppDeploy/DeployFilesSelector.js ***!
|
|
3833
|
+
\*********************************************************/
|
|
3626
3834
|
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
3627
3835
|
|
|
3628
3836
|
__webpack_require__.r(__webpack_exports__);
|
|
3629
3837
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
3630
|
-
/* harmony export */
|
|
3838
|
+
/* harmony export */ FileUploadPopup: () => (/* binding */ FileUploadPopup)
|
|
3631
3839
|
/* harmony export */ });
|
|
3632
|
-
/* harmony import */ var
|
|
3633
|
-
/* harmony import */ var
|
|
3634
|
-
/* harmony import */ var
|
|
3635
|
-
/* harmony import */ var
|
|
3636
|
-
/* harmony import */ var
|
|
3637
|
-
/* harmony import */ var
|
|
3638
|
-
/* harmony import */ var
|
|
3639
|
-
/*
|
|
3640
|
-
|
|
3641
|
-
|
|
3642
|
-
|
|
3840
|
+
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ "webpack/sharing/consume/default/react");
|
|
3841
|
+
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
|
|
3842
|
+
/* harmony import */ var _style_ConnectionForm_css__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../style/ConnectionForm.css */ "./style/ConnectionForm.css");
|
|
3843
|
+
/* harmony import */ var _style_button_css__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../../style/button.css */ "./style/button.css");
|
|
3844
|
+
/* harmony import */ var _style_FilesSelector_css__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../../style/FilesSelector.css */ "./style/FilesSelector.css");
|
|
3845
|
+
/* harmony import */ var _jupyterlab_ui_components__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @jupyterlab/ui-components */ "webpack/sharing/consume/default/@jupyterlab/ui-components");
|
|
3846
|
+
/* harmony import */ var _jupyterlab_ui_components__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(_jupyterlab_ui_components__WEBPACK_IMPORTED_MODULE_4__);
|
|
3847
|
+
/*
|
|
3848
|
+
* Copyright (c) Saga Inc.
|
|
3849
|
+
* Distributed under the terms of the GNU Affero General Public License v3.0 License.
|
|
3850
|
+
*/
|
|
3851
|
+
|
|
3852
|
+
|
|
3853
|
+
|
|
3854
|
+
|
|
3855
|
+
|
|
3856
|
+
const FileIcon = _jupyterlab_ui_components__WEBPACK_IMPORTED_MODULE_4__.fileIcon.react;
|
|
3857
|
+
const FolderIcon = _jupyterlab_ui_components__WEBPACK_IMPORTED_MODULE_4__.folderIcon.react;
|
|
3858
|
+
const CloseIcon = _jupyterlab_ui_components__WEBPACK_IMPORTED_MODULE_4__.closeIcon.react;
|
|
3859
|
+
const FileUploadPopup = ({ filePath, onClose, onSubmit }) => {
|
|
3860
|
+
const [items, setItems] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)([]);
|
|
3861
|
+
const [selectedItems, setSelectedItems] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(new Set());
|
|
3862
|
+
// Figure out current notebook directory
|
|
3863
|
+
const getNotebookDir = () => {
|
|
3864
|
+
if (!filePath)
|
|
3865
|
+
return '';
|
|
3866
|
+
const parts = filePath.split('/');
|
|
3867
|
+
parts.pop(); // remove notebook filename
|
|
3868
|
+
return parts.join('/');
|
|
3869
|
+
};
|
|
3870
|
+
const alwaysSelected = ['requirements.txt', 'app.py'];
|
|
3871
|
+
(0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
|
|
3872
|
+
const nbDir = getNotebookDir();
|
|
3873
|
+
const apiPath = nbDir ? `/api/contents/${nbDir}` : '/api/contents/';
|
|
3874
|
+
fetch(apiPath)
|
|
3875
|
+
.then(res => res.json())
|
|
3876
|
+
.then(data => {
|
|
3877
|
+
const entries = data.content.map((item) => ({
|
|
3878
|
+
name: item.name,
|
|
3879
|
+
type: item.type, // "file" or "directory"
|
|
3880
|
+
}))
|
|
3881
|
+
.sort((a, b) => a.name.localeCompare(b.name));
|
|
3882
|
+
setItems(entries);
|
|
3883
|
+
// Pre-select default files
|
|
3884
|
+
const defaultFiles = new Set();
|
|
3885
|
+
entries.forEach(entry => {
|
|
3886
|
+
if (alwaysSelected.includes(entry.name)) {
|
|
3887
|
+
defaultFiles.add(entry.name);
|
|
3888
|
+
}
|
|
3889
|
+
});
|
|
3890
|
+
setSelectedItems(defaultFiles);
|
|
3891
|
+
})
|
|
3892
|
+
.catch(err => console.error('Error fetching files/dirs:', err));
|
|
3893
|
+
}, []);
|
|
3894
|
+
const handleCheckboxChange = (name) => {
|
|
3895
|
+
setSelectedItems(prev => {
|
|
3896
|
+
const newSet = new Set(prev);
|
|
3897
|
+
if (newSet.has(name))
|
|
3898
|
+
newSet.delete(name);
|
|
3899
|
+
else
|
|
3900
|
+
newSet.add(name);
|
|
3901
|
+
return newSet;
|
|
3902
|
+
});
|
|
3903
|
+
};
|
|
3904
|
+
const handleSelectAll = (checked) => {
|
|
3905
|
+
if (checked) {
|
|
3906
|
+
// select all, nothing excluded
|
|
3907
|
+
setSelectedItems(new Set(items.map(i => i.name)));
|
|
3908
|
+
}
|
|
3909
|
+
else {
|
|
3910
|
+
// keep only alwaysSelected
|
|
3911
|
+
setSelectedItems(new Set(alwaysSelected));
|
|
3912
|
+
}
|
|
3913
|
+
};
|
|
3914
|
+
const handleSubmit = () => {
|
|
3915
|
+
const selectedPaths = Array.from(selectedItems);
|
|
3916
|
+
onSubmit(selectedPaths);
|
|
3917
|
+
onClose();
|
|
3918
|
+
};
|
|
3919
|
+
const allSelected = items.length > 0 && selectedItems.size === items.length;
|
|
3920
|
+
const partiallySelected = selectedItems.size > 0 && selectedItems.size < items.length;
|
|
3921
|
+
return (react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { className: "modal-overlay" },
|
|
3922
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { className: "modal-content" },
|
|
3923
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { className: "modal-header" },
|
|
3924
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement("h3", null, "Upload files Required for the App"),
|
|
3925
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement("button", { onClick: onClose, className: "modal-close-button", title: "Close" },
|
|
3926
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(CloseIcon, null))),
|
|
3927
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { className: "modal-subheader" },
|
|
3928
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement("p", { className: "modal-subtext" }, "Select the files and/or directories that are required to render the app. For example, if your app reads data from a csv file, you must select it here.")),
|
|
3929
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { className: "modal-body" }, items.length === 0 ? (react__WEBPACK_IMPORTED_MODULE_0___default().createElement("p", null, "No items found.")) : (react__WEBPACK_IMPORTED_MODULE_0___default().createElement((react__WEBPACK_IMPORTED_MODULE_0___default().Fragment), null,
|
|
3930
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { className: "files-selector-select-all" },
|
|
3931
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement("label", { className: "checkbox-label" },
|
|
3932
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement("input", { type: "checkbox", checked: allSelected, ref: el => {
|
|
3933
|
+
if (el)
|
|
3934
|
+
el.indeterminate = partiallySelected;
|
|
3935
|
+
}, onChange: e => handleSelectAll(e.target.checked) }),
|
|
3936
|
+
"Select All")),
|
|
3937
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { className: "file-list-scrollable" },
|
|
3938
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement("ul", { className: "file-list" }, items.map((item, index) => (react__WEBPACK_IMPORTED_MODULE_0___default().createElement("li", { key: index },
|
|
3939
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement("label", { className: "checkbox-label" },
|
|
3940
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement("input", { type: "checkbox", checked: selectedItems.has(item.name), onChange: () => handleCheckboxChange(item.name), disabled: alwaysSelected.includes(item.name), title: alwaysSelected.includes(item.name) ? "Required for deploying your app" : undefined }),
|
|
3941
|
+
item.type === 'directory' ? react__WEBPACK_IMPORTED_MODULE_0___default().createElement(FolderIcon, null) : react__WEBPACK_IMPORTED_MODULE_0___default().createElement(FileIcon, null),
|
|
3942
|
+
" ",
|
|
3943
|
+
item.name))))))))),
|
|
3944
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { className: "modal-footer" },
|
|
3945
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement("button", { className: "files-selector-submit-button", onClick: handleSubmit, disabled: selectedItems.size === 0 }, "Deploy App")))));
|
|
3946
|
+
};
|
|
3947
|
+
|
|
3948
|
+
|
|
3949
|
+
/***/ }),
|
|
3950
|
+
|
|
3951
|
+
/***/ "./lib/Extensions/AppDeploy/DeployStreamlitApp.js":
|
|
3952
|
+
/*!********************************************************!*\
|
|
3953
|
+
!*** ./lib/Extensions/AppDeploy/DeployStreamlitApp.js ***!
|
|
3954
|
+
\********************************************************/
|
|
3955
|
+
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
3956
|
+
|
|
3957
|
+
__webpack_require__.r(__webpack_exports__);
|
|
3958
|
+
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
3959
|
+
/* harmony export */ deployStreamlitApp: () => (/* binding */ deployStreamlitApp)
|
|
3960
|
+
/* harmony export */ });
|
|
3961
|
+
/* harmony import */ var _jupyterlab_apputils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @jupyterlab/apputils */ "webpack/sharing/consume/default/@jupyterlab/apputils");
|
|
3962
|
+
/* harmony import */ var _jupyterlab_apputils__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_jupyterlab_apputils__WEBPACK_IMPORTED_MODULE_0__);
|
|
3963
|
+
/* harmony import */ var _requirementsUtils__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./requirementsUtils */ "./lib/Extensions/AppDeploy/requirementsUtils.js");
|
|
3964
|
+
/* harmony import */ var _fileUtils__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./fileUtils */ "./lib/Extensions/AppDeploy/fileUtils.js");
|
|
3965
|
+
/* harmony import */ var _lumino_coreutils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @lumino/coreutils */ "webpack/sharing/consume/default/@lumino/coreutils");
|
|
3966
|
+
/* harmony import */ var _lumino_coreutils__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_lumino_coreutils__WEBPACK_IMPORTED_MODULE_1__);
|
|
3967
|
+
/* harmony import */ var _DeployAppNotification__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./DeployAppNotification */ "./lib/Extensions/AppDeploy/DeployAppNotification.js");
|
|
3968
|
+
/* harmony import */ var _auth__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./auth */ "./lib/Extensions/AppDeploy/auth.js");
|
|
3969
|
+
/* harmony import */ var _authPopupUtils__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./authPopupUtils */ "./lib/Extensions/AppDeploy/authPopupUtils.js");
|
|
3970
|
+
/* harmony import */ var _FilesSelectorUtils__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./FilesSelectorUtils */ "./lib/Extensions/AppDeploy/FilesSelectorUtils.js");
|
|
3643
3971
|
/*
|
|
3644
3972
|
* Copyright (c) Saga Inc.
|
|
3645
3973
|
* Distributed under the terms of the GNU Affero General Public License v3.0 License.
|
|
@@ -3653,21 +3981,23 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
3653
3981
|
|
|
3654
3982
|
|
|
3655
3983
|
/*
|
|
3656
|
-
This function generates
|
|
3984
|
+
This function generates the requirements.txt file needed to host the streamlit app,
|
|
3985
|
+
and deploys it!
|
|
3657
3986
|
*/
|
|
3658
|
-
const
|
|
3659
|
-
let
|
|
3987
|
+
const deployStreamlitApp = async (notebookTracker, appDeployService, appManagerService) => {
|
|
3988
|
+
let selectedFiles = [];
|
|
3989
|
+
let jwtToken = await (0,_auth__WEBPACK_IMPORTED_MODULE_2__.getJWTToken)();
|
|
3660
3990
|
if (!jwtToken) {
|
|
3661
3991
|
// No token found, show authentication popup
|
|
3662
3992
|
console.log('User not authenticated, redirected to signup');
|
|
3663
3993
|
try {
|
|
3664
|
-
const user = await (0,
|
|
3994
|
+
const user = await (0,_authPopupUtils__WEBPACK_IMPORTED_MODULE_3__.showAuthenticationPopup)();
|
|
3665
3995
|
console.log('User authenticated successfully:', user);
|
|
3666
3996
|
// Try to get the JWT token again after successful authentication
|
|
3667
|
-
jwtToken = await (0,
|
|
3997
|
+
jwtToken = await (0,_auth__WEBPACK_IMPORTED_MODULE_2__.getJWTToken)();
|
|
3668
3998
|
if (!jwtToken) {
|
|
3669
3999
|
console.error('JWT token still not available after authentication');
|
|
3670
|
-
|
|
4000
|
+
_jupyterlab_apputils__WEBPACK_IMPORTED_MODULE_0__.Notification.emit('Authentication failed - JWT token not found', 'error', {
|
|
3671
4001
|
autoClose: false
|
|
3672
4002
|
});
|
|
3673
4003
|
return;
|
|
@@ -3684,56 +4014,117 @@ const convertNotebookToStreamlit = async (notebookTracker, appBuilderService) =>
|
|
|
3684
4014
|
return;
|
|
3685
4015
|
}
|
|
3686
4016
|
const notebookPath = notebookPanel.context.path;
|
|
3687
|
-
const
|
|
3688
|
-
|
|
3689
|
-
|
|
3690
|
-
console.log('Current working directory info:', notebookPanel.context);
|
|
4017
|
+
const notificationId = _jupyterlab_apputils__WEBPACK_IMPORTED_MODULE_0__.Notification.emit('Step 1/7: Gathering requirements...', 'in-progress', {
|
|
4018
|
+
autoClose: false
|
|
4019
|
+
});
|
|
3691
4020
|
// Build the requirements.txt file
|
|
3692
|
-
|
|
3693
|
-
const requirementsContent = await (0,_requirementsUtils__WEBPACK_IMPORTED_MODULE_5__.generateRequirementsTxt)(notebookTracker);
|
|
4021
|
+
const requirementsContent = await (0,_requirementsUtils__WEBPACK_IMPORTED_MODULE_4__.generateRequirementsTxt)(notebookTracker);
|
|
3694
4022
|
// Save the files to the current directory
|
|
3695
|
-
await (0,
|
|
4023
|
+
await (0,_fileUtils__WEBPACK_IMPORTED_MODULE_5__.saveFileWithKernel)(notebookTracker, './requirements.txt', requirementsContent);
|
|
4024
|
+
try {
|
|
4025
|
+
_jupyterlab_apputils__WEBPACK_IMPORTED_MODULE_0__.Notification.dismiss(notificationId);
|
|
4026
|
+
selectedFiles = await (0,_FilesSelectorUtils__WEBPACK_IMPORTED_MODULE_6__.fileSelectorPopup)(notebookPath);
|
|
4027
|
+
}
|
|
4028
|
+
catch (error) {
|
|
4029
|
+
console.log('File selection failed:', error);
|
|
4030
|
+
return;
|
|
4031
|
+
}
|
|
4032
|
+
const newNotificationId = _jupyterlab_apputils__WEBPACK_IMPORTED_MODULE_0__.Notification.emit("Step 2/7: Preparing your app...", 'in-progress', {
|
|
4033
|
+
autoClose: false
|
|
4034
|
+
});
|
|
3696
4035
|
// After building the files, we need to send a request to the backend to deploy the app
|
|
3697
|
-
|
|
3698
|
-
|
|
3699
|
-
|
|
3700
|
-
|
|
3701
|
-
|
|
3702
|
-
|
|
3703
|
-
|
|
3704
|
-
|
|
3705
|
-
|
|
4036
|
+
try {
|
|
4037
|
+
console.log("Sending request to deploy the app");
|
|
4038
|
+
// Use the JWT token that was already obtained or refreshed above
|
|
4039
|
+
const response = await appDeployService.client.sendMessage({
|
|
4040
|
+
type: 'deploy-app',
|
|
4041
|
+
message_id: _lumino_coreutils__WEBPACK_IMPORTED_MODULE_1__.UUID.uuid4(),
|
|
4042
|
+
notebook_path: notebookPath,
|
|
4043
|
+
jwt_token: jwtToken,
|
|
4044
|
+
selected_files: selectedFiles
|
|
4045
|
+
});
|
|
4046
|
+
if (response.error) {
|
|
4047
|
+
_jupyterlab_apputils__WEBPACK_IMPORTED_MODULE_0__.Notification.update({
|
|
4048
|
+
id: newNotificationId,
|
|
4049
|
+
message: response.error.title,
|
|
4050
|
+
type: 'error',
|
|
4051
|
+
autoClose: false
|
|
3706
4052
|
});
|
|
3707
|
-
if (response.error) {
|
|
3708
|
-
_jupyterlab_apputils__WEBPACK_IMPORTED_MODULE_1__.Notification.emit(response.error.title, 'error', {
|
|
3709
|
-
autoClose: false
|
|
3710
|
-
});
|
|
3711
|
-
}
|
|
3712
|
-
else {
|
|
3713
|
-
console.log("App deployment response:", response);
|
|
3714
|
-
const url = response.url;
|
|
3715
|
-
(0,_DeployAppNotification__WEBPACK_IMPORTED_MODULE_7__.deployAppNotification)(url);
|
|
3716
|
-
}
|
|
3717
4053
|
}
|
|
3718
|
-
|
|
3719
|
-
|
|
3720
|
-
|
|
4054
|
+
else {
|
|
4055
|
+
console.log("App deployment response:", response);
|
|
4056
|
+
const url = response.url;
|
|
4057
|
+
(0,_DeployAppNotification__WEBPACK_IMPORTED_MODULE_7__.deployAppNotification)(url, appManagerService, newNotificationId);
|
|
3721
4058
|
}
|
|
3722
4059
|
}
|
|
3723
|
-
|
|
3724
|
-
|
|
4060
|
+
catch (error) {
|
|
4061
|
+
// TODO: Do something with the error
|
|
4062
|
+
console.error("Error deploying app:", error);
|
|
3725
4063
|
}
|
|
3726
4064
|
};
|
|
3727
4065
|
|
|
3728
4066
|
|
|
3729
4067
|
/***/ }),
|
|
3730
4068
|
|
|
3731
|
-
/***/ "./lib/Extensions/
|
|
4069
|
+
/***/ "./lib/Extensions/AppDeploy/FilesSelectorUtils.js":
|
|
3732
4070
|
/*!********************************************************!*\
|
|
3733
|
-
!*** ./lib/Extensions/
|
|
4071
|
+
!*** ./lib/Extensions/AppDeploy/FilesSelectorUtils.js ***!
|
|
3734
4072
|
\********************************************************/
|
|
3735
4073
|
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
3736
4074
|
|
|
4075
|
+
__webpack_require__.r(__webpack_exports__);
|
|
4076
|
+
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
4077
|
+
/* harmony export */ fileSelectorPopup: () => (/* binding */ fileSelectorPopup)
|
|
4078
|
+
/* harmony export */ });
|
|
4079
|
+
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ "webpack/sharing/consume/default/react");
|
|
4080
|
+
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
|
|
4081
|
+
/* harmony import */ var react_dom_client__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! react-dom/client */ "./node_modules/react-dom/client.js");
|
|
4082
|
+
/* harmony import */ var _DeployFilesSelector__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./DeployFilesSelector */ "./lib/Extensions/AppDeploy/DeployFilesSelector.js");
|
|
4083
|
+
/*
|
|
4084
|
+
* Copyright (c) Saga Inc.
|
|
4085
|
+
* Distributed under the terms of the GNU Affero General Public License v3.0 License.
|
|
4086
|
+
*/
|
|
4087
|
+
|
|
4088
|
+
|
|
4089
|
+
|
|
4090
|
+
/**
|
|
4091
|
+
* Shows a file selector popup
|
|
4092
|
+
*/
|
|
4093
|
+
const fileSelectorPopup = (notebookPath) => {
|
|
4094
|
+
return new Promise((resolve, reject) => {
|
|
4095
|
+
console.log("Starting file selector for:", notebookPath);
|
|
4096
|
+
// Create a container for the popup
|
|
4097
|
+
const popupContainer = document.createElement('div');
|
|
4098
|
+
popupContainer.id = 'file-selector-popup-container';
|
|
4099
|
+
document.body.appendChild(popupContainer);
|
|
4100
|
+
// Create root
|
|
4101
|
+
const root = (0,react_dom_client__WEBPACK_IMPORTED_MODULE_1__.createRoot)(popupContainer);
|
|
4102
|
+
const handleSubmit = (items) => {
|
|
4103
|
+
// Clean up the popup
|
|
4104
|
+
root.unmount();
|
|
4105
|
+
document.body.removeChild(popupContainer);
|
|
4106
|
+
resolve(items);
|
|
4107
|
+
};
|
|
4108
|
+
const handleClose = () => {
|
|
4109
|
+
// Clean up the popup
|
|
4110
|
+
root.unmount();
|
|
4111
|
+
document.body.removeChild(popupContainer);
|
|
4112
|
+
reject(new Error('File selection cancelled'));
|
|
4113
|
+
};
|
|
4114
|
+
// Render the AuthPopup
|
|
4115
|
+
root.render(react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_DeployFilesSelector__WEBPACK_IMPORTED_MODULE_2__.FileUploadPopup, { filePath: notebookPath, onClose: handleClose, onSubmit: handleSubmit }));
|
|
4116
|
+
});
|
|
4117
|
+
};
|
|
4118
|
+
|
|
4119
|
+
|
|
4120
|
+
/***/ }),
|
|
4121
|
+
|
|
4122
|
+
/***/ "./lib/Extensions/AppDeploy/auth-popup-deploy.js":
|
|
4123
|
+
/*!*******************************************************!*\
|
|
4124
|
+
!*** ./lib/Extensions/AppDeploy/auth-popup-deploy.js ***!
|
|
4125
|
+
\*******************************************************/
|
|
4126
|
+
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
4127
|
+
|
|
3737
4128
|
__webpack_require__.r(__webpack_exports__);
|
|
3738
4129
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
3739
4130
|
/* harmony export */ AuthPopup: () => (/* binding */ AuthPopup)
|
|
@@ -3838,10 +4229,10 @@ const AuthPopup = ({ isOpen, onClose, onSuccess }) => {
|
|
|
3838
4229
|
|
|
3839
4230
|
/***/ }),
|
|
3840
4231
|
|
|
3841
|
-
/***/ "./lib/Extensions/
|
|
3842
|
-
|
|
3843
|
-
!*** ./lib/Extensions/
|
|
3844
|
-
|
|
4232
|
+
/***/ "./lib/Extensions/AppDeploy/auth.js":
|
|
4233
|
+
/*!******************************************!*\
|
|
4234
|
+
!*** ./lib/Extensions/AppDeploy/auth.js ***!
|
|
4235
|
+
\******************************************/
|
|
3845
4236
|
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
3846
4237
|
|
|
3847
4238
|
__webpack_require__.r(__webpack_exports__);
|
|
@@ -3852,7 +4243,7 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
3852
4243
|
/* harmony export */ });
|
|
3853
4244
|
/* harmony import */ var aws_amplify_auth__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! aws-amplify/auth */ "./node_modules/@aws-amplify/core/dist/esm/singleton/apis/fetchAuthSession.mjs");
|
|
3854
4245
|
/* harmony import */ var aws_amplify_auth__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! aws-amplify/auth */ "./node_modules/@aws-amplify/auth/dist/esm/providers/cognito/apis/signOut.mjs");
|
|
3855
|
-
/* harmony import */ var _aws_config__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./aws-config */ "./lib/Extensions/
|
|
4246
|
+
/* harmony import */ var _aws_config__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./aws-config */ "./lib/Extensions/AppDeploy/aws-config.js");
|
|
3856
4247
|
/*
|
|
3857
4248
|
* Copyright (c) Saga Inc.
|
|
3858
4249
|
* Distributed under the terms of the GNU Affero General Public License v3.0 License.
|
|
@@ -3921,10 +4312,10 @@ const logoutAndClearJWTTokens = async () => {
|
|
|
3921
4312
|
|
|
3922
4313
|
/***/ }),
|
|
3923
4314
|
|
|
3924
|
-
/***/ "./lib/Extensions/
|
|
3925
|
-
|
|
3926
|
-
!*** ./lib/Extensions/
|
|
3927
|
-
|
|
4315
|
+
/***/ "./lib/Extensions/AppDeploy/authPopupUtils.js":
|
|
4316
|
+
/*!****************************************************!*\
|
|
4317
|
+
!*** ./lib/Extensions/AppDeploy/authPopupUtils.js ***!
|
|
4318
|
+
\****************************************************/
|
|
3928
4319
|
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
3929
4320
|
|
|
3930
4321
|
__webpack_require__.r(__webpack_exports__);
|
|
@@ -3934,7 +4325,7 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
3934
4325
|
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ "webpack/sharing/consume/default/react");
|
|
3935
4326
|
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
|
|
3936
4327
|
/* harmony import */ var react_dom_client__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! react-dom/client */ "./node_modules/react-dom/client.js");
|
|
3937
|
-
/* harmony import */ var _auth_popup_deploy__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./auth-popup-deploy */ "./lib/Extensions/
|
|
4328
|
+
/* harmony import */ var _auth_popup_deploy__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./auth-popup-deploy */ "./lib/Extensions/AppDeploy/auth-popup-deploy.js");
|
|
3938
4329
|
/*
|
|
3939
4330
|
* Copyright (c) Saga Inc.
|
|
3940
4331
|
* Distributed under the terms of the GNU Affero General Public License v3.0 License.
|
|
@@ -3973,10 +4364,10 @@ const showAuthenticationPopup = () => {
|
|
|
3973
4364
|
|
|
3974
4365
|
/***/ }),
|
|
3975
4366
|
|
|
3976
|
-
/***/ "./lib/Extensions/
|
|
3977
|
-
|
|
3978
|
-
!*** ./lib/Extensions/
|
|
3979
|
-
|
|
4367
|
+
/***/ "./lib/Extensions/AppDeploy/aws-config.js":
|
|
4368
|
+
/*!************************************************!*\
|
|
4369
|
+
!*** ./lib/Extensions/AppDeploy/aws-config.js ***!
|
|
4370
|
+
\************************************************/
|
|
3980
4371
|
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
3981
4372
|
|
|
3982
4373
|
__webpack_require__.r(__webpack_exports__);
|
|
@@ -4016,10 +4407,10 @@ configureAmplify();
|
|
|
4016
4407
|
|
|
4017
4408
|
/***/ }),
|
|
4018
4409
|
|
|
4019
|
-
/***/ "./lib/Extensions/
|
|
4020
|
-
|
|
4021
|
-
!*** ./lib/Extensions/
|
|
4022
|
-
|
|
4410
|
+
/***/ "./lib/Extensions/AppDeploy/fileUtils.js":
|
|
4411
|
+
/*!***********************************************!*\
|
|
4412
|
+
!*** ./lib/Extensions/AppDeploy/fileUtils.js ***!
|
|
4413
|
+
\***********************************************/
|
|
4023
4414
|
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
4024
4415
|
|
|
4025
4416
|
__webpack_require__.r(__webpack_exports__);
|
|
@@ -4084,10 +4475,10 @@ print(f"File saved successfully to ${filePath}")
|
|
|
4084
4475
|
|
|
4085
4476
|
/***/ }),
|
|
4086
4477
|
|
|
4087
|
-
/***/ "./lib/Extensions/
|
|
4088
|
-
|
|
4089
|
-
!*** ./lib/Extensions/
|
|
4090
|
-
|
|
4478
|
+
/***/ "./lib/Extensions/AppDeploy/requirementsUtils.js":
|
|
4479
|
+
/*!*******************************************************!*\
|
|
4480
|
+
!*** ./lib/Extensions/AppDeploy/requirementsUtils.js ***!
|
|
4481
|
+
\*******************************************************/
|
|
4091
4482
|
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
4092
4483
|
|
|
4093
4484
|
__webpack_require__.r(__webpack_exports__);
|
|
@@ -4111,70 +4502,77 @@ const generateRequirementsTxt = async (notebookTracker) => {
|
|
|
4111
4502
|
// Use the kernel to execute Python code using pipreqs
|
|
4112
4503
|
const session = notebookPanel.sessionContext.session;
|
|
4113
4504
|
if (session) {
|
|
4114
|
-
|
|
4115
|
-
|
|
4116
|
-
let codeContent = '';
|
|
4117
|
-
// Gather all code cells content
|
|
4118
|
-
notebook.widgets.forEach(cell => {
|
|
4119
|
-
if (cell.model.type === 'code') {
|
|
4120
|
-
const source = cell.model.sharedModel.source;
|
|
4121
|
-
// Filter out lines that start with shell commands
|
|
4122
|
-
const filteredLines = source.split('\n').filter(line => {
|
|
4123
|
-
const trimmed = line.trim();
|
|
4124
|
-
return !trimmed.startsWith('!') && !trimmed.startsWith('%');
|
|
4125
|
-
});
|
|
4126
|
-
if (filteredLines.length > 0) {
|
|
4127
|
-
codeContent += filteredLines.join('\n') + '\n\n';
|
|
4128
|
-
}
|
|
4129
|
-
}
|
|
4130
|
-
});
|
|
4131
|
-
// Create Python code to run pipreqs on a temporary directory
|
|
4505
|
+
const appPyPath = `app.py`;
|
|
4506
|
+
// Create Python code to run pipreqs on the app.py file
|
|
4132
4507
|
const pythonCode = `
|
|
4133
4508
|
import subprocess
|
|
4134
4509
|
import os
|
|
4135
|
-
|
|
4136
|
-
|
|
4137
|
-
|
|
4138
|
-
|
|
4139
|
-
|
|
4140
|
-
|
|
4141
|
-
|
|
4142
|
-
|
|
4143
|
-
|
|
4144
|
-
|
|
4145
|
-
|
|
4146
|
-
|
|
4147
|
-
#
|
|
4148
|
-
|
|
4149
|
-
|
|
4150
|
-
|
|
4151
|
-
|
|
4152
|
-
|
|
4153
|
-
|
|
4154
|
-
|
|
4155
|
-
|
|
4156
|
-
|
|
4157
|
-
|
|
4158
|
-
|
|
4159
|
-
|
|
4160
|
-
|
|
4161
|
-
|
|
4162
|
-
|
|
4163
|
-
|
|
4164
|
-
|
|
4165
|
-
|
|
4166
|
-
|
|
4167
|
-
|
|
4168
|
-
|
|
4169
|
-
|
|
4170
|
-
|
|
4171
|
-
|
|
4172
|
-
|
|
4173
|
-
|
|
4174
|
-
|
|
4175
|
-
|
|
4176
|
-
|
|
4177
|
-
|
|
4510
|
+
|
|
4511
|
+
# Check if app.py exists in the notebook directory
|
|
4512
|
+
app_py_path = os.path.join(os.getcwd(), "${appPyPath}")
|
|
4513
|
+
if not os.path.exists(app_py_path):
|
|
4514
|
+
print(f"Error: app.py not found at {app_py_path}")
|
|
4515
|
+
exit(1)
|
|
4516
|
+
|
|
4517
|
+
# Make sure pipreqs is installed. Then
|
|
4518
|
+
# 1. Create a requirements.in file
|
|
4519
|
+
# 2. From the requirements.in file, generate the requirements.txt file with the canonical PyPI name of the packages
|
|
4520
|
+
# and the versions as they exist on the user's terminal
|
|
4521
|
+
try:
|
|
4522
|
+
# Run pipreqs on the directory containing app.py
|
|
4523
|
+
notebook_dir = os.path.dirname(app_py_path)
|
|
4524
|
+
generate_req_in_file = subprocess.run(
|
|
4525
|
+
['pipreqs', '--encoding=utf-8', '--savepath', 'requirements.in', '--force', notebook_dir],
|
|
4526
|
+
capture_output=True,
|
|
4527
|
+
text=True
|
|
4528
|
+
)
|
|
4529
|
+
|
|
4530
|
+
print("Log: ", generate_req_in_file.stderr)
|
|
4531
|
+
|
|
4532
|
+
# Read requirements.in and process each line
|
|
4533
|
+
requirements_in_path = os.path.join(notebook_dir, 'requirements.in')
|
|
4534
|
+
if os.path.exists(requirements_in_path):
|
|
4535
|
+
with open(requirements_in_path, 'r') as f:
|
|
4536
|
+
lines = f.readlines()
|
|
4537
|
+
|
|
4538
|
+
processed_requirements = []
|
|
4539
|
+
for line in lines:
|
|
4540
|
+
line = line.strip()
|
|
4541
|
+
if not line:
|
|
4542
|
+
continue
|
|
4543
|
+
|
|
4544
|
+
# Extract package name (everything before =)
|
|
4545
|
+
pkg_name = line.split('=')[0].strip()
|
|
4546
|
+
|
|
4547
|
+
# Get package info using pip show
|
|
4548
|
+
try:
|
|
4549
|
+
result = subprocess.run(['pip', 'show', pkg_name],
|
|
4550
|
+
capture_output=True, text=True, check=True)
|
|
4551
|
+
output = result.stdout
|
|
4552
|
+
|
|
4553
|
+
# Parse the output to get Name and Version
|
|
4554
|
+
name = None
|
|
4555
|
+
version = None
|
|
4556
|
+
for output_line in output.split('\\n'):
|
|
4557
|
+
if output_line.startswith('Name:'):
|
|
4558
|
+
name = output_line.split(':', 1)[1].strip()
|
|
4559
|
+
elif output_line.startswith('Version:'):
|
|
4560
|
+
version = output_line.split(':', 1)[1].strip()
|
|
4561
|
+
|
|
4562
|
+
if name and version:
|
|
4563
|
+
processed_requirements.append(f"{name}=={version}")
|
|
4564
|
+
else:
|
|
4565
|
+
processed_requirements.append(line)
|
|
4566
|
+
except subprocess.CalledProcessError:
|
|
4567
|
+
# If pip show fails, use the original line
|
|
4568
|
+
processed_requirements.append(line)
|
|
4569
|
+
|
|
4570
|
+
# Print the processed requirements
|
|
4571
|
+
for req in processed_requirements:
|
|
4572
|
+
print(req)
|
|
4573
|
+
|
|
4574
|
+
except Exception as e:
|
|
4575
|
+
print(f"Error running pipreqs: {e}")
|
|
4178
4576
|
`;
|
|
4179
4577
|
const kernel = session.kernel;
|
|
4180
4578
|
if (kernel === null) {
|
|
@@ -4196,6 +4594,7 @@ with tempfile.TemporaryDirectory() as temp_dir:
|
|
|
4196
4594
|
console.error(text);
|
|
4197
4595
|
}
|
|
4198
4596
|
else {
|
|
4597
|
+
console.log('Found dependencies:\n', text);
|
|
4199
4598
|
resultText += text;
|
|
4200
4599
|
}
|
|
4201
4600
|
}
|
|
@@ -4240,7 +4639,7 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
4240
4639
|
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
|
|
4241
4640
|
/* harmony import */ var _jupyterlab_ui_components__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @jupyterlab/ui-components */ "webpack/sharing/consume/default/@jupyterlab/ui-components");
|
|
4242
4641
|
/* harmony import */ var _jupyterlab_ui_components__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_jupyterlab_ui_components__WEBPACK_IMPORTED_MODULE_1__);
|
|
4243
|
-
/* harmony import */ var
|
|
4642
|
+
/* harmony import */ var _AppDeploy_auth__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../AppDeploy/auth */ "./lib/Extensions/AppDeploy/auth.js");
|
|
4244
4643
|
/* harmony import */ var _ListAppsAPI__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./ListAppsAPI */ "./lib/Extensions/AppManager/ListAppsAPI.js");
|
|
4245
4644
|
/* harmony import */ var _style_AppsList_css__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../../style/AppsList.css */ "./style/AppsList.css");
|
|
4246
4645
|
/*
|
|
@@ -4337,7 +4736,7 @@ const AppsList = ({ appManagerService }) => {
|
|
|
4337
4736
|
react__WEBPACK_IMPORTED_MODULE_0__.createElement("button", { onClick: refreshApps, disabled: loading, className: "apps-list-button", title: "Refresh apps" }, loading ? 'Loading...' : 'Refresh'),
|
|
4338
4737
|
react__WEBPACK_IMPORTED_MODULE_0__.createElement("button", { onClick: () => {
|
|
4339
4738
|
console.log('Logout clicked');
|
|
4340
|
-
void (0,
|
|
4739
|
+
void (0,_AppDeploy_auth__WEBPACK_IMPORTED_MODULE_4__.logoutAndClearJWTTokens)();
|
|
4341
4740
|
}, className: "apps-list-button", title: "Logout" }, "Logout"))),
|
|
4342
4741
|
loading ? (react__WEBPACK_IMPORTED_MODULE_0__.createElement("div", { className: "apps-list-loading" }, "Loading apps...")) : error ? (react__WEBPACK_IMPORTED_MODULE_0__.createElement("div", { className: "apps-list-error" },
|
|
4343
4742
|
"Error: ",
|
|
@@ -4360,6 +4759,49 @@ const AppsList = ({ appManagerService }) => {
|
|
|
4360
4759
|
};
|
|
4361
4760
|
|
|
4362
4761
|
|
|
4762
|
+
/***/ }),
|
|
4763
|
+
|
|
4764
|
+
/***/ "./lib/Extensions/AppManager/CheckAppStatusAPI.js":
|
|
4765
|
+
/*!********************************************************!*\
|
|
4766
|
+
!*** ./lib/Extensions/AppManager/CheckAppStatusAPI.js ***!
|
|
4767
|
+
\********************************************************/
|
|
4768
|
+
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
4769
|
+
|
|
4770
|
+
__webpack_require__.r(__webpack_exports__);
|
|
4771
|
+
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
4772
|
+
/* harmony export */ checkAppStatus: () => (/* binding */ checkAppStatus)
|
|
4773
|
+
/* harmony export */ });
|
|
4774
|
+
/*
|
|
4775
|
+
* Copyright (c) Saga Inc.
|
|
4776
|
+
* Distributed under the terms of the GNU Affero General Public License v3.0 License.
|
|
4777
|
+
*/
|
|
4778
|
+
/**
|
|
4779
|
+
* Check if an app URL is accessible through the backend.
|
|
4780
|
+
*/
|
|
4781
|
+
const checkAppStatus = async (appUrl, appManagerService) => {
|
|
4782
|
+
try {
|
|
4783
|
+
// Create the request message with proper typing
|
|
4784
|
+
const request = {
|
|
4785
|
+
type: 'check-app-status',
|
|
4786
|
+
app_url: appUrl
|
|
4787
|
+
};
|
|
4788
|
+
// Using websocket service
|
|
4789
|
+
const response = await appManagerService.client.sendMessage(request);
|
|
4790
|
+
// Check if the response indicates an error
|
|
4791
|
+
if (response.error) {
|
|
4792
|
+
console.error('Error checking app status:', response.error.title);
|
|
4793
|
+
return false;
|
|
4794
|
+
}
|
|
4795
|
+
console.log('App is accessible:', response.is_accessible);
|
|
4796
|
+
return response.is_accessible;
|
|
4797
|
+
}
|
|
4798
|
+
catch (error) {
|
|
4799
|
+
console.error('Error checking app status:', error);
|
|
4800
|
+
return false;
|
|
4801
|
+
}
|
|
4802
|
+
};
|
|
4803
|
+
|
|
4804
|
+
|
|
4363
4805
|
/***/ }),
|
|
4364
4806
|
|
|
4365
4807
|
/***/ "./lib/Extensions/AppManager/ListAppsAPI.js":
|
|
@@ -4374,7 +4816,7 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
4374
4816
|
/* harmony export */ isGetAppsFailure: () => (/* binding */ isGetAppsFailure),
|
|
4375
4817
|
/* harmony export */ isGetAppsSuccess: () => (/* binding */ isGetAppsSuccess)
|
|
4376
4818
|
/* harmony export */ });
|
|
4377
|
-
/* harmony import */ var
|
|
4819
|
+
/* harmony import */ var _AppDeploy_auth__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../AppDeploy/auth */ "./lib/Extensions/AppDeploy/auth.js");
|
|
4378
4820
|
/*
|
|
4379
4821
|
* Copyright (c) Saga Inc.
|
|
4380
4822
|
* Distributed under the terms of the GNU Affero General Public License v3.0 License.
|
|
@@ -4389,7 +4831,7 @@ const isGetAppsFailure = (response) => {
|
|
|
4389
4831
|
};
|
|
4390
4832
|
const fetchUserApps = async (appManagerService) => {
|
|
4391
4833
|
try {
|
|
4392
|
-
const jwtToken = await (0,
|
|
4834
|
+
const jwtToken = await (0,_AppDeploy_auth__WEBPACK_IMPORTED_MODULE_0__.getJWTToken)();
|
|
4393
4835
|
if (!jwtToken) {
|
|
4394
4836
|
return {
|
|
4395
4837
|
success: false,
|
|
@@ -4530,6 +4972,211 @@ const ManageAppsPlugin = {
|
|
|
4530
4972
|
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (ManageAppsPlugin);
|
|
4531
4973
|
|
|
4532
4974
|
|
|
4975
|
+
/***/ }),
|
|
4976
|
+
|
|
4977
|
+
/***/ "./lib/Extensions/AppPreview/StreamlitPreviewPlugin.js":
|
|
4978
|
+
/*!*************************************************************!*\
|
|
4979
|
+
!*** ./lib/Extensions/AppPreview/StreamlitPreviewPlugin.js ***!
|
|
4980
|
+
\*************************************************************/
|
|
4981
|
+
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
4982
|
+
|
|
4983
|
+
__webpack_require__.r(__webpack_exports__);
|
|
4984
|
+
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
4985
|
+
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
|
|
4986
|
+
/* harmony export */ });
|
|
4987
|
+
/* harmony import */ var _jupyterlab_notebook__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @jupyterlab/notebook */ "webpack/sharing/consume/default/@jupyterlab/notebook");
|
|
4988
|
+
/* harmony import */ var _jupyterlab_notebook__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_jupyterlab_notebook__WEBPACK_IMPORTED_MODULE_0__);
|
|
4989
|
+
/* harmony import */ var _jupyterlab_apputils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @jupyterlab/apputils */ "webpack/sharing/consume/default/@jupyterlab/apputils");
|
|
4990
|
+
/* harmony import */ var _jupyterlab_apputils__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_jupyterlab_apputils__WEBPACK_IMPORTED_MODULE_1__);
|
|
4991
|
+
/* harmony import */ var _jupyterlab_coreutils__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @jupyterlab/coreutils */ "webpack/sharing/consume/default/@jupyterlab/coreutils");
|
|
4992
|
+
/* harmony import */ var _jupyterlab_coreutils__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_jupyterlab_coreutils__WEBPACK_IMPORTED_MODULE_2__);
|
|
4993
|
+
/* harmony import */ var _lumino_widgets__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @lumino/widgets */ "webpack/sharing/consume/default/@lumino/widgets");
|
|
4994
|
+
/* harmony import */ var _lumino_widgets__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_lumino_widgets__WEBPACK_IMPORTED_MODULE_3__);
|
|
4995
|
+
/* harmony import */ var _restAPI_RestAPI__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../../restAPI/RestAPI */ "./lib/restAPI/RestAPI.js");
|
|
4996
|
+
/* harmony import */ var _AppDeploy_DeployStreamlitApp__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../AppDeploy/DeployStreamlitApp */ "./lib/Extensions/AppDeploy/DeployStreamlitApp.js");
|
|
4997
|
+
/* harmony import */ var _AppDeploy_AppDeployPlugin__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../AppDeploy/AppDeployPlugin */ "./lib/Extensions/AppDeploy/AppDeployPlugin.js");
|
|
4998
|
+
/* harmony import */ var _AppManager_ManageAppsPlugin__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../AppManager/ManageAppsPlugin */ "./lib/Extensions/AppManager/ManageAppsPlugin.js");
|
|
4999
|
+
/* harmony import */ var _commands__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../../commands */ "./lib/commands.js");
|
|
5000
|
+
/* harmony import */ var _icons__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../../icons */ "./lib/icons/index.js");
|
|
5001
|
+
/* harmony import */ var _style_StreamlitPreviewPlugin_css__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../../style/StreamlitPreviewPlugin.css */ "./style/StreamlitPreviewPlugin.css");
|
|
5002
|
+
/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./utils */ "./lib/Extensions/AppPreview/utils.js");
|
|
5003
|
+
/*
|
|
5004
|
+
* Copyright (c) Saga Inc.
|
|
5005
|
+
* Distributed under the terms of the GNU Affero General Public License v3.0 License.
|
|
5006
|
+
*/
|
|
5007
|
+
|
|
5008
|
+
|
|
5009
|
+
|
|
5010
|
+
|
|
5011
|
+
|
|
5012
|
+
|
|
5013
|
+
|
|
5014
|
+
|
|
5015
|
+
|
|
5016
|
+
|
|
5017
|
+
|
|
5018
|
+
|
|
5019
|
+
|
|
5020
|
+
|
|
5021
|
+
/**
|
|
5022
|
+
* Simple HTML widget for displaying iframe content.
|
|
5023
|
+
*/
|
|
5024
|
+
class IFrameWidget extends _lumino_widgets__WEBPACK_IMPORTED_MODULE_3__.Widget {
|
|
5025
|
+
constructor(url) {
|
|
5026
|
+
super();
|
|
5027
|
+
this.addClass('jp-iframe-widget');
|
|
5028
|
+
const iframe = document.createElement('iframe');
|
|
5029
|
+
iframe.src = url;
|
|
5030
|
+
iframe.style.width = '100%';
|
|
5031
|
+
iframe.style.height = '100%';
|
|
5032
|
+
iframe.style.border = 'none';
|
|
5033
|
+
this.node.appendChild(iframe);
|
|
5034
|
+
}
|
|
5035
|
+
setUrl(url) {
|
|
5036
|
+
const iframe = this.node.querySelector('iframe');
|
|
5037
|
+
if (iframe) {
|
|
5038
|
+
iframe.src = url;
|
|
5039
|
+
}
|
|
5040
|
+
}
|
|
5041
|
+
}
|
|
5042
|
+
/**
|
|
5043
|
+
* The streamlit preview plugin.
|
|
5044
|
+
*/
|
|
5045
|
+
const StreamlitPreviewPlugin = {
|
|
5046
|
+
id: 'mito-ai:streamlit-preview',
|
|
5047
|
+
autoStart: true,
|
|
5048
|
+
requires: [_jupyterlab_notebook__WEBPACK_IMPORTED_MODULE_0__.INotebookTracker, _jupyterlab_apputils__WEBPACK_IMPORTED_MODULE_1__.ICommandPalette, _AppDeploy_AppDeployPlugin__WEBPACK_IMPORTED_MODULE_5__.IAppDeployService, _AppManager_ManageAppsPlugin__WEBPACK_IMPORTED_MODULE_6__.IAppManagerService],
|
|
5049
|
+
activate: (app, notebookTracker, palette, appDeployService, appManagerService) => {
|
|
5050
|
+
console.log('mito-ai: StreamlitPreviewPlugin activated');
|
|
5051
|
+
// Add command to command palette
|
|
5052
|
+
app.commands.addCommand(_commands__WEBPACK_IMPORTED_MODULE_7__.COMMAND_MITO_AI_PREVIEW_AS_STREAMLIT, {
|
|
5053
|
+
label: 'Preview as Streamlit',
|
|
5054
|
+
caption: 'Convert current notebook to Streamlit app and preview it',
|
|
5055
|
+
execute: async () => {
|
|
5056
|
+
await previewNotebookAsStreamlit(app, notebookTracker, appDeployService, appManagerService);
|
|
5057
|
+
}
|
|
5058
|
+
});
|
|
5059
|
+
// Add to command palette
|
|
5060
|
+
palette.addItem({
|
|
5061
|
+
command: _commands__WEBPACK_IMPORTED_MODULE_7__.COMMAND_MITO_AI_PREVIEW_AS_STREAMLIT,
|
|
5062
|
+
category: 'Mito AI'
|
|
5063
|
+
});
|
|
5064
|
+
}
|
|
5065
|
+
};
|
|
5066
|
+
/**
|
|
5067
|
+
* Preview the current notebook as a Streamlit app.
|
|
5068
|
+
*/
|
|
5069
|
+
async function previewNotebookAsStreamlit(app, notebookTracker, appDeployService, appManagerService) {
|
|
5070
|
+
const notebookPanel = notebookTracker.currentWidget;
|
|
5071
|
+
if (!notebookPanel) {
|
|
5072
|
+
_jupyterlab_apputils__WEBPACK_IMPORTED_MODULE_1__.Notification.error('No notebook is currently active');
|
|
5073
|
+
return;
|
|
5074
|
+
}
|
|
5075
|
+
// First save the notebook to ensure the app is up to date
|
|
5076
|
+
await notebookPanel.context.save();
|
|
5077
|
+
const notebookPath = notebookPanel.context.path;
|
|
5078
|
+
const notebookName = _jupyterlab_coreutils__WEBPACK_IMPORTED_MODULE_2__.PathExt.basename(notebookPath, '.ipynb');
|
|
5079
|
+
let globalNotificationId;
|
|
5080
|
+
try {
|
|
5081
|
+
const { previewData, notificationId } = await (0,_utils__WEBPACK_IMPORTED_MODULE_8__.startStreamlitPreviewAndNotify)(notebookPath);
|
|
5082
|
+
globalNotificationId = notificationId;
|
|
5083
|
+
// Create iframe widget
|
|
5084
|
+
// TODO: Instead of having this widget creation code in the previewNotebookAsStreamlit function,
|
|
5085
|
+
// I wonder if we can make it part of the StreamlitPreviewPlugin. What we want is the following:
|
|
5086
|
+
// a react component that takes the app, notebookTracker, and appDeployService as a prop and is
|
|
5087
|
+
// already set up with this layout. Each time it opens, we're just deciding which notebook to display.
|
|
5088
|
+
const iframeWidget = new IFrameWidget(previewData.url);
|
|
5089
|
+
// Create main area widget
|
|
5090
|
+
const widget = new _jupyterlab_apputils__WEBPACK_IMPORTED_MODULE_1__.MainAreaWidget({ content: iframeWidget });
|
|
5091
|
+
widget.title.label = `App Preview (${notebookName})`;
|
|
5092
|
+
widget.title.closable = true;
|
|
5093
|
+
// Add toolbar button to the MainAreaWidget's toolbar
|
|
5094
|
+
const deployButton = new _jupyterlab_apputils__WEBPACK_IMPORTED_MODULE_1__.ToolbarButton({
|
|
5095
|
+
className: 'text-button-mito-ai button-base button-small jp-ToolbarButton mito-deploy-button',
|
|
5096
|
+
onClick: () => {
|
|
5097
|
+
void (0,_AppDeploy_DeployStreamlitApp__WEBPACK_IMPORTED_MODULE_9__.deployStreamlitApp)(notebookTracker, appDeployService, appManagerService);
|
|
5098
|
+
},
|
|
5099
|
+
tooltip: 'Deploy Streamlit App',
|
|
5100
|
+
label: 'Deploy App',
|
|
5101
|
+
icon: _icons__WEBPACK_IMPORTED_MODULE_10__.DeployLabIcon,
|
|
5102
|
+
iconClass: 'mito-ai-deploy-icon'
|
|
5103
|
+
});
|
|
5104
|
+
// Add toolbar button to the MainAreaWidget's toolbar
|
|
5105
|
+
const refreshButton = new _jupyterlab_apputils__WEBPACK_IMPORTED_MODULE_1__.ToolbarButton({
|
|
5106
|
+
className: 'text-button-mito-ai button-base button-small jp-ToolbarButton mito-deploy-button',
|
|
5107
|
+
onClick: () => {
|
|
5108
|
+
void (0,_utils__WEBPACK_IMPORTED_MODULE_8__.startStreamlitPreviewAndNotify)(notebookPath, true);
|
|
5109
|
+
},
|
|
5110
|
+
tooltip: 'Rebuild Streamlit App',
|
|
5111
|
+
label: 'Rebuild App',
|
|
5112
|
+
icon: _icons__WEBPACK_IMPORTED_MODULE_10__.DeployLabIcon,
|
|
5113
|
+
iconClass: 'mito-ai-deploy-icon'
|
|
5114
|
+
});
|
|
5115
|
+
// Insert the button into the toolbar
|
|
5116
|
+
widget.toolbar.insertAfter('spacer', 'refresh-app-button', refreshButton);
|
|
5117
|
+
widget.toolbar.insertAfter('spacer', 'deploy-app-button', deployButton);
|
|
5118
|
+
// Handle widget disposal
|
|
5119
|
+
widget.disposed.connect(() => {
|
|
5120
|
+
console.log('Widget disposed, stopping preview');
|
|
5121
|
+
void (0,_restAPI_RestAPI__WEBPACK_IMPORTED_MODULE_11__.stopStreamlitPreview)(previewData.id);
|
|
5122
|
+
});
|
|
5123
|
+
// Add widget to main area with split-right mode
|
|
5124
|
+
app.shell.add(widget, 'main', {
|
|
5125
|
+
mode: 'split-right',
|
|
5126
|
+
ref: notebookPanel.id
|
|
5127
|
+
});
|
|
5128
|
+
}
|
|
5129
|
+
catch (error) {
|
|
5130
|
+
console.error('Error starting streamlit preview:', error);
|
|
5131
|
+
// Update notification to error
|
|
5132
|
+
if (globalNotificationId) {
|
|
5133
|
+
_jupyterlab_apputils__WEBPACK_IMPORTED_MODULE_1__.Notification.update({
|
|
5134
|
+
id: globalNotificationId,
|
|
5135
|
+
message: `Failed to start preview: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
5136
|
+
type: 'error',
|
|
5137
|
+
autoClose: false
|
|
5138
|
+
});
|
|
5139
|
+
}
|
|
5140
|
+
}
|
|
5141
|
+
}
|
|
5142
|
+
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (StreamlitPreviewPlugin);
|
|
5143
|
+
|
|
5144
|
+
|
|
5145
|
+
/***/ }),
|
|
5146
|
+
|
|
5147
|
+
/***/ "./lib/Extensions/AppPreview/utils.js":
|
|
5148
|
+
/*!********************************************!*\
|
|
5149
|
+
!*** ./lib/Extensions/AppPreview/utils.js ***!
|
|
5150
|
+
\********************************************/
|
|
5151
|
+
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
5152
|
+
|
|
5153
|
+
__webpack_require__.r(__webpack_exports__);
|
|
5154
|
+
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
5155
|
+
/* harmony export */ startStreamlitPreviewAndNotify: () => (/* binding */ startStreamlitPreviewAndNotify)
|
|
5156
|
+
/* harmony export */ });
|
|
5157
|
+
/* harmony import */ var _restAPI_RestAPI__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../restAPI/RestAPI */ "./lib/restAPI/RestAPI.js");
|
|
5158
|
+
/* harmony import */ var _jupyterlab_apputils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @jupyterlab/apputils */ "webpack/sharing/consume/default/@jupyterlab/apputils");
|
|
5159
|
+
/* harmony import */ var _jupyterlab_apputils__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_jupyterlab_apputils__WEBPACK_IMPORTED_MODULE_0__);
|
|
5160
|
+
/*
|
|
5161
|
+
* Copyright (c) Saga Inc.
|
|
5162
|
+
* Distributed under the terms of the GNU Affero General Public License v3.0 License.
|
|
5163
|
+
*/
|
|
5164
|
+
|
|
5165
|
+
|
|
5166
|
+
const startStreamlitPreviewAndNotify = async (notebookPath, force_recreate = false) => {
|
|
5167
|
+
const notificationId = _jupyterlab_apputils__WEBPACK_IMPORTED_MODULE_0__.Notification.emit('Building App Preview...', 'in-progress', { autoClose: false });
|
|
5168
|
+
const previewData = await (0,_restAPI_RestAPI__WEBPACK_IMPORTED_MODULE_1__.startStreamlitPreview)(notebookPath, force_recreate);
|
|
5169
|
+
// Update notification to success
|
|
5170
|
+
_jupyterlab_apputils__WEBPACK_IMPORTED_MODULE_0__.Notification.update({
|
|
5171
|
+
id: notificationId,
|
|
5172
|
+
message: 'Streamlit preview started successfully!',
|
|
5173
|
+
type: 'default',
|
|
5174
|
+
autoClose: 5 * 1000
|
|
5175
|
+
});
|
|
5176
|
+
return { previewData, notificationId };
|
|
5177
|
+
};
|
|
5178
|
+
|
|
5179
|
+
|
|
4533
5180
|
/***/ }),
|
|
4534
5181
|
|
|
4535
5182
|
/***/ "./lib/Extensions/ContextManager/ContextManagerPlugin.js":
|
|
@@ -4565,37 +5212,31 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
4565
5212
|
const IContextManager = new _lumino_coreutils__WEBPACK_IMPORTED_MODULE_1__.Token('mito-ai:IContextManager');
|
|
4566
5213
|
class ContextManager {
|
|
4567
5214
|
constructor(app, notebookTracker) {
|
|
4568
|
-
this.
|
|
4569
|
-
this.
|
|
4570
|
-
|
|
4571
|
-
this.setupKernelListener(app, notebookTracker);
|
|
4572
|
-
}
|
|
4573
|
-
get variables() {
|
|
4574
|
-
return this._variables;
|
|
4575
|
-
}
|
|
4576
|
-
setVariables(newVars) {
|
|
4577
|
-
this._variables = newVars;
|
|
4578
|
-
}
|
|
4579
|
-
get files() {
|
|
4580
|
-
return this._files;
|
|
4581
|
-
}
|
|
4582
|
-
setFiles(newFiles) {
|
|
4583
|
-
this._files = newFiles;
|
|
4584
|
-
}
|
|
4585
|
-
// Setup kernel execution listener
|
|
4586
|
-
setupKernelListener(app, notebookTracker) {
|
|
4587
|
-
notebookTracker.currentChanged.connect(async (tracker, notebookPanel) => {
|
|
4588
|
-
if (!notebookPanel) {
|
|
5215
|
+
this.notebookContexts = new Map();
|
|
5216
|
+
this._startKernelListener = async (app, notebookPanel) => {
|
|
5217
|
+
if (notebookPanel === null) {
|
|
4589
5218
|
return;
|
|
4590
5219
|
}
|
|
4591
|
-
//
|
|
5220
|
+
// Initialize context for this notebook if it doesn't exist
|
|
5221
|
+
if (!this.notebookContexts.has(notebookPanel.id)) {
|
|
5222
|
+
this.notebookContexts.set(notebookPanel.id, { variables: [], files: [] });
|
|
5223
|
+
}
|
|
5224
|
+
// As soon as the notebook is opened, fetch the files since these are not related to the kernel,
|
|
5225
|
+
// but to the notebook itself. This is useful so we can tell the agent which files are available
|
|
5226
|
+
// or let the user select a file from the dropdown menu before the kernel is started.
|
|
5227
|
+
// We use the notebookPanel.id to identify the notebook because we might need to access
|
|
5228
|
+
// NotebookContext even before the kernel is started. For example, to figure out
|
|
5229
|
+
// which files are available.
|
|
5230
|
+
const updatedFiles = await (0,_FileInspector__WEBPACK_IMPORTED_MODULE_2__.getFiles)(app, notebookPanel);
|
|
5231
|
+
this.updateNotebookFiles(notebookPanel.id, updatedFiles);
|
|
5232
|
+
// Listen for kernel restart or shut down events and clear the variables for this notebook
|
|
4592
5233
|
notebookPanel.context.sessionContext.statusChanged.connect((sender, status) => {
|
|
4593
|
-
if (status === 'restarting') {
|
|
4594
|
-
|
|
5234
|
+
if (status === 'restarting' || status === 'terminating' || status === 'unknown') {
|
|
5235
|
+
// Clear the variables for this specific notebook, but don't clear the files
|
|
5236
|
+
// as they have not changed.
|
|
5237
|
+
this.updateNotebookVariables(notebookPanel.id, []); // Clear variables for this specific notebook
|
|
4595
5238
|
}
|
|
4596
5239
|
});
|
|
4597
|
-
// As soon as the notebook is opened, fetch the files so we don't have to wait for the first message.
|
|
4598
|
-
await (0,_FileInspector__WEBPACK_IMPORTED_MODULE_2__.fetchFilesAndUpdateState)(app, notebookTracker, this.setFiles.bind(this));
|
|
4599
5240
|
// Listen to kernel messages
|
|
4600
5241
|
notebookPanel.context.sessionContext.iopubMessage.connect(async (sender, msg) => {
|
|
4601
5242
|
// Watch for execute_input messages, which indicate is a request to execute code.
|
|
@@ -4603,11 +5244,46 @@ class ContextManager {
|
|
|
4603
5244
|
// from the kernel when a code cell prints a value to the output cell, which is not what we want.
|
|
4604
5245
|
// TODO: Check if there is a race condition where we might end up fetching variables before the
|
|
4605
5246
|
// code is executed. I don't think this is the case because the kernel runs in one thread I believe.
|
|
5247
|
+
// TODO: Eventually we should create a document manager listener so if the user uploads a new file
|
|
5248
|
+
// to jupyter, we can update the available files even if they have not executed a kernel message.
|
|
4606
5249
|
if (msg.header.msg_type === 'execute_input') {
|
|
4607
|
-
|
|
4608
|
-
await (0,_FileInspector__WEBPACK_IMPORTED_MODULE_2__.
|
|
5250
|
+
void (0,_VariableInspector__WEBPACK_IMPORTED_MODULE_3__.fetchVariablesAndUpdateState)(notebookPanel, this.updateNotebookVariables.bind(this, notebookPanel.id));
|
|
5251
|
+
const updatedFiles = await (0,_FileInspector__WEBPACK_IMPORTED_MODULE_2__.getFiles)(app, notebookPanel);
|
|
5252
|
+
this.updateNotebookFiles(notebookPanel.id, updatedFiles);
|
|
4609
5253
|
}
|
|
4610
5254
|
});
|
|
5255
|
+
};
|
|
5256
|
+
this.notebookTracker = notebookTracker;
|
|
5257
|
+
// Setup the kernel listener to update context as kernel messages are received
|
|
5258
|
+
this.setupKernelListener(app, notebookTracker);
|
|
5259
|
+
}
|
|
5260
|
+
getNotebookContext(notebookId) {
|
|
5261
|
+
return this.notebookContexts.get(notebookId);
|
|
5262
|
+
}
|
|
5263
|
+
getActiveNotebookContext() {
|
|
5264
|
+
const activeNotebook = this.notebookTracker.currentWidget;
|
|
5265
|
+
if (!activeNotebook)
|
|
5266
|
+
return undefined;
|
|
5267
|
+
return this.getNotebookContext(activeNotebook.id);
|
|
5268
|
+
}
|
|
5269
|
+
updateNotebookVariables(notebookID, variables) {
|
|
5270
|
+
const context = this.notebookContexts.get(notebookID) || { variables: [], files: [] };
|
|
5271
|
+
context.variables = variables;
|
|
5272
|
+
this.notebookContexts.set(notebookID, context);
|
|
5273
|
+
}
|
|
5274
|
+
updateNotebookFiles(notebookID, files) {
|
|
5275
|
+
const context = this.notebookContexts.get(notebookID) || { variables: [], files: [] };
|
|
5276
|
+
context.files = files;
|
|
5277
|
+
this.notebookContexts.set(notebookID, context);
|
|
5278
|
+
}
|
|
5279
|
+
// Setup kernel execution listener
|
|
5280
|
+
setupKernelListener(app, notebookTracker) {
|
|
5281
|
+
// Start the kernel listener for the currently active notebook
|
|
5282
|
+
const notebookPanel = notebookTracker.currentWidget;
|
|
5283
|
+
void this._startKernelListener(app, notebookPanel);
|
|
5284
|
+
// Update the kernel listener whenever the active notebook changes
|
|
5285
|
+
notebookTracker.currentChanged.connect(async (_, notebookPanel) => {
|
|
5286
|
+
void this._startKernelListener(app, notebookPanel);
|
|
4611
5287
|
});
|
|
4612
5288
|
}
|
|
4613
5289
|
}
|
|
@@ -4634,7 +5310,7 @@ const ContextManagerPlugin = {
|
|
|
4634
5310
|
|
|
4635
5311
|
__webpack_require__.r(__webpack_exports__);
|
|
4636
5312
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
4637
|
-
/* harmony export */
|
|
5313
|
+
/* harmony export */ getFiles: () => (/* binding */ getFiles)
|
|
4638
5314
|
/* harmony export */ });
|
|
4639
5315
|
/* harmony import */ var _jupyterlab_coreutils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @jupyterlab/coreutils */ "webpack/sharing/consume/default/@jupyterlab/coreutils");
|
|
4640
5316
|
/* harmony import */ var _jupyterlab_coreutils__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_jupyterlab_coreutils__WEBPACK_IMPORTED_MODULE_0__);
|
|
@@ -4646,15 +5322,9 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
4646
5322
|
/*
|
|
4647
5323
|
Fetches all files in the current directory and updates the state of the files.
|
|
4648
5324
|
*/
|
|
4649
|
-
const
|
|
5325
|
+
const getFiles = async (app, notebookPanel) => {
|
|
4650
5326
|
const fileManager = app.serviceManager.contents;
|
|
4651
|
-
|
|
4652
|
-
const currentNotebook = notebookTracker.currentWidget;
|
|
4653
|
-
if (!currentNotebook) {
|
|
4654
|
-
return;
|
|
4655
|
-
}
|
|
4656
|
-
// Get the directory path using PathExt.dirname from @jupyterlab/coreutils
|
|
4657
|
-
const relativeNotebookPath = currentNotebook.context.path;
|
|
5327
|
+
const relativeNotebookPath = notebookPanel.context.path;
|
|
4658
5328
|
const relativeDirectoryPath = _jupyterlab_coreutils__WEBPACK_IMPORTED_MODULE_0__.PathExt.dirname(relativeNotebookPath);
|
|
4659
5329
|
try {
|
|
4660
5330
|
const contents = await fileManager.get(relativeDirectoryPath);
|
|
@@ -4673,16 +5343,16 @@ const fetchFilesAndUpdateState = async (app, notebookTracker, setFiles) => {
|
|
|
4673
5343
|
file_name: file.name
|
|
4674
5344
|
}));
|
|
4675
5345
|
// Update the state of the files
|
|
4676
|
-
|
|
5346
|
+
return files;
|
|
4677
5347
|
}
|
|
4678
5348
|
else {
|
|
4679
5349
|
// If the contents are not a directory, set the files to an empty array
|
|
4680
|
-
|
|
5350
|
+
return [];
|
|
4681
5351
|
}
|
|
4682
5352
|
}
|
|
4683
5353
|
catch (error) {
|
|
4684
5354
|
console.error('Error listing directory contents:', error);
|
|
4685
|
-
return;
|
|
5355
|
+
return [];
|
|
4686
5356
|
}
|
|
4687
5357
|
};
|
|
4688
5358
|
|
|
@@ -4819,7 +5489,9 @@ def structured_globals():
|
|
|
4819
5489
|
|
|
4820
5490
|
print(structured_globals())
|
|
4821
5491
|
`;
|
|
4822
|
-
|
|
5492
|
+
/*
|
|
5493
|
+
Function to fetch variables and sync with the frontend
|
|
5494
|
+
*/
|
|
4823
5495
|
function fetchVariablesAndUpdateState(notebookPanel, setVariables) {
|
|
4824
5496
|
var _a;
|
|
4825
5497
|
const kernel = (_a = notebookPanel.context.sessionContext.session) === null || _a === void 0 ? void 0 : _a.kernel;
|
|
@@ -4835,7 +5507,7 @@ function fetchVariablesAndUpdateState(notebookPanel, setVariables) {
|
|
|
4835
5507
|
// Listen for the output from the kernel
|
|
4836
5508
|
future.onIOPub = (msg) => {
|
|
4837
5509
|
// A 'stream' message represents standard output (stdout) or standard error (stderr) produced
|
|
4838
|
-
// during the execution of code in the kernel.
|
|
5510
|
+
// during the execution of code in the kernel.
|
|
4839
5511
|
if (_jupyterlab_services__WEBPACK_IMPORTED_MODULE_0__.KernelMessage.isStreamMsg(msg)) {
|
|
4840
5512
|
if (msg.content.name === 'stdout') {
|
|
4841
5513
|
try {
|
|
@@ -6214,10 +6886,11 @@ const ContextManagerSection = ({ contextManager }) => {
|
|
|
6214
6886
|
// Force a re-render by toggling the state
|
|
6215
6887
|
setRefreshKey(prev => prev + 1);
|
|
6216
6888
|
};
|
|
6889
|
+
const activeNotebookContext = contextManager.getActiveNotebookContext();
|
|
6217
6890
|
const copyContextManagerToClipboard = async () => {
|
|
6218
6891
|
const jsonContent = JSON.stringify({
|
|
6219
|
-
variables:
|
|
6220
|
-
files:
|
|
6892
|
+
variables: activeNotebookContext === null || activeNotebookContext === void 0 ? void 0 : activeNotebookContext.variables,
|
|
6893
|
+
files: activeNotebookContext === null || activeNotebookContext === void 0 ? void 0 : activeNotebookContext.files
|
|
6221
6894
|
}, null, 2);
|
|
6222
6895
|
try {
|
|
6223
6896
|
await navigator.clipboard.writeText(jsonContent);
|
|
@@ -6234,8 +6907,8 @@ const ContextManagerSection = ({ contextManager }) => {
|
|
|
6234
6907
|
react__WEBPACK_IMPORTED_MODULE_0___default().createElement("button", { className: "button-base", onClick: copyContextManagerToClipboard }, "Copy")),
|
|
6235
6908
|
refreshKey > 0 && (react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { className: "settings-option" },
|
|
6236
6909
|
react__WEBPACK_IMPORTED_MODULE_0___default().createElement("pre", { className: "json-container" }, JSON.stringify({
|
|
6237
|
-
variables:
|
|
6238
|
-
files:
|
|
6910
|
+
variables: activeNotebookContext === null || activeNotebookContext === void 0 ? void 0 : activeNotebookContext.variables,
|
|
6911
|
+
files: activeNotebookContext === null || activeNotebookContext === void 0 ? void 0 : activeNotebookContext.files
|
|
6239
6912
|
}, null, 2))))));
|
|
6240
6913
|
};
|
|
6241
6914
|
|
|
@@ -6516,142 +7189,6 @@ const SupportPage = () => {
|
|
|
6516
7189
|
};
|
|
6517
7190
|
|
|
6518
7191
|
|
|
6519
|
-
/***/ }),
|
|
6520
|
-
|
|
6521
|
-
/***/ "./lib/Extensions/StreamlitPreview/StreamlitPreviewPlugin.js":
|
|
6522
|
-
/*!*******************************************************************!*\
|
|
6523
|
-
!*** ./lib/Extensions/StreamlitPreview/StreamlitPreviewPlugin.js ***!
|
|
6524
|
-
\*******************************************************************/
|
|
6525
|
-
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
6526
|
-
|
|
6527
|
-
__webpack_require__.r(__webpack_exports__);
|
|
6528
|
-
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
6529
|
-
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
|
|
6530
|
-
/* harmony export */ });
|
|
6531
|
-
/* harmony import */ var _jupyterlab_notebook__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @jupyterlab/notebook */ "webpack/sharing/consume/default/@jupyterlab/notebook");
|
|
6532
|
-
/* harmony import */ var _jupyterlab_notebook__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_jupyterlab_notebook__WEBPACK_IMPORTED_MODULE_0__);
|
|
6533
|
-
/* harmony import */ var _jupyterlab_apputils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @jupyterlab/apputils */ "webpack/sharing/consume/default/@jupyterlab/apputils");
|
|
6534
|
-
/* harmony import */ var _jupyterlab_apputils__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_jupyterlab_apputils__WEBPACK_IMPORTED_MODULE_1__);
|
|
6535
|
-
/* harmony import */ var _jupyterlab_coreutils__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @jupyterlab/coreutils */ "webpack/sharing/consume/default/@jupyterlab/coreutils");
|
|
6536
|
-
/* harmony import */ var _jupyterlab_coreutils__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_jupyterlab_coreutils__WEBPACK_IMPORTED_MODULE_2__);
|
|
6537
|
-
/* harmony import */ var _lumino_widgets__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @lumino/widgets */ "webpack/sharing/consume/default/@lumino/widgets");
|
|
6538
|
-
/* harmony import */ var _lumino_widgets__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_lumino_widgets__WEBPACK_IMPORTED_MODULE_3__);
|
|
6539
|
-
/* harmony import */ var _AiChat_token__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../AiChat/token */ "./lib/Extensions/AiChat/token.js");
|
|
6540
|
-
/* harmony import */ var _restAPI_RestAPI__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../restAPI/RestAPI */ "./lib/restAPI/RestAPI.js");
|
|
6541
|
-
/* harmony import */ var _commands__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../commands */ "./lib/commands.js");
|
|
6542
|
-
/*
|
|
6543
|
-
* Copyright (c) Saga Inc.
|
|
6544
|
-
* Distributed under the terms of the GNU Affero General Public License v3.0 License.
|
|
6545
|
-
*/
|
|
6546
|
-
|
|
6547
|
-
|
|
6548
|
-
|
|
6549
|
-
|
|
6550
|
-
|
|
6551
|
-
|
|
6552
|
-
|
|
6553
|
-
|
|
6554
|
-
|
|
6555
|
-
/**
|
|
6556
|
-
* Simple HTML widget for displaying iframe content.
|
|
6557
|
-
*/
|
|
6558
|
-
class IFrameWidget extends _lumino_widgets__WEBPACK_IMPORTED_MODULE_3__.Widget {
|
|
6559
|
-
constructor(url) {
|
|
6560
|
-
super();
|
|
6561
|
-
this.addClass('jp-iframe-widget');
|
|
6562
|
-
const iframe = document.createElement('iframe');
|
|
6563
|
-
iframe.src = url;
|
|
6564
|
-
iframe.style.width = '100%';
|
|
6565
|
-
iframe.style.height = '100%';
|
|
6566
|
-
iframe.style.border = 'none';
|
|
6567
|
-
this.node.appendChild(iframe);
|
|
6568
|
-
}
|
|
6569
|
-
setUrl(url) {
|
|
6570
|
-
const iframe = this.node.querySelector('iframe');
|
|
6571
|
-
if (iframe) {
|
|
6572
|
-
iframe.src = url;
|
|
6573
|
-
}
|
|
6574
|
-
}
|
|
6575
|
-
}
|
|
6576
|
-
/**
|
|
6577
|
-
* The streamlit preview plugin.
|
|
6578
|
-
*/
|
|
6579
|
-
const StreamlitPreviewPlugin = {
|
|
6580
|
-
id: 'mito-ai:streamlit-preview',
|
|
6581
|
-
autoStart: true,
|
|
6582
|
-
requires: [_jupyterlab_notebook__WEBPACK_IMPORTED_MODULE_0__.INotebookTracker, _jupyterlab_apputils__WEBPACK_IMPORTED_MODULE_1__.ICommandPalette, _AiChat_token__WEBPACK_IMPORTED_MODULE_4__.IChatTracker],
|
|
6583
|
-
activate: (app, notebookTracker, palette) => {
|
|
6584
|
-
console.log('mito-ai: StreamlitPreviewPlugin activated');
|
|
6585
|
-
// Add command to command palette
|
|
6586
|
-
app.commands.addCommand(_commands__WEBPACK_IMPORTED_MODULE_5__.previewAsStreamlit, {
|
|
6587
|
-
label: 'Preview as Streamlit',
|
|
6588
|
-
caption: 'Convert current notebook to Streamlit app and preview it',
|
|
6589
|
-
execute: async () => {
|
|
6590
|
-
await previewNotebookAsStreamlit(app, notebookTracker);
|
|
6591
|
-
}
|
|
6592
|
-
});
|
|
6593
|
-
// Add to command palette
|
|
6594
|
-
palette.addItem({
|
|
6595
|
-
command: _commands__WEBPACK_IMPORTED_MODULE_5__.previewAsStreamlit,
|
|
6596
|
-
category: 'Mito AI'
|
|
6597
|
-
});
|
|
6598
|
-
}
|
|
6599
|
-
};
|
|
6600
|
-
/**
|
|
6601
|
-
* Preview the current notebook as a Streamlit app.
|
|
6602
|
-
*/
|
|
6603
|
-
async function previewNotebookAsStreamlit(app, notebookTracker) {
|
|
6604
|
-
const notebookPanel = notebookTracker.currentWidget;
|
|
6605
|
-
if (!notebookPanel) {
|
|
6606
|
-
_jupyterlab_apputils__WEBPACK_IMPORTED_MODULE_1__.Notification.error('No notebook is currently active');
|
|
6607
|
-
return;
|
|
6608
|
-
}
|
|
6609
|
-
// First save the notebook to ensure the app is up to date
|
|
6610
|
-
await notebookPanel.context.save();
|
|
6611
|
-
const notebookPath = notebookPanel.context.path;
|
|
6612
|
-
const notebookName = _jupyterlab_coreutils__WEBPACK_IMPORTED_MODULE_2__.PathExt.basename(notebookPath, '.ipynb');
|
|
6613
|
-
// Show building notification
|
|
6614
|
-
const notificationId = _jupyterlab_apputils__WEBPACK_IMPORTED_MODULE_1__.Notification.emit('Building App Preview...', 'in-progress', { autoClose: false });
|
|
6615
|
-
try {
|
|
6616
|
-
const previewData = await (0,_restAPI_RestAPI__WEBPACK_IMPORTED_MODULE_6__.startStreamlitPreview)(notebookPath);
|
|
6617
|
-
// Create iframe widget
|
|
6618
|
-
const iframeWidget = new IFrameWidget(previewData.url);
|
|
6619
|
-
// Create main area widget
|
|
6620
|
-
const widget = new _jupyterlab_apputils__WEBPACK_IMPORTED_MODULE_1__.MainAreaWidget({ content: iframeWidget });
|
|
6621
|
-
widget.title.label = `App Preview (${notebookName})`;
|
|
6622
|
-
widget.title.closable = true;
|
|
6623
|
-
// Handle widget disposal
|
|
6624
|
-
widget.disposed.connect(() => {
|
|
6625
|
-
console.log('Widget disposed, stopping preview');
|
|
6626
|
-
void (0,_restAPI_RestAPI__WEBPACK_IMPORTED_MODULE_6__.stopStreamlitPreview)(previewData.id);
|
|
6627
|
-
});
|
|
6628
|
-
// Add widget to main area with split-right mode
|
|
6629
|
-
app.shell.add(widget, 'main', {
|
|
6630
|
-
mode: 'split-right',
|
|
6631
|
-
ref: notebookPanel.id
|
|
6632
|
-
});
|
|
6633
|
-
// Update notification to success
|
|
6634
|
-
_jupyterlab_apputils__WEBPACK_IMPORTED_MODULE_1__.Notification.update({
|
|
6635
|
-
id: notificationId,
|
|
6636
|
-
message: 'Streamlit preview started successfully!',
|
|
6637
|
-
type: 'default',
|
|
6638
|
-
autoClose: false
|
|
6639
|
-
});
|
|
6640
|
-
}
|
|
6641
|
-
catch (error) {
|
|
6642
|
-
console.error('Error starting streamlit preview:', error);
|
|
6643
|
-
// Update notification to error
|
|
6644
|
-
_jupyterlab_apputils__WEBPACK_IMPORTED_MODULE_1__.Notification.update({
|
|
6645
|
-
id: notificationId,
|
|
6646
|
-
message: `Failed to start preview: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
6647
|
-
type: 'error',
|
|
6648
|
-
autoClose: false
|
|
6649
|
-
});
|
|
6650
|
-
}
|
|
6651
|
-
}
|
|
6652
|
-
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (StreamlitPreviewPlugin);
|
|
6653
|
-
|
|
6654
|
-
|
|
6655
7192
|
/***/ }),
|
|
6656
7193
|
|
|
6657
7194
|
/***/ "./lib/Extensions/ToolbarButtons/ToolbarButtonsPlugin.js":
|
|
@@ -6666,12 +7203,10 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
6666
7203
|
/* harmony export */ });
|
|
6667
7204
|
/* harmony import */ var _jupyterlab_notebook__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @jupyterlab/notebook */ "webpack/sharing/consume/default/@jupyterlab/notebook");
|
|
6668
7205
|
/* harmony import */ var _jupyterlab_notebook__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_jupyterlab_notebook__WEBPACK_IMPORTED_MODULE_0__);
|
|
6669
|
-
/* harmony import */ var
|
|
6670
|
-
/* harmony import */ var
|
|
6671
|
-
/* harmony import */ var
|
|
6672
|
-
/* harmony import */ var
|
|
6673
|
-
/* harmony import */ var _AppBuilder_AppBuilderPlugin__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../AppBuilder/AppBuilderPlugin */ "./lib/Extensions/AppBuilder/AppBuilderPlugin.js");
|
|
6674
|
-
/* harmony import */ var _restAPI_RestAPI__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../restAPI/RestAPI */ "./lib/restAPI/RestAPI.js");
|
|
7206
|
+
/* harmony import */ var _commands__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../commands */ "./lib/commands.js");
|
|
7207
|
+
/* harmony import */ var _icons__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../icons */ "./lib/icons/index.js");
|
|
7208
|
+
/* harmony import */ var _utils_cellMetadata__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../utils/cellMetadata */ "./lib/utils/cellMetadata.js");
|
|
7209
|
+
/* harmony import */ var _restAPI_RestAPI__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../restAPI/RestAPI */ "./lib/restAPI/RestAPI.js");
|
|
6675
7210
|
/*
|
|
6676
7211
|
* Copyright (c) Saga Inc.
|
|
6677
7212
|
* Distributed under the terms of the GNU Affero General Public License v3.0 License.
|
|
@@ -6681,8 +7216,6 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
6681
7216
|
|
|
6682
7217
|
|
|
6683
7218
|
|
|
6684
|
-
|
|
6685
|
-
|
|
6686
7219
|
const ToolbarButtonsPlugin = {
|
|
6687
7220
|
// Important: The Cell Toolbar Buttons are added to the toolbar registry via the schema/toolbar-buttons.json file.
|
|
6688
7221
|
// The id here must be mito-ai:toolbar-buttons otherwise the buttons are not successfully added. My understanding is that
|
|
@@ -6691,28 +7224,27 @@ const ToolbarButtonsPlugin = {
|
|
|
6691
7224
|
description: 'Adds an "explain code cell with AI" button to the cell toolbar',
|
|
6692
7225
|
autoStart: true,
|
|
6693
7226
|
requires: [_jupyterlab_notebook__WEBPACK_IMPORTED_MODULE_0__.INotebookTracker],
|
|
6694
|
-
|
|
6695
|
-
activate: (app, notebookTracker, appBuilderService) => {
|
|
7227
|
+
activate: (app, notebookTracker) => {
|
|
6696
7228
|
const { commands } = app;
|
|
6697
7229
|
// Important: To add a button to the cell toolbar, the command must start with "toolbar-button:"
|
|
6698
7230
|
// and the command must match the command in the schema/plugin.json file.
|
|
6699
7231
|
commands.addCommand('toolbar-button:explain-code', {
|
|
6700
|
-
icon:
|
|
7232
|
+
icon: _icons__WEBPACK_IMPORTED_MODULE_1__.lightBulbLabIcon,
|
|
6701
7233
|
caption: 'Explain code in AI Chat',
|
|
6702
7234
|
execute: async () => {
|
|
6703
7235
|
/*
|
|
6704
7236
|
In order to click on the cell toolbar button, that cell must be the active cell,
|
|
6705
7237
|
so the ChatHistoryManager will take care of providing the cell context.
|
|
6706
7238
|
*/
|
|
6707
|
-
await app.commands.execute(
|
|
6708
|
-
await app.commands.execute(
|
|
7239
|
+
await app.commands.execute(_commands__WEBPACK_IMPORTED_MODULE_2__.COMMAND_MITO_AI_OPEN_CHAT);
|
|
7240
|
+
await app.commands.execute(_commands__WEBPACK_IMPORTED_MODULE_2__.COMMAND_MITO_AI_SEND_EXPLAIN_CODE_MESSAGE);
|
|
6709
7241
|
},
|
|
6710
|
-
isVisible: () => { var _a; return ((_a = notebookTracker.activeCell) === null || _a === void 0 ? void 0 : _a.model.type) === 'code' && app.commands.hasCommand(
|
|
7242
|
+
isVisible: () => { var _a; return ((_a = notebookTracker.activeCell) === null || _a === void 0 ? void 0 : _a.model.type) === 'code' && app.commands.hasCommand(_commands__WEBPACK_IMPORTED_MODULE_2__.COMMAND_MITO_AI_SEND_EXPLAIN_CODE_MESSAGE); }
|
|
6711
7243
|
});
|
|
6712
7244
|
commands.addCommand('toolbar-button:toggle-include-cell-in-app', {
|
|
6713
7245
|
icon: () => {
|
|
6714
|
-
const includeCellInApp = (0,
|
|
6715
|
-
return includeCellInApp ?
|
|
7246
|
+
const includeCellInApp = (0,_utils_cellMetadata__WEBPACK_IMPORTED_MODULE_3__.getActiveCellIncludeInApp)(notebookTracker);
|
|
7247
|
+
return includeCellInApp ? _icons__WEBPACK_IMPORTED_MODULE_1__.AppBuilderIncludeCellLabIcon : _icons__WEBPACK_IMPORTED_MODULE_1__.AppBuilderExcludeCellLabIcon;
|
|
6716
7248
|
},
|
|
6717
7249
|
caption: 'Toggle cell output visibility in Streamlit app',
|
|
6718
7250
|
execute: async () => {
|
|
@@ -6729,47 +7261,33 @@ const ToolbarButtonsPlugin = {
|
|
|
6729
7261
|
Potential solutions:
|
|
6730
7262
|
- Use linting (pyright/pylance) to detect reportUnusedExpression in cells that have outputs turned off and remove unused expressions
|
|
6731
7263
|
- Use AI to identify and remove hanging variables
|
|
6732
|
-
- Parse code to find and remove lone variable references and literals
|
|
6733
|
-
*/
|
|
6734
|
-
(0,
|
|
6735
|
-
// Force command refresh to update the icon
|
|
6736
|
-
commands.notifyCommandChanged('toolbar-button:toggle-include-cell-in-app');
|
|
6737
|
-
},
|
|
6738
|
-
isVisible: () => {
|
|
6739
|
-
return app.commands.hasCommand(_commands__WEBPACK_IMPORTED_MODULE_3__.COMMAND_MITO_AI_BETA_MODE_ENABLED);
|
|
6740
|
-
}
|
|
6741
|
-
});
|
|
6742
|
-
commands.addCommand('toolbar-button:convert-to-streamlit', {
|
|
6743
|
-
label: 'Deploy App',
|
|
6744
|
-
caption: 'Convert to Streamlit',
|
|
6745
|
-
className: 'text-button-mito-ai button-base button-purple button-small',
|
|
6746
|
-
execute: async () => {
|
|
6747
|
-
void (0,_AppBuilder_NotebookToStreamlit__WEBPACK_IMPORTED_MODULE_5__.convertNotebookToStreamlit)(notebookTracker, appBuilderService);
|
|
7264
|
+
- Parse code to find and remove lone variable references and literals
|
|
7265
|
+
*/
|
|
7266
|
+
(0,_utils_cellMetadata__WEBPACK_IMPORTED_MODULE_3__.toggleActiveCellIncludeInAppMetadata)(notebookTracker);
|
|
7267
|
+
// Force command refresh to update the icon
|
|
7268
|
+
commands.notifyCommandChanged('toolbar-button:toggle-include-cell-in-app');
|
|
6748
7269
|
},
|
|
6749
7270
|
isVisible: () => {
|
|
6750
|
-
|
|
6751
|
-
// use async commands in isVisible.
|
|
6752
|
-
return app.commands.hasCommand(_commands__WEBPACK_IMPORTED_MODULE_3__.COMMAND_MITO_AI_BETA_MODE_ENABLED);
|
|
7271
|
+
return app.commands.hasCommand(_commands__WEBPACK_IMPORTED_MODULE_2__.COMMAND_MITO_AI_BETA_MODE_ENABLED);
|
|
6753
7272
|
}
|
|
6754
7273
|
});
|
|
6755
7274
|
commands.addCommand('toolbar-button:preview-as-streamlit', {
|
|
6756
|
-
label: '
|
|
6757
|
-
caption: 'Preview as
|
|
7275
|
+
label: 'App Mode',
|
|
7276
|
+
caption: 'Preview notebook as app and turn on App Mode',
|
|
6758
7277
|
className: 'text-button-mito-ai button-base button-purple button-small',
|
|
6759
7278
|
execute: async () => {
|
|
6760
7279
|
void app.commands.execute('mito-ai:preview-as-streamlit');
|
|
6761
7280
|
},
|
|
6762
7281
|
isVisible: () => {
|
|
6763
|
-
return app.commands.hasCommand(
|
|
7282
|
+
return app.commands.hasCommand(_commands__WEBPACK_IMPORTED_MODULE_2__.COMMAND_MITO_AI_BETA_MODE_ENABLED);
|
|
6764
7283
|
}
|
|
6765
7284
|
});
|
|
6766
7285
|
// Check if the beta mode is enabled. After checking, tell Jupyter to
|
|
6767
7286
|
// re-evaluate convert-to-streamlit visibility now that we have had the
|
|
6768
7287
|
// opportunity to set the mito-ai:beta-mode-enabled command if beta mode is enabled.
|
|
6769
|
-
(0,
|
|
7288
|
+
(0,_restAPI_RestAPI__WEBPACK_IMPORTED_MODULE_4__.getSetting)('beta_mode').then(value => {
|
|
6770
7289
|
if (value === 'true') {
|
|
6771
|
-
commands.addCommand(
|
|
6772
|
-
commands.notifyCommandChanged('toolbar-button:convert-to-streamlit');
|
|
7290
|
+
commands.addCommand(_commands__WEBPACK_IMPORTED_MODULE_2__.COMMAND_MITO_AI_BETA_MODE_ENABLED, { execute: () => { } });
|
|
6773
7291
|
commands.notifyCommandChanged('toolbar-button:toggle-include-cell-in-app');
|
|
6774
7292
|
commands.notifyCommandChanged('toolbar-button:preview-as-streamlit');
|
|
6775
7293
|
}
|
|
@@ -7264,13 +7782,13 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
7264
7782
|
/* harmony export */ COMMAND_MITO_AI_CELL_TOOLBAR_ACCEPT_CODE: () => (/* binding */ COMMAND_MITO_AI_CELL_TOOLBAR_ACCEPT_CODE),
|
|
7265
7783
|
/* harmony export */ COMMAND_MITO_AI_CELL_TOOLBAR_REJECT_CODE: () => (/* binding */ COMMAND_MITO_AI_CELL_TOOLBAR_REJECT_CODE),
|
|
7266
7784
|
/* harmony export */ COMMAND_MITO_AI_OPEN_CHAT: () => (/* binding */ COMMAND_MITO_AI_OPEN_CHAT),
|
|
7785
|
+
/* harmony export */ COMMAND_MITO_AI_PREVIEW_AS_STREAMLIT: () => (/* binding */ COMMAND_MITO_AI_PREVIEW_AS_STREAMLIT),
|
|
7267
7786
|
/* harmony export */ COMMAND_MITO_AI_PREVIEW_LATEST_CODE: () => (/* binding */ COMMAND_MITO_AI_PREVIEW_LATEST_CODE),
|
|
7268
7787
|
/* harmony export */ COMMAND_MITO_AI_REJECT_LATEST_CODE: () => (/* binding */ COMMAND_MITO_AI_REJECT_LATEST_CODE),
|
|
7269
7788
|
/* harmony export */ COMMAND_MITO_AI_SEND_AGENT_MESSAGE: () => (/* binding */ COMMAND_MITO_AI_SEND_AGENT_MESSAGE),
|
|
7270
7789
|
/* harmony export */ COMMAND_MITO_AI_SEND_DEBUG_ERROR_MESSAGE: () => (/* binding */ COMMAND_MITO_AI_SEND_DEBUG_ERROR_MESSAGE),
|
|
7271
7790
|
/* harmony export */ COMMAND_MITO_AI_SEND_EXPLAIN_CODE_MESSAGE: () => (/* binding */ COMMAND_MITO_AI_SEND_EXPLAIN_CODE_MESSAGE),
|
|
7272
|
-
/* harmony export */ COMMAND_MITO_AI_SEND_MESSAGE: () => (/* binding */ COMMAND_MITO_AI_SEND_MESSAGE)
|
|
7273
|
-
/* harmony export */ previewAsStreamlit: () => (/* binding */ previewAsStreamlit)
|
|
7791
|
+
/* harmony export */ COMMAND_MITO_AI_SEND_MESSAGE: () => (/* binding */ COMMAND_MITO_AI_SEND_MESSAGE)
|
|
7274
7792
|
/* harmony export */ });
|
|
7275
7793
|
/*
|
|
7276
7794
|
* Copyright (c) Saga Inc.
|
|
@@ -7290,7 +7808,7 @@ const COMMAND_MITO_AI_CELL_TOOLBAR_REJECT_CODE = `toolbar-button:reject-code`;
|
|
|
7290
7808
|
// Beta mode commands
|
|
7291
7809
|
const COMMAND_MITO_AI_BETA_MODE_ENABLED = `${MITO_AI}:beta-mode-enabled`;
|
|
7292
7810
|
// Streamlit commands
|
|
7293
|
-
const
|
|
7811
|
+
const COMMAND_MITO_AI_PREVIEW_AS_STREAMLIT = 'mito-ai:preview-as-streamlit';
|
|
7294
7812
|
|
|
7295
7813
|
|
|
7296
7814
|
/***/ }),
|
|
@@ -7972,9 +8490,7 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
7972
8490
|
|
|
7973
8491
|
|
|
7974
8492
|
const MODEL_MAPPINGS = [
|
|
7975
|
-
{ displayName: _utils_models__WEBPACK_IMPORTED_MODULE_2__.GPT_DISPLAY_NAME, fullName: _utils_models__WEBPACK_IMPORTED_MODULE_2__.GPT_MODEL_NAME },
|
|
7976
8493
|
{ displayName: 'GPT 4.1', fullName: 'gpt-4.1' },
|
|
7977
|
-
{ displayName: _utils_models__WEBPACK_IMPORTED_MODULE_2__.CLAUDE_OPUS_DISPLAY_NAME, fullName: _utils_models__WEBPACK_IMPORTED_MODULE_2__.CLAUDE_OPUS_MODEL_NAME },
|
|
7978
8494
|
{ displayName: _utils_models__WEBPACK_IMPORTED_MODULE_2__.CLAUDE_SONNET_DISPLAY_NAME, fullName: _utils_models__WEBPACK_IMPORTED_MODULE_2__.CLAUDE_SONNET_MODEL_NAME },
|
|
7979
8495
|
{ displayName: 'Gemini 2.5 Pro', fullName: 'gemini-2.5-pro-preview-03-25' }
|
|
7980
8496
|
];
|
|
@@ -8886,6 +9402,7 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
8886
9402
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
8887
9403
|
/* harmony export */ AppBuilderExcludeCellLabIcon: () => (/* binding */ AppBuilderExcludeCellLabIcon),
|
|
8888
9404
|
/* harmony export */ AppBuilderIncludeCellLabIcon: () => (/* binding */ AppBuilderIncludeCellLabIcon),
|
|
9405
|
+
/* harmony export */ DeployLabIcon: () => (/* binding */ DeployLabIcon),
|
|
8889
9406
|
/* harmony export */ NucleusLabIcon: () => (/* binding */ NucleusLabIcon),
|
|
8890
9407
|
/* harmony export */ OpenIndicatorLabIcon: () => (/* binding */ OpenIndicatorLabIcon),
|
|
8891
9408
|
/* harmony export */ lightBulbLabIcon: () => (/* binding */ lightBulbLabIcon)
|
|
@@ -8897,6 +9414,7 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
8897
9414
|
/* harmony import */ var _src_icons_OpenIndicatorIcon_svg__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../src/icons/OpenIndicatorIcon.svg */ "./src/icons/OpenIndicatorIcon.svg");
|
|
8898
9415
|
/* harmony import */ var _src_icons_AppBuilderExcludeCellIcon_svg__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../src/icons/AppBuilderExcludeCellIcon.svg */ "./src/icons/AppBuilderExcludeCellIcon.svg");
|
|
8899
9416
|
/* harmony import */ var _src_icons_AppBuilderIncludeCellIcon_svg__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../src/icons/AppBuilderIncludeCellIcon.svg */ "./src/icons/AppBuilderIncludeCellIcon.svg");
|
|
9417
|
+
/* harmony import */ var _src_icons_App_DeployIcon_svg__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../src/icons/App/DeployIcon.svg */ "./src/icons/App/DeployIcon.svg");
|
|
8900
9418
|
/*
|
|
8901
9419
|
* Copyright (c) Saga Inc.
|
|
8902
9420
|
* Distributed under the terms of the GNU Affero General Public License v3.0 License.
|
|
@@ -8907,6 +9425,7 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
8907
9425
|
|
|
8908
9426
|
|
|
8909
9427
|
|
|
9428
|
+
|
|
8910
9429
|
const lightBulbLabIcon = new _jupyterlab_ui_components__WEBPACK_IMPORTED_MODULE_0__.LabIcon({
|
|
8911
9430
|
name: 'lightbulb-icon',
|
|
8912
9431
|
svgstr: _src_icons_LightbulbIcon_svg__WEBPACK_IMPORTED_MODULE_1__
|
|
@@ -8927,6 +9446,10 @@ const AppBuilderIncludeCellLabIcon = new _jupyterlab_ui_components__WEBPACK_IMPO
|
|
|
8927
9446
|
name: 'app-builder-include-cell-icon',
|
|
8928
9447
|
svgstr: _src_icons_AppBuilderIncludeCellIcon_svg__WEBPACK_IMPORTED_MODULE_5__
|
|
8929
9448
|
});
|
|
9449
|
+
const DeployLabIcon = new _jupyterlab_ui_components__WEBPACK_IMPORTED_MODULE_0__.LabIcon({
|
|
9450
|
+
name: 'deploy-icon',
|
|
9451
|
+
svgstr: _src_icons_App_DeployIcon_svg__WEBPACK_IMPORTED_MODULE_6__
|
|
9452
|
+
});
|
|
8930
9453
|
|
|
8931
9454
|
|
|
8932
9455
|
/***/ }),
|
|
@@ -8945,8 +9468,8 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
8945
9468
|
/* harmony import */ var _Extensions_ContextManager_ContextManagerPlugin__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./Extensions/ContextManager/ContextManagerPlugin */ "./lib/Extensions/ContextManager/ContextManagerPlugin.js");
|
|
8946
9469
|
/* harmony import */ var _Extensions_ErrorMimeRenderer_ErrorMimeRendererPlugin__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./Extensions/ErrorMimeRenderer/ErrorMimeRendererPlugin */ "./lib/Extensions/ErrorMimeRenderer/ErrorMimeRendererPlugin.js");
|
|
8947
9470
|
/* harmony import */ var _Extensions_ToolbarButtons_ToolbarButtonsPlugin__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./Extensions/ToolbarButtons/ToolbarButtonsPlugin */ "./lib/Extensions/ToolbarButtons/ToolbarButtonsPlugin.js");
|
|
8948
|
-
/* harmony import */ var
|
|
8949
|
-
/* harmony import */ var
|
|
9471
|
+
/* harmony import */ var _Extensions_AppDeploy_AppDeployPlugin__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./Extensions/AppDeploy/AppDeployPlugin */ "./lib/Extensions/AppDeploy/AppDeployPlugin.js");
|
|
9472
|
+
/* harmony import */ var _Extensions_AppPreview_StreamlitPreviewPlugin__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./Extensions/AppPreview/StreamlitPreviewPlugin */ "./lib/Extensions/AppPreview/StreamlitPreviewPlugin.js");
|
|
8950
9473
|
/* harmony import */ var _Extensions_emptyCell_EmptyCellPlugin__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./Extensions/emptyCell/EmptyCellPlugin */ "./lib/Extensions/emptyCell/EmptyCellPlugin.js");
|
|
8951
9474
|
/* harmony import */ var _Extensions_status__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./Extensions/status */ "./lib/Extensions/status/index.js");
|
|
8952
9475
|
/* harmony import */ var _Extensions_SettingsManager_SettingsManagerPlugin__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./Extensions/SettingsManager/SettingsManagerPlugin */ "./lib/Extensions/SettingsManager/SettingsManagerPlugin.js");
|
|
@@ -8975,8 +9498,8 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
8975
9498
|
_Extensions_AiChat_AiChatPlugin__WEBPACK_IMPORTED_MODULE_0__["default"],
|
|
8976
9499
|
_Extensions_ErrorMimeRenderer_ErrorMimeRendererPlugin__WEBPACK_IMPORTED_MODULE_1__["default"],
|
|
8977
9500
|
_Extensions_ContextManager_ContextManagerPlugin__WEBPACK_IMPORTED_MODULE_2__["default"],
|
|
8978
|
-
|
|
8979
|
-
|
|
9501
|
+
_Extensions_AppDeploy_AppDeployPlugin__WEBPACK_IMPORTED_MODULE_3__["default"],
|
|
9502
|
+
_Extensions_AppPreview_StreamlitPreviewPlugin__WEBPACK_IMPORTED_MODULE_4__["default"],
|
|
8980
9503
|
_Extensions_ToolbarButtons_ToolbarButtonsPlugin__WEBPACK_IMPORTED_MODULE_5__["default"],
|
|
8981
9504
|
_Extensions_emptyCell_EmptyCellPlugin__WEBPACK_IMPORTED_MODULE_6__.emptyCellPlaceholder,
|
|
8982
9505
|
_Extensions_status__WEBPACK_IMPORTED_MODULE_7__.statusItem,
|
|
@@ -9100,10 +9623,10 @@ const getDatabaseConnections = async () => {
|
|
|
9100
9623
|
STREAMLIT PREVIEW ENDPOINTS
|
|
9101
9624
|
|
|
9102
9625
|
************************************/
|
|
9103
|
-
const startStreamlitPreview = async (notebookPath) => {
|
|
9626
|
+
const startStreamlitPreview = async (notebookPath, force_recreate = false) => {
|
|
9104
9627
|
const response = await (0,_utils__WEBPACK_IMPORTED_MODULE_0__.requestAPI)('streamlit-preview', {
|
|
9105
9628
|
method: 'POST',
|
|
9106
|
-
body: JSON.stringify({ notebook_path: notebookPath }),
|
|
9629
|
+
body: JSON.stringify({ notebook_path: notebookPath, force_recreate: force_recreate }),
|
|
9107
9630
|
});
|
|
9108
9631
|
if (response.error) {
|
|
9109
9632
|
throw new Error(response.error.message);
|
|
@@ -9227,13 +9750,14 @@ const getXsrfToken = () => {
|
|
|
9227
9750
|
__webpack_require__.r(__webpack_exports__);
|
|
9228
9751
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
9229
9752
|
/* harmony export */ acceptAndRunCellUpdate: () => (/* binding */ acceptAndRunCellUpdate),
|
|
9230
|
-
/* harmony export */ acceptAndRunCode: () => (/* binding */ acceptAndRunCode),
|
|
9231
9753
|
/* harmony export */ retryIfExecutionError: () => (/* binding */ retryIfExecutionError),
|
|
9232
9754
|
/* harmony export */ runAllCells: () => (/* binding */ runAllCells)
|
|
9233
9755
|
/* harmony export */ });
|
|
9234
|
-
/* harmony import */ var
|
|
9235
|
-
/* harmony import */ var
|
|
9236
|
-
/* harmony import */ var
|
|
9756
|
+
/* harmony import */ var _jupyterlab_notebook__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @jupyterlab/notebook */ "webpack/sharing/consume/default/@jupyterlab/notebook");
|
|
9757
|
+
/* harmony import */ var _jupyterlab_notebook__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_jupyterlab_notebook__WEBPACK_IMPORTED_MODULE_0__);
|
|
9758
|
+
/* harmony import */ var _Extensions_ErrorMimeRenderer_errorUtils__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Extensions/ErrorMimeRenderer/errorUtils */ "./lib/Extensions/ErrorMimeRenderer/errorUtils.js");
|
|
9759
|
+
/* harmony import */ var _sleep__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./sleep */ "./lib/utils/sleep.js");
|
|
9760
|
+
/* harmony import */ var _notebook__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./notebook */ "./lib/utils/notebook.js");
|
|
9237
9761
|
/*
|
|
9238
9762
|
* Copyright (c) Saga Inc.
|
|
9239
9763
|
* Distributed under the terms of the GNU Affero General Public License v3.0 License.
|
|
@@ -9241,70 +9765,71 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
9241
9765
|
|
|
9242
9766
|
|
|
9243
9767
|
|
|
9244
|
-
|
|
9768
|
+
|
|
9769
|
+
|
|
9770
|
+
const acceptAndRunCellUpdate = async (cellUpdate, notebookPanel) => {
|
|
9245
9771
|
// If the cellUpdate is creating a new code cell, insert it
|
|
9246
|
-
// before previewing and accepting the code.
|
|
9772
|
+
// before previewing and accepting the code. It is safe to do this
|
|
9773
|
+
// in the background agent because it does not effect the active cell
|
|
9774
|
+
// in other notebooks.
|
|
9247
9775
|
if (cellUpdate.type === 'new') {
|
|
9248
9776
|
// makes the cell the active cell
|
|
9249
|
-
(0,
|
|
9777
|
+
(0,_notebook__WEBPACK_IMPORTED_MODULE_1__.createCodeCellAtIndexAndActivate)(notebookPanel, cellUpdate.index);
|
|
9250
9778
|
}
|
|
9251
9779
|
else {
|
|
9252
|
-
(0,
|
|
9780
|
+
(0,_notebook__WEBPACK_IMPORTED_MODULE_1__.setActiveCellByIDInNotebookPanel)(notebookPanel, cellUpdate.id);
|
|
9253
9781
|
}
|
|
9254
|
-
|
|
9255
|
-
|
|
9256
|
-
|
|
9257
|
-
|
|
9258
|
-
|
|
9259
|
-
|
|
9260
|
-
|
|
9261
|
-
this function
|
|
9262
|
-
*/
|
|
9263
|
-
previewAICodeToActiveCell();
|
|
9264
|
-
acceptAICode();
|
|
9782
|
+
const notebook = notebookPanel.content;
|
|
9783
|
+
const context = notebookPanel.context;
|
|
9784
|
+
if (notebook === undefined) {
|
|
9785
|
+
return;
|
|
9786
|
+
}
|
|
9787
|
+
const cellID = (0,_notebook__WEBPACK_IMPORTED_MODULE_1__.getActiveCellIDInNotebookPanel)(notebookPanel);
|
|
9788
|
+
(0,_notebook__WEBPACK_IMPORTED_MODULE_1__.writeCodeToCellByIDInNotebookPanel)(notebookPanel, cellUpdate.code, cellID);
|
|
9265
9789
|
// We always create code cells, and then convert to markdown if necessary.
|
|
9266
|
-
if (
|
|
9267
|
-
|
|
9790
|
+
if (cellUpdate.cell_type === 'markdown') {
|
|
9791
|
+
_jupyterlab_notebook__WEBPACK_IMPORTED_MODULE_0__.NotebookActions.changeCellType(notebook, 'markdown');
|
|
9268
9792
|
}
|
|
9269
|
-
else if (
|
|
9270
|
-
|
|
9793
|
+
else if (cellUpdate.cell_type === 'code') {
|
|
9794
|
+
_jupyterlab_notebook__WEBPACK_IMPORTED_MODULE_0__.NotebookActions.changeCellType(notebook, 'code');
|
|
9271
9795
|
}
|
|
9272
9796
|
// This awaits until after the execution is finished.
|
|
9273
9797
|
// Note that it is important that we just run the cell and don't run and advance the cell.
|
|
9274
9798
|
// We rely on the active cell remaining the same after running the cell in order to get the output
|
|
9275
9799
|
// of the cell to send to the agent. This is changeable in the future, but for now its an invariant we rely on.
|
|
9276
|
-
await
|
|
9800
|
+
await _jupyterlab_notebook__WEBPACK_IMPORTED_MODULE_0__.NotebookActions.run(notebook, context === null || context === void 0 ? void 0 : context.sessionContext);
|
|
9277
9801
|
// Scroll to the bottom of the active cell to show the output
|
|
9278
|
-
|
|
9802
|
+
// as long as we are not operating in background agent mode.
|
|
9803
|
+
const activeCellID = (0,_notebook__WEBPACK_IMPORTED_MODULE_1__.getActiveCellIDInNotebookPanel)(notebookPanel);
|
|
9279
9804
|
if (activeCellID) {
|
|
9280
|
-
(0,
|
|
9805
|
+
(0,_notebook__WEBPACK_IMPORTED_MODULE_1__.scrollToCell)(notebookPanel, activeCellID, undefined, 'end');
|
|
9281
9806
|
}
|
|
9282
9807
|
// By sleeping here, we make sure that this function returns after the variable manager
|
|
9283
9808
|
// has updated the state of the variables. This ensures that on the next Ai message
|
|
9284
9809
|
// gets the most up to date data.
|
|
9285
|
-
await (0,
|
|
9810
|
+
await (0,_sleep__WEBPACK_IMPORTED_MODULE_2__.sleep)(1000);
|
|
9286
9811
|
};
|
|
9287
|
-
const retryIfExecutionError = async (
|
|
9288
|
-
var _a
|
|
9289
|
-
const cell =
|
|
9812
|
+
const retryIfExecutionError = async (notebookPanel, app, sendAgentSmartDebugMessage, shouldContinueAgentExecution, markAgentForStopping, chatHistoryManagerRef) => {
|
|
9813
|
+
var _a;
|
|
9814
|
+
const cell = notebookPanel.content.activeCell;
|
|
9290
9815
|
// Note: If you update the max retries, update the message we display on each failure
|
|
9291
9816
|
// attempt to ensure we don't say "third attempt" over and over again.
|
|
9292
9817
|
const MAX_RETRIES = 3;
|
|
9293
9818
|
let attempts = 0;
|
|
9294
9819
|
let runAllCellsAttempts = 0;
|
|
9295
9820
|
const MAX_RUN_ALL_CELLS_ATTEMPTS = 2; // Only allow two run_all_cells attempt per error cycle
|
|
9296
|
-
while ((0,
|
|
9821
|
+
while ((0,_notebook__WEBPACK_IMPORTED_MODULE_1__.didCellExecutionError)(cell) && attempts < MAX_RETRIES) {
|
|
9297
9822
|
if (!shouldContinueAgentExecution.current) {
|
|
9298
|
-
|
|
9823
|
+
await markAgentForStopping();
|
|
9299
9824
|
return 'interupted';
|
|
9300
9825
|
}
|
|
9301
9826
|
// If the code cell has an error, we need to send the error to the AI
|
|
9302
9827
|
// and get it to fix the error.
|
|
9303
|
-
const errorOutput = (
|
|
9828
|
+
const errorOutput = (_a = cell === null || cell === void 0 ? void 0 : cell.model.outputs) === null || _a === void 0 ? void 0 : _a.toJSON().find(output => output.output_type === "error");
|
|
9304
9829
|
if (!errorOutput) {
|
|
9305
9830
|
return 'success'; // If no error output, we're done
|
|
9306
9831
|
}
|
|
9307
|
-
const errorMessage = (0,
|
|
9832
|
+
const errorMessage = (0,_Extensions_ErrorMimeRenderer_errorUtils__WEBPACK_IMPORTED_MODULE_3__.getFullErrorMessageFromTraceback)(errorOutput.traceback);
|
|
9308
9833
|
await sendAgentSmartDebugMessage(errorMessage);
|
|
9309
9834
|
const aiDisplayOptimizedChatItem = chatHistoryManagerRef.current.getLastAIDisplayOptimizedChatItem();
|
|
9310
9835
|
// Handle different response types from the agent when fixing errors
|
|
@@ -9315,7 +9840,7 @@ const retryIfExecutionError = async (notebookTracker, app, getDuplicateChatHisto
|
|
|
9315
9840
|
if (agentResponse.type === 'cell_update') {
|
|
9316
9841
|
const cellUpdate = agentResponse.cell_update;
|
|
9317
9842
|
if (cellUpdate !== undefined && cellUpdate !== null) {
|
|
9318
|
-
await acceptAndRunCellUpdate(cellUpdate,
|
|
9843
|
+
await acceptAndRunCellUpdate(cellUpdate, notebookPanel);
|
|
9319
9844
|
}
|
|
9320
9845
|
}
|
|
9321
9846
|
else if (agentResponse.type === 'run_all_cells') {
|
|
@@ -9326,7 +9851,7 @@ const retryIfExecutionError = async (notebookTracker, app, getDuplicateChatHisto
|
|
|
9326
9851
|
}
|
|
9327
9852
|
runAllCellsAttempts++;
|
|
9328
9853
|
// Execute runAllCells to fix NameError issues
|
|
9329
|
-
const result = await runAllCells(app,
|
|
9854
|
+
const result = await runAllCells(app, notebookPanel);
|
|
9330
9855
|
if (!result.success) {
|
|
9331
9856
|
// If run_all_cells resulted in an error, we should continue with error handling
|
|
9332
9857
|
// The error will be caught in the main loop
|
|
@@ -9339,32 +9864,29 @@ const retryIfExecutionError = async (notebookTracker, app, getDuplicateChatHisto
|
|
|
9339
9864
|
}
|
|
9340
9865
|
attempts++;
|
|
9341
9866
|
// If this was the last attempt and it still failed
|
|
9342
|
-
if (attempts === MAX_RETRIES && (0,
|
|
9867
|
+
if (attempts === MAX_RETRIES && (0,_notebook__WEBPACK_IMPORTED_MODULE_1__.didCellExecutionError)(cell)) {
|
|
9343
9868
|
return 'failure';
|
|
9344
9869
|
}
|
|
9345
9870
|
}
|
|
9346
9871
|
return 'success';
|
|
9347
9872
|
};
|
|
9348
|
-
const runAllCells = async (app,
|
|
9873
|
+
const runAllCells = async (app, notebookPanel) => {
|
|
9349
9874
|
var _a, _b;
|
|
9350
|
-
|
|
9875
|
+
const notebook = notebookPanel.content;
|
|
9876
|
+
const sessionContext = (_a = notebookPanel.context) === null || _a === void 0 ? void 0 : _a.sessionContext;
|
|
9877
|
+
await _jupyterlab_notebook__WEBPACK_IMPORTED_MODULE_0__.NotebookActions.runAll(notebook, sessionContext);
|
|
9351
9878
|
// Give the execution some time to complete and update variables
|
|
9352
9879
|
// This ensures that the variable manager has time to update the state
|
|
9353
|
-
await (0,
|
|
9354
|
-
// Check all cells for errors after execution
|
|
9355
|
-
const notebook = (_a = notebookTracker.currentWidget) === null || _a === void 0 ? void 0 : _a.content;
|
|
9356
|
-
if (!notebook) {
|
|
9357
|
-
return { success: false, errorMessage: "No active notebook found" };
|
|
9358
|
-
}
|
|
9880
|
+
await (0,_sleep__WEBPACK_IMPORTED_MODULE_2__.sleep)(2000);
|
|
9359
9881
|
// Iterate through all cells to find any with errors
|
|
9360
9882
|
for (let i = 0; i < notebook.widgets.length; i++) {
|
|
9361
9883
|
const cell = notebook.widgets[i];
|
|
9362
9884
|
if (cell && cell.model.type === 'code') {
|
|
9363
9885
|
const codeCell = cell;
|
|
9364
|
-
if ((0,
|
|
9886
|
+
if ((0,_notebook__WEBPACK_IMPORTED_MODULE_1__.didCellExecutionError)(codeCell)) {
|
|
9365
9887
|
const errorOutput = (_b = codeCell.model.outputs) === null || _b === void 0 ? void 0 : _b.toJSON().find(output => output.output_type === "error");
|
|
9366
9888
|
if (errorOutput) {
|
|
9367
|
-
const errorMessage = (0,
|
|
9889
|
+
const errorMessage = (0,_Extensions_ErrorMimeRenderer_errorUtils__WEBPACK_IMPORTED_MODULE_3__.getFullErrorMessageFromTraceback)(errorOutput.traceback);
|
|
9368
9890
|
return {
|
|
9369
9891
|
success: false,
|
|
9370
9892
|
errorMessage: errorMessage,
|
|
@@ -9507,6 +10029,146 @@ const checkForBlacklistedWords = (code) => {
|
|
|
9507
10029
|
};
|
|
9508
10030
|
|
|
9509
10031
|
|
|
10032
|
+
/***/ }),
|
|
10033
|
+
|
|
10034
|
+
/***/ "./lib/utils/cellMetadata.js":
|
|
10035
|
+
/*!***********************************!*\
|
|
10036
|
+
!*** ./lib/utils/cellMetadata.js ***!
|
|
10037
|
+
\***********************************/
|
|
10038
|
+
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
10039
|
+
|
|
10040
|
+
__webpack_require__.r(__webpack_exports__);
|
|
10041
|
+
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
10042
|
+
/* harmony export */ getActiveCellIncludeInApp: () => (/* binding */ getActiveCellIncludeInApp),
|
|
10043
|
+
/* harmony export */ getIncludeCellInApp: () => (/* binding */ getIncludeCellInApp),
|
|
10044
|
+
/* harmony export */ toggleActiveCellIncludeInAppMetadata: () => (/* binding */ toggleActiveCellIncludeInAppMetadata),
|
|
10045
|
+
/* harmony export */ toggleIncludeCellInAppMetadata: () => (/* binding */ toggleIncludeCellInAppMetadata)
|
|
10046
|
+
/* harmony export */ });
|
|
10047
|
+
/* harmony import */ var _notebook__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./notebook */ "./lib/utils/notebook.js");
|
|
10048
|
+
/*
|
|
10049
|
+
* Copyright (c) Saga Inc.
|
|
10050
|
+
* Distributed under the terms of the GNU Affero General Public License v3.0 License.
|
|
10051
|
+
*/
|
|
10052
|
+
|
|
10053
|
+
const INCLUDE_CELL_IN_APP = 'include-cell-in-app';
|
|
10054
|
+
const toggleActiveCellIncludeInAppMetadata = (notebookTracker) => {
|
|
10055
|
+
const activeCellID = (0,_notebook__WEBPACK_IMPORTED_MODULE_0__.getActiveCellID)(notebookTracker);
|
|
10056
|
+
toggleIncludeCellInAppMetadata(notebookTracker, activeCellID);
|
|
10057
|
+
};
|
|
10058
|
+
const toggleIncludeCellInAppMetadata = (notebookTracker, cellID) => {
|
|
10059
|
+
if (cellID === undefined) {
|
|
10060
|
+
return;
|
|
10061
|
+
}
|
|
10062
|
+
const cell = (0,_notebook__WEBPACK_IMPORTED_MODULE_0__.getCellByID)(notebookTracker, cellID);
|
|
10063
|
+
if (!cell) {
|
|
10064
|
+
return undefined;
|
|
10065
|
+
}
|
|
10066
|
+
if (Object.prototype.hasOwnProperty.call(cell.model.metadata, INCLUDE_CELL_IN_APP)) {
|
|
10067
|
+
const originalVisibility = cell.model.getMetadata(INCLUDE_CELL_IN_APP);
|
|
10068
|
+
cell.model.setMetadata(INCLUDE_CELL_IN_APP, !originalVisibility);
|
|
10069
|
+
}
|
|
10070
|
+
else {
|
|
10071
|
+
// If the metadata doesn't exist yet, that means the user has not yet toggled the visibility.
|
|
10072
|
+
// The default value is to show the output, so the first toggle should set the visibiltiy to false.
|
|
10073
|
+
cell.model.setMetadata(INCLUDE_CELL_IN_APP, false);
|
|
10074
|
+
}
|
|
10075
|
+
};
|
|
10076
|
+
const getActiveCellIncludeInApp = (notebookTracker) => {
|
|
10077
|
+
const activeCellID = (0,_notebook__WEBPACK_IMPORTED_MODULE_0__.getActiveCellID)(notebookTracker);
|
|
10078
|
+
return getIncludeCellInApp(notebookTracker, activeCellID);
|
|
10079
|
+
};
|
|
10080
|
+
const getIncludeCellInApp = (notebookTracker, cellID) => {
|
|
10081
|
+
/*
|
|
10082
|
+
Checks the cell metadata tag to see if the user has marked that this cell should not be included in the app.
|
|
10083
|
+
*/
|
|
10084
|
+
const cell = (0,_notebook__WEBPACK_IMPORTED_MODULE_0__.getCellByID)(notebookTracker, cellID);
|
|
10085
|
+
if (!cell) {
|
|
10086
|
+
return false;
|
|
10087
|
+
}
|
|
10088
|
+
if (!Object.prototype.hasOwnProperty.call(cell.model.metadata, INCLUDE_CELL_IN_APP)) {
|
|
10089
|
+
cell.model.setMetadata(INCLUDE_CELL_IN_APP, true);
|
|
10090
|
+
}
|
|
10091
|
+
return cell.model.getMetadata(INCLUDE_CELL_IN_APP);
|
|
10092
|
+
};
|
|
10093
|
+
|
|
10094
|
+
|
|
10095
|
+
/***/ }),
|
|
10096
|
+
|
|
10097
|
+
/***/ "./lib/utils/cellOutput.js":
|
|
10098
|
+
/*!*********************************!*\
|
|
10099
|
+
!*** ./lib/utils/cellOutput.js ***!
|
|
10100
|
+
\*********************************/
|
|
10101
|
+
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
10102
|
+
|
|
10103
|
+
__webpack_require__.r(__webpack_exports__);
|
|
10104
|
+
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
10105
|
+
/* harmony export */ getActiveCellOutput: () => (/* binding */ getActiveCellOutput),
|
|
10106
|
+
/* harmony export */ getCellOutputByID: () => (/* binding */ getCellOutputByID),
|
|
10107
|
+
/* harmony export */ getCellOutputByIDInNotebook: () => (/* binding */ getCellOutputByIDInNotebook)
|
|
10108
|
+
/* harmony export */ });
|
|
10109
|
+
/* harmony import */ var _jupyterlab_cells__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @jupyterlab/cells */ "webpack/sharing/consume/default/@jupyterlab/cells");
|
|
10110
|
+
/* harmony import */ var _jupyterlab_cells__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_jupyterlab_cells__WEBPACK_IMPORTED_MODULE_0__);
|
|
10111
|
+
/* harmony import */ var _notebook__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./notebook */ "./lib/utils/notebook.js");
|
|
10112
|
+
/*
|
|
10113
|
+
* Copyright (c) Saga Inc.
|
|
10114
|
+
* Distributed under the terms of the GNU Affero General Public License v3.0 License.
|
|
10115
|
+
*/
|
|
10116
|
+
|
|
10117
|
+
|
|
10118
|
+
const getActiveCellOutput = async (notebookTracker) => {
|
|
10119
|
+
const activeCellID = (0,_notebook__WEBPACK_IMPORTED_MODULE_1__.getActiveCellID)(notebookTracker);
|
|
10120
|
+
return getCellOutputByID(notebookTracker, activeCellID);
|
|
10121
|
+
};
|
|
10122
|
+
const getCellOutputByID = async (notebookTracker, codeCellID) => {
|
|
10123
|
+
const notebookPanel = notebookTracker.currentWidget;
|
|
10124
|
+
return getCellOutputByIDInNotebook(notebookPanel, codeCellID);
|
|
10125
|
+
};
|
|
10126
|
+
const getCellOutputByIDInNotebook = async (notebookPanel, codeCellID) => {
|
|
10127
|
+
// TODO: There is a bug where if the cell is not actually rendered on the screen,
|
|
10128
|
+
// then the output is not captured. This is pretty unlikely to happen currently because
|
|
10129
|
+
// the agent scrolls to the cell.
|
|
10130
|
+
var _a;
|
|
10131
|
+
if (codeCellID === undefined || notebookPanel === null) {
|
|
10132
|
+
return undefined;
|
|
10133
|
+
}
|
|
10134
|
+
const cell = notebookPanel.content.widgets.find(cell => cell.model.id === codeCellID);
|
|
10135
|
+
if (!(cell instanceof _jupyterlab_cells__WEBPACK_IMPORTED_MODULE_0__.CodeCell)) {
|
|
10136
|
+
return undefined;
|
|
10137
|
+
}
|
|
10138
|
+
const outputNode = (_a = cell.outputArea) === null || _a === void 0 ? void 0 : _a.node;
|
|
10139
|
+
if (!outputNode)
|
|
10140
|
+
return undefined;
|
|
10141
|
+
// Find the top-level Jupyter image output div
|
|
10142
|
+
// so we can check if there is a base64 encoded image
|
|
10143
|
+
// already constructed for us.
|
|
10144
|
+
const renderedImageDiv = outputNode.querySelector('.jp-RenderedImage.jp-OutputArea-output');
|
|
10145
|
+
// If the image is the top-level output, then just use that instead
|
|
10146
|
+
// of capturing the entire output node. This is much faster and handles
|
|
10147
|
+
// matplotlib graphs.
|
|
10148
|
+
if (renderedImageDiv) {
|
|
10149
|
+
const img = renderedImageDiv.querySelector('img');
|
|
10150
|
+
if (img && img.src.startsWith('data:image')) {
|
|
10151
|
+
console.log('image found in top-level output');
|
|
10152
|
+
// Remove the data URL prefix
|
|
10153
|
+
// The img is initially in the format data:image/png;base64, <base64_data>
|
|
10154
|
+
// We want to return the base64 data.
|
|
10155
|
+
const base64 = img.src.split(',')[1];
|
|
10156
|
+
return base64;
|
|
10157
|
+
}
|
|
10158
|
+
}
|
|
10159
|
+
// Fallback: (optional) handle other output types, or use captureNode if needed
|
|
10160
|
+
// Previously, we used html2canvas to capture the entire output node. This would
|
|
10161
|
+
// give us the output even if it was html, svg, text, etc. However, starting around
|
|
10162
|
+
// Chrome release 138, html2canvas became untenably slow. https://issues.chromium.org/issues/429073017
|
|
10163
|
+
if (outputNode) {
|
|
10164
|
+
// If the AI requested, a cell output that we cannot provide, we just tell it
|
|
10165
|
+
// "Cell Output is present in notebook, but not available to share with the AI right now"
|
|
10166
|
+
return "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rNkrAoqAIqAIKAKKgCKgCCgCioAioAgoAoqAIqAIKAKKgCKgjliVAUVAEVAEFAFFQBFQBBQBRUARUAQUAUVAEVAEFAFFQBFQBJqMwHDjiP3888+jUPXq1cuMPPLI0TB5+NNPP5mff/5Zfrprz549zfjjj+9+640ioAgoAoqAItAKBP7++28zbNiwpKgxxhijFUWWWsZvv/1murq6TI8ePcxoo41Wat7NzKy7495MbDTv4ROBIvZzEUTKaGvt4r1IvUf0tL/++msCAf0C/YPS8I+A2AOMx0cdddRuVeHuzHu3Ano4YlZ13HD0MptclaY5YocOHWpef/118+qrrxruJ5tsMjP11FObxRZbzIwyyiilVuubb74xvXv3juZ5xRVXmEUWWSQaJg+POOIIc9FFF8lPd11ooYXM1Vdf7X43++aLL74wL7/8snnllVfMOOOMY+aee24zxxxzmO44CG82Vp2Y//TTT5+wtdlmm5n+/ft3IovKkyLgENhuu+3Mvffem+jlBx54wD3Xm85A4PLLLzf9+vVLmBk8eLCZccYZO4OxBrmg//z222+Tfuymm25qMFX7o3V33NuPoHLQbgReeukls/baaydsDBo0yKyxxhqpLBW1n1MzbiCgaFtrJ+8NVE+jRBB47733zPLLL5+EHH744aZPnz6RWPqoVQi0atwi9sBKK61kzjzzzFZVr5RyujPvPgA4lPHLCPHuxxtvPPlZdf3hhx/Mu+++W/U89mDKKac0E088cSyoY55l6ReLMK06rgh6I17a0h2xzALsv//+5vbbb4+iOeaYY5oTTjjBrLjiitHwPA+/++47s+CCC0aTNuKIHTBggLnggguq0rfKEcuqgEMOOcRceeWVVTzw4PzzzzfLLLNMNKyshy+++KIZMmRIkt1WW21lJpxwwrKybno+ncK7GDQbbrihGThwYNPrrQV0TwQ6RV633nprgwN20kknNY899lj3BLOFXN92223mjTfeMKOPPrrp27dv00u+7LLLkn6Bgu6++24z00wzNb3MMguQwQsTit3JEdspuGPXiF2ywgormHnmmafM19PRebW6rXU0GDmYe/755816662XpDzxxBOdUzaWVVH7OZZno8+KtrV28t5oHRuJNyLJu++kOOyww8wWW2zRCEQap0kI5Bm35JHXueaay/zyyy+m3Y7Y7sx7URG48847K2zX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";
|
|
10167
|
+
}
|
|
10168
|
+
return undefined;
|
|
10169
|
+
};
|
|
10170
|
+
|
|
10171
|
+
|
|
9510
10172
|
/***/ }),
|
|
9511
10173
|
|
|
9512
10174
|
/***/ "./lib/utils/chatHistory.js":
|
|
@@ -9994,23 +10656,19 @@ const stripFileEnding = (rule) => {
|
|
|
9994
10656
|
|
|
9995
10657
|
__webpack_require__.r(__webpack_exports__);
|
|
9996
10658
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
9997
|
-
/* harmony export */ CLAUDE_OPUS_DISPLAY_NAME: () => (/* binding */ CLAUDE_OPUS_DISPLAY_NAME),
|
|
9998
|
-
/* harmony export */ CLAUDE_OPUS_MODEL_NAME: () => (/* binding */ CLAUDE_OPUS_MODEL_NAME),
|
|
9999
10659
|
/* harmony export */ CLAUDE_SONNET_DISPLAY_NAME: () => (/* binding */ CLAUDE_SONNET_DISPLAY_NAME),
|
|
10000
10660
|
/* harmony export */ CLAUDE_SONNET_MODEL_NAME: () => (/* binding */ CLAUDE_SONNET_MODEL_NAME),
|
|
10001
|
-
/* harmony export */
|
|
10002
|
-
/* harmony export */
|
|
10661
|
+
/* harmony export */ GPT_4_1_DISPLAY_NAME: () => (/* binding */ GPT_4_1_DISPLAY_NAME),
|
|
10662
|
+
/* harmony export */ GPT_4_1_MODEL_NAME: () => (/* binding */ GPT_4_1_MODEL_NAME)
|
|
10003
10663
|
/* harmony export */ });
|
|
10004
10664
|
/*
|
|
10005
10665
|
* Copyright (c) Saga Inc.
|
|
10006
10666
|
* Distributed under the terms of the GNU Affero General Public License v3.0 License.
|
|
10007
10667
|
*/
|
|
10008
|
-
const
|
|
10009
|
-
const
|
|
10010
|
-
const
|
|
10011
|
-
const
|
|
10012
|
-
const GPT_DISPLAY_NAME = 'GPT 5 (max)';
|
|
10013
|
-
const GPT_MODEL_NAME = 'gpt-5';
|
|
10668
|
+
const CLAUDE_SONNET_DISPLAY_NAME = 'Claude 4.5 Sonnet';
|
|
10669
|
+
const CLAUDE_SONNET_MODEL_NAME = 'claude-sonnet-4-5-20250929';
|
|
10670
|
+
const GPT_4_1_DISPLAY_NAME = 'GPT 4.1';
|
|
10671
|
+
const GPT_4_1_MODEL_NAME = 'gpt-4.1';
|
|
10014
10672
|
|
|
10015
10673
|
|
|
10016
10674
|
/***/ }),
|
|
@@ -10026,156 +10684,82 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
10026
10684
|
/* harmony export */ createCodeCellAtIndexAndActivate: () => (/* binding */ createCodeCellAtIndexAndActivate),
|
|
10027
10685
|
/* harmony export */ didCellExecutionError: () => (/* binding */ didCellExecutionError),
|
|
10028
10686
|
/* harmony export */ getAIOptimizedCells: () => (/* binding */ getAIOptimizedCells),
|
|
10687
|
+
/* harmony export */ getAIOptimizedCellsInNotebookPanel: () => (/* binding */ getAIOptimizedCellsInNotebookPanel),
|
|
10029
10688
|
/* harmony export */ getActiveCell: () => (/* binding */ getActiveCell),
|
|
10030
10689
|
/* harmony export */ getActiveCellCode: () => (/* binding */ getActiveCellCode),
|
|
10031
10690
|
/* harmony export */ getActiveCellID: () => (/* binding */ getActiveCellID),
|
|
10032
|
-
/* harmony export */
|
|
10033
|
-
/* harmony export */
|
|
10691
|
+
/* harmony export */ getActiveCellIDInNotebookPanel: () => (/* binding */ getActiveCellIDInNotebookPanel),
|
|
10692
|
+
/* harmony export */ getActiveCellInNotebookPanel: () => (/* binding */ getActiveCellInNotebookPanel),
|
|
10034
10693
|
/* harmony export */ getCellByID: () => (/* binding */ getCellByID),
|
|
10694
|
+
/* harmony export */ getCellByIDInNotebookPanel: () => (/* binding */ getCellByIDInNotebookPanel),
|
|
10035
10695
|
/* harmony export */ getCellCodeByID: () => (/* binding */ getCellCodeByID),
|
|
10696
|
+
/* harmony export */ getCellCodeByIDInNotebookPanel: () => (/* binding */ getCellCodeByIDInNotebookPanel),
|
|
10036
10697
|
/* harmony export */ getCellIndexByID: () => (/* binding */ getCellIndexByID),
|
|
10037
|
-
/* harmony export */
|
|
10038
|
-
/* harmony export */ getIncludeCellInApp: () => (/* binding */ getIncludeCellInApp),
|
|
10698
|
+
/* harmony export */ getCellIndexByIDInNotebookPanel: () => (/* binding */ getCellIndexByIDInNotebookPanel),
|
|
10039
10699
|
/* harmony export */ getNotebookName: () => (/* binding */ getNotebookName),
|
|
10040
10700
|
/* harmony export */ highlightCodeCell: () => (/* binding */ highlightCodeCell),
|
|
10041
10701
|
/* harmony export */ highlightLinesOfCodeInCodeCell: () => (/* binding */ highlightLinesOfCodeInCodeCell),
|
|
10042
10702
|
/* harmony export */ scrollToAndHighlightCell: () => (/* binding */ scrollToAndHighlightCell),
|
|
10043
10703
|
/* harmony export */ scrollToCell: () => (/* binding */ scrollToCell),
|
|
10044
10704
|
/* harmony export */ setActiveCellByID: () => (/* binding */ setActiveCellByID),
|
|
10045
|
-
/* harmony export */
|
|
10046
|
-
/* harmony export */
|
|
10047
|
-
/* harmony export */
|
|
10705
|
+
/* harmony export */ setActiveCellByIDInNotebookPanel: () => (/* binding */ setActiveCellByIDInNotebookPanel),
|
|
10706
|
+
/* harmony export */ writeCodeToCellByID: () => (/* binding */ writeCodeToCellByID),
|
|
10707
|
+
/* harmony export */ writeCodeToCellByIDInNotebookPanel: () => (/* binding */ writeCodeToCellByIDInNotebookPanel)
|
|
10048
10708
|
/* harmony export */ });
|
|
10049
10709
|
/* harmony import */ var _jupyterlab_notebook__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @jupyterlab/notebook */ "webpack/sharing/consume/default/@jupyterlab/notebook");
|
|
10050
10710
|
/* harmony import */ var _jupyterlab_notebook__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_jupyterlab_notebook__WEBPACK_IMPORTED_MODULE_0__);
|
|
10051
|
-
/* harmony import */ var
|
|
10052
|
-
/* harmony import */ var _jupyterlab_cells__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_jupyterlab_cells__WEBPACK_IMPORTED_MODULE_1__);
|
|
10053
|
-
/* harmony import */ var _strings__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./strings */ "./lib/utils/strings.js");
|
|
10711
|
+
/* harmony import */ var _strings__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./strings */ "./lib/utils/strings.js");
|
|
10054
10712
|
/*
|
|
10055
10713
|
* Copyright (c) Saga Inc.
|
|
10056
10714
|
* Distributed under the terms of the GNU Affero General Public License v3.0 License.
|
|
10057
10715
|
*/
|
|
10058
10716
|
|
|
10059
10717
|
|
|
10060
|
-
|
|
10061
|
-
const INCLUDE_CELL_IN_APP = 'include-cell-in-app';
|
|
10062
10718
|
const getActiveCell = (notebookTracker) => {
|
|
10063
|
-
|
|
10064
|
-
|
|
10065
|
-
|
|
10719
|
+
const notebookPanel = notebookTracker.currentWidget;
|
|
10720
|
+
return getActiveCellInNotebookPanel(notebookPanel);
|
|
10721
|
+
};
|
|
10722
|
+
const getActiveCellInNotebookPanel = (notebookPanel) => {
|
|
10723
|
+
const activeCell = notebookPanel === null || notebookPanel === void 0 ? void 0 : notebookPanel.content.activeCell;
|
|
10066
10724
|
return activeCell || undefined;
|
|
10067
10725
|
};
|
|
10068
10726
|
const getCellByID = (notebookTracker, cellID) => {
|
|
10069
|
-
|
|
10070
|
-
|
|
10071
|
-
return undefined;
|
|
10072
|
-
}
|
|
10073
|
-
const notebook = (_a = notebookTracker.currentWidget) === null || _a === void 0 ? void 0 : _a.content;
|
|
10074
|
-
return notebook === null || notebook === void 0 ? void 0 : notebook.widgets.find(cell => cell.model.id === cellID);
|
|
10727
|
+
const notebook = notebookTracker.currentWidget;
|
|
10728
|
+
return getCellByIDInNotebookPanel(notebook, cellID);
|
|
10075
10729
|
};
|
|
10076
|
-
const
|
|
10077
|
-
const activeCellID = getActiveCellID(notebookTracker);
|
|
10078
|
-
toggleIncludeCellInAppMetadata(notebookTracker, activeCellID);
|
|
10079
|
-
};
|
|
10080
|
-
const toggleIncludeCellInAppMetadata = (notebookTracker, cellID) => {
|
|
10730
|
+
const getCellByIDInNotebookPanel = (notebookPanel, cellID) => {
|
|
10081
10731
|
if (cellID === undefined) {
|
|
10082
|
-
return;
|
|
10083
|
-
}
|
|
10084
|
-
const cell = getCellByID(notebookTracker, cellID);
|
|
10085
|
-
if (!cell) {
|
|
10086
10732
|
return undefined;
|
|
10087
10733
|
}
|
|
10088
|
-
|
|
10089
|
-
const originalVisibility = cell.model.getMetadata(INCLUDE_CELL_IN_APP);
|
|
10090
|
-
cell.model.setMetadata(INCLUDE_CELL_IN_APP, !originalVisibility);
|
|
10091
|
-
}
|
|
10092
|
-
else {
|
|
10093
|
-
// If the metadata doesn't exist yet, that means the user has not yet toggled the visibility.
|
|
10094
|
-
// The default value is to show the output, so the first toggle should set the visibiltiy to false.
|
|
10095
|
-
cell.model.setMetadata(INCLUDE_CELL_IN_APP, false);
|
|
10096
|
-
}
|
|
10097
|
-
};
|
|
10098
|
-
const getActiveCellIncludeInApp = (notebookTracker) => {
|
|
10099
|
-
const activeCellID = getActiveCellID(notebookTracker);
|
|
10100
|
-
return getIncludeCellInApp(notebookTracker, activeCellID);
|
|
10101
|
-
};
|
|
10102
|
-
const getIncludeCellInApp = (notebookTracker, cellID) => {
|
|
10103
|
-
/*
|
|
10104
|
-
Checks the cell metadata tag to see if the user has marked that this cell should not be included in the app.
|
|
10105
|
-
*/
|
|
10106
|
-
const cell = getCellByID(notebookTracker, cellID);
|
|
10107
|
-
if (!cell) {
|
|
10108
|
-
return false;
|
|
10109
|
-
}
|
|
10110
|
-
if (!Object.prototype.hasOwnProperty.call(cell.model.metadata, INCLUDE_CELL_IN_APP)) {
|
|
10111
|
-
cell.model.setMetadata(INCLUDE_CELL_IN_APP, true);
|
|
10112
|
-
}
|
|
10113
|
-
return cell.model.getMetadata(INCLUDE_CELL_IN_APP);
|
|
10734
|
+
return notebookPanel === null || notebookPanel === void 0 ? void 0 : notebookPanel.content.widgets.find(cell => cell.model.id === cellID);
|
|
10114
10735
|
};
|
|
10115
10736
|
const getActiveCellID = (notebookTracker) => {
|
|
10737
|
+
const notebookPanel = notebookTracker.currentWidget;
|
|
10738
|
+
return getActiveCellIDInNotebookPanel(notebookPanel);
|
|
10739
|
+
};
|
|
10740
|
+
const getActiveCellIDInNotebookPanel = (notebookPanel) => {
|
|
10116
10741
|
var _a;
|
|
10117
|
-
return (_a =
|
|
10742
|
+
return (_a = getActiveCellInNotebookPanel(notebookPanel)) === null || _a === void 0 ? void 0 : _a.model.id;
|
|
10118
10743
|
};
|
|
10119
10744
|
const getActiveCellCode = (notebookTracker) => {
|
|
10120
10745
|
const activeCell = getActiveCell(notebookTracker);
|
|
10121
10746
|
return activeCell === null || activeCell === void 0 ? void 0 : activeCell.model.sharedModel.source;
|
|
10122
10747
|
};
|
|
10123
10748
|
const getCellCodeByID = (notebookTracker, codeCellID) => {
|
|
10124
|
-
const
|
|
10125
|
-
return
|
|
10126
|
-
};
|
|
10127
|
-
const getActiveCellOutput = async (notebookTracker) => {
|
|
10128
|
-
const activeCellID = getActiveCellID(notebookTracker);
|
|
10129
|
-
return getCellOutputByID(notebookTracker, activeCellID);
|
|
10749
|
+
const notebookPanel = notebookTracker.currentWidget;
|
|
10750
|
+
return getCellCodeByIDInNotebookPanel(notebookPanel, codeCellID);
|
|
10130
10751
|
};
|
|
10131
|
-
const
|
|
10132
|
-
|
|
10133
|
-
|
|
10134
|
-
// the agent scrolls to the cell.
|
|
10135
|
-
var _a, _b;
|
|
10136
|
-
if (codeCellID === undefined) {
|
|
10137
|
-
return undefined;
|
|
10138
|
-
}
|
|
10139
|
-
const notebook = (_a = notebookTracker.currentWidget) === null || _a === void 0 ? void 0 : _a.content;
|
|
10140
|
-
const cell = notebook === null || notebook === void 0 ? void 0 : notebook.widgets.find(cell => cell.model.id === codeCellID);
|
|
10141
|
-
if (!(cell instanceof _jupyterlab_cells__WEBPACK_IMPORTED_MODULE_1__.CodeCell)) {
|
|
10142
|
-
return undefined;
|
|
10143
|
-
}
|
|
10144
|
-
const outputNode = (_b = cell.outputArea) === null || _b === void 0 ? void 0 : _b.node;
|
|
10145
|
-
if (!outputNode)
|
|
10146
|
-
return undefined;
|
|
10147
|
-
// Find the top-level Jupyter image output div
|
|
10148
|
-
// so we can check if there is a base64 encoded image
|
|
10149
|
-
// already constructed for us.
|
|
10150
|
-
const renderedImageDiv = outputNode.querySelector('.jp-RenderedImage.jp-OutputArea-output');
|
|
10151
|
-
// If the image is the top-level output, then just use that instead
|
|
10152
|
-
// of capturing the entire output node. This is much faster and handles
|
|
10153
|
-
// matplotlib graphs.
|
|
10154
|
-
if (renderedImageDiv) {
|
|
10155
|
-
const img = renderedImageDiv.querySelector('img');
|
|
10156
|
-
if (img && img.src.startsWith('data:image')) {
|
|
10157
|
-
console.log('image found in top-level output');
|
|
10158
|
-
// Remove the data URL prefix
|
|
10159
|
-
// The img is initially in the format data:image/png;base64, <base64_data>
|
|
10160
|
-
// We want to return the base64 data.
|
|
10161
|
-
const base64 = img.src.split(',')[1];
|
|
10162
|
-
return base64;
|
|
10163
|
-
}
|
|
10164
|
-
}
|
|
10165
|
-
// Fallback: (optional) handle other output types, or use captureNode if needed
|
|
10166
|
-
// Previously, we used html2canvas to capture the entire output node. This would
|
|
10167
|
-
// give us the output even if it was html, svg, text, etc. However, starting around
|
|
10168
|
-
// Chrome release 138, html2canvas became untenably slow. https://issues.chromium.org/issues/429073017
|
|
10169
|
-
if (outputNode) {
|
|
10170
|
-
// If the AI requested, a cell output that we cannot provide, we just tell it
|
|
10171
|
-
// "Cell Output is present in notebook, but not available to share with the AI right now"
|
|
10172
|
-
return "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rNkrAoqAIqAIKAKKgCKgCCgCioAioAgoAoqAIqAIKAKKgCKgjliVAUVAEVAEFAFFQBFQBBQBRUARUAQUAUVAEVAEFAFFQBFQBJqMwHDjiP3888+jUPXq1cuMPPLI0TB5+NNPP5mff/5Zfrprz549zfjjj+9+640ioAgoAoqAItAKBP7++28zbNiwpKgxxhijFUWWWsZvv/1murq6TI8ePcxoo41Wat7NzKy7495MbDTv4ROBIvZzEUTKaGvt4r1IvUf0tL/++msCAf0C/YPS8I+A2AOMx0cdddRuVeHuzHu3Ano4YlZ13HD0MptclaY5YocOHWpef/118+qrrxruJ5tsMjP11FObxRZbzIwyyiilVuubb74xvXv3juZ5xRVXmEUWWSQaJg+POOIIc9FFF8lPd11ooYXM1Vdf7X43++aLL74wL7/8snnllVfMOOOMY+aee24zxxxzmO44CG82Vp2Y//TTT5+wtdlmm5n+/ft3IovKkyLgENhuu+3Mvffem+jlBx54wD3Xm85A4PLLLzf9+vVLmBk8eLCZccYZO4OxBrmg//z222+Tfuymm25qMFX7o3V33NuPoHLQbgReeukls/baaydsDBo0yKyxxhqpLBW1n1MzbiCgaFtrJ+8NVE+jRBB47733zPLLL5+EHH744aZPnz6RWPqoVQi0atwi9sBKK61kzjzzzFZVr5RyujPvPgA4lPHLCPHuxxtvPPlZdf3hhx/Mu+++W/U89mDKKac0E088cSyoY55l6ReLMK06rgh6I17a0h2xzALsv//+5vbbb4+iOeaYY5oTTjjBrLjiitHwPA+/++47s+CCC0aTNuKIHTBggLnggguq0rfKEcuqgEMOOcRceeWVVTzw4PzzzzfLLLNMNKyshy+++KIZMmRIkt1WW21lJpxwwrKybno+ncK7GDQbbrihGThwYNPrrQV0TwQ6RV633nprgwN20kknNY899lj3BLOFXN92223mjTfeMKOPPrrp27dv00u+7LLLkn6Bgu6++24z00wzNb3MMguQwQsTit3JEdspuGPXiF2ywgormHnmmafM19PRebW6rXU0GDmYe/755816662XpDzxxBOdUzaWVVH7OZZno8+KtrV28t5oHRuJNyLJu++kOOyww8wWW2zRCEQap0kI5Bm35JHXueaay/zyyy+m3Y7Y7sx7URG48847K2zX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";
|
|
10173
|
-
}
|
|
10174
|
-
return undefined;
|
|
10752
|
+
const getCellCodeByIDInNotebookPanel = (notebookPanel, codeCellID) => {
|
|
10753
|
+
const cell = getCellByIDInNotebookPanel(notebookPanel, codeCellID);
|
|
10754
|
+
return cell === null || cell === void 0 ? void 0 : cell.model.sharedModel.source;
|
|
10175
10755
|
};
|
|
10176
10756
|
const getCellIndexByID = (notebookTracker, cellID) => {
|
|
10177
|
-
|
|
10178
|
-
|
|
10757
|
+
const notebookPanel = notebookTracker.currentWidget;
|
|
10758
|
+
return getCellIndexByIDInNotebookPanel(notebookPanel, cellID);
|
|
10759
|
+
};
|
|
10760
|
+
const getCellIndexByIDInNotebookPanel = (notebookPanel, cellID) => {
|
|
10761
|
+
var _a;
|
|
10762
|
+
const cellList = (_a = notebookPanel === null || notebookPanel === void 0 ? void 0 : notebookPanel.model) === null || _a === void 0 ? void 0 : _a.cells;
|
|
10179
10763
|
if (cellList === undefined) {
|
|
10180
10764
|
return undefined;
|
|
10181
10765
|
}
|
|
@@ -10190,28 +10774,38 @@ const getCellIndexByID = (notebookTracker, cellID) => {
|
|
|
10190
10774
|
return undefined;
|
|
10191
10775
|
};
|
|
10192
10776
|
const setActiveCellByID = (notebookTracker, cellID) => {
|
|
10193
|
-
const cellIndex = getCellIndexByID(notebookTracker, cellID);
|
|
10194
10777
|
const notebookPanel = notebookTracker.currentWidget;
|
|
10195
|
-
|
|
10778
|
+
setActiveCellByIDInNotebookPanel(notebookPanel, cellID);
|
|
10779
|
+
};
|
|
10780
|
+
const setActiveCellByIDInNotebookPanel = (notebookPanel, cellID) => {
|
|
10781
|
+
const cellIndex = getCellIndexByIDInNotebookPanel(notebookPanel, cellID);
|
|
10782
|
+
if (cellIndex !== undefined && notebookPanel !== null) {
|
|
10196
10783
|
notebookPanel.content.activeCellIndex = cellIndex;
|
|
10197
10784
|
}
|
|
10198
10785
|
};
|
|
10199
10786
|
const writeCodeToCellByID = (notebookTracker, code, codeCellID) => {
|
|
10200
|
-
|
|
10201
|
-
|
|
10787
|
+
const notebookPanel = notebookTracker.currentWidget;
|
|
10788
|
+
writeCodeToCellByIDInNotebookPanel(notebookPanel, code, codeCellID);
|
|
10789
|
+
};
|
|
10790
|
+
const writeCodeToCellByIDInNotebookPanel = (notebookPanel, code, codeCellID) => {
|
|
10791
|
+
if (code === undefined || codeCellID === undefined) {
|
|
10202
10792
|
return;
|
|
10203
10793
|
}
|
|
10204
|
-
const codeMirrorValidCode = (0,
|
|
10205
|
-
const notebook =
|
|
10794
|
+
const codeMirrorValidCode = (0,_strings__WEBPACK_IMPORTED_MODULE_1__.removeMarkdownCodeFormatting)(code);
|
|
10795
|
+
const notebook = notebookPanel === null || notebookPanel === void 0 ? void 0 : notebookPanel.content;
|
|
10206
10796
|
const cell = notebook === null || notebook === void 0 ? void 0 : notebook.widgets.find(cell => cell.model.id === codeCellID);
|
|
10207
10797
|
if (cell) {
|
|
10208
10798
|
cell.model.sharedModel.source = codeMirrorValidCode;
|
|
10209
10799
|
}
|
|
10210
10800
|
};
|
|
10211
10801
|
const getAIOptimizedCells = (notebookTracker) => {
|
|
10212
|
-
|
|
10213
|
-
|
|
10214
|
-
|
|
10802
|
+
const notebookPanel = notebookTracker.currentWidget;
|
|
10803
|
+
return getAIOptimizedCellsInNotebookPanel(notebookPanel);
|
|
10804
|
+
};
|
|
10805
|
+
const getAIOptimizedCellsInNotebookPanel = (notebookPanel) => {
|
|
10806
|
+
var _a;
|
|
10807
|
+
const cellList = (_a = notebookPanel === null || notebookPanel === void 0 ? void 0 : notebookPanel.model) === null || _a === void 0 ? void 0 : _a.cells;
|
|
10808
|
+
if (cellList == undefined || cellList == null) {
|
|
10215
10809
|
return [];
|
|
10216
10810
|
}
|
|
10217
10811
|
// In order to get the cell index, we need to iterate over the cells and call the `get` method
|
|
@@ -10228,12 +10822,11 @@ const getAIOptimizedCells = (notebookTracker) => {
|
|
|
10228
10822
|
}
|
|
10229
10823
|
return cells;
|
|
10230
10824
|
};
|
|
10231
|
-
function createCodeCellAtIndexAndActivate(
|
|
10825
|
+
function createCodeCellAtIndexAndActivate(notebookPanel, index) {
|
|
10232
10826
|
/*
|
|
10233
10827
|
Create a new code cell at index and make it the active cell.
|
|
10234
10828
|
*/
|
|
10235
|
-
|
|
10236
|
-
const notebook = (_a = notebookTracker.currentWidget) === null || _a === void 0 ? void 0 : _a.content;
|
|
10829
|
+
const notebook = notebookPanel.content;
|
|
10237
10830
|
if (notebook === undefined) {
|
|
10238
10831
|
return;
|
|
10239
10832
|
}
|
|
@@ -10280,7 +10873,7 @@ const highlightCodeCell = (notebookTracker, codeCellID) => {
|
|
|
10280
10873
|
}, 500);
|
|
10281
10874
|
}
|
|
10282
10875
|
};
|
|
10283
|
-
const highlightLinesOfCodeInCodeCell = (
|
|
10876
|
+
const highlightLinesOfCodeInCodeCell = (notebookPanel, codeCellID, startLine, endLine) => {
|
|
10284
10877
|
/*
|
|
10285
10878
|
Briefly highlights a range of lines in a code cell, to draw the user's attention to it.
|
|
10286
10879
|
|
|
@@ -10293,7 +10886,7 @@ const highlightLinesOfCodeInCodeCell = (notebookTracker, codeCellID, startLine,
|
|
|
10293
10886
|
endLine: The 0-indexed end line number to highlight (inclusive).
|
|
10294
10887
|
*/
|
|
10295
10888
|
// Get the cell with the given ID
|
|
10296
|
-
const cell =
|
|
10889
|
+
const cell = getCellByIDInNotebookPanel(notebookPanel, codeCellID);
|
|
10297
10890
|
if (!cell) {
|
|
10298
10891
|
return;
|
|
10299
10892
|
}
|
|
@@ -10337,42 +10930,44 @@ const highlightLinesOfCodeInCodeCell = (notebookTracker, codeCellID, startLine,
|
|
|
10337
10930
|
});
|
|
10338
10931
|
}, 2000);
|
|
10339
10932
|
};
|
|
10340
|
-
const scrollToAndHighlightCell = (
|
|
10933
|
+
const scrollToAndHighlightCell = (notebookPanel, cellID, startLine, endLine, position = 'center') => {
|
|
10934
|
+
if (notebookPanel === null) {
|
|
10935
|
+
return;
|
|
10936
|
+
}
|
|
10341
10937
|
// Scroll to the cell
|
|
10342
|
-
scrollToCell(
|
|
10938
|
+
scrollToCell(notebookPanel, cellID, startLine, position);
|
|
10343
10939
|
// Wait for the scroll animation to complete before highlighting the lines
|
|
10344
10940
|
// The default smooth scroll takes about 300-500ms to complete
|
|
10345
10941
|
setTimeout(() => {
|
|
10346
10942
|
if (startLine !== undefined) {
|
|
10347
10943
|
// If no end line was provided, then we just highlight the single line
|
|
10348
10944
|
endLine = endLine || startLine;
|
|
10349
|
-
highlightLinesOfCodeInCodeCell(
|
|
10945
|
+
highlightLinesOfCodeInCodeCell(notebookPanel, cellID, startLine, endLine);
|
|
10350
10946
|
}
|
|
10351
10947
|
else {
|
|
10352
10948
|
// If no start line was provided, then we just highlight the entire cell
|
|
10353
|
-
highlightLinesOfCodeInCodeCell(
|
|
10949
|
+
highlightLinesOfCodeInCodeCell(notebookPanel, cellID, undefined, undefined);
|
|
10354
10950
|
}
|
|
10355
10951
|
}, 500);
|
|
10356
10952
|
};
|
|
10357
|
-
const scrollToCell = (
|
|
10358
|
-
var _a;
|
|
10953
|
+
const scrollToCell = (notebookPanel, cellID, startLine, position = 'center') => {
|
|
10359
10954
|
// Get the cell
|
|
10360
|
-
const cell =
|
|
10361
|
-
if (!cell) {
|
|
10955
|
+
const cell = getCellByIDInNotebookPanel(notebookPanel, cellID);
|
|
10956
|
+
if (!cell || notebookPanel === null) {
|
|
10362
10957
|
return;
|
|
10363
10958
|
}
|
|
10364
10959
|
// If line numbers are provided, figure out what position to scroll to
|
|
10365
10960
|
// based on the start line's position in the cell
|
|
10366
|
-
const code =
|
|
10961
|
+
const code = getCellCodeByIDInNotebookPanel(notebookPanel, cellID);
|
|
10367
10962
|
startLine = startLine || 0;
|
|
10368
10963
|
const relativeLinePosition = startLine / ((code === null || code === void 0 ? void 0 : code.split('\n').length) || 1);
|
|
10369
10964
|
// These positions must be of type BaseScrollToAlignment defined in @jupyterlab/ui-components
|
|
10370
10965
|
position = relativeLinePosition < 0.5 ? 'start' : 'end';
|
|
10371
10966
|
// If the cell is not the active cell, the scrolling does not work.
|
|
10372
10967
|
// It scrolls to the cell and then flashes back to the active cell.
|
|
10373
|
-
|
|
10968
|
+
setActiveCellByIDInNotebookPanel(notebookPanel, cellID);
|
|
10374
10969
|
// Use the new JupyterLab scrollToCell method instead of DOM node scrollIntoView
|
|
10375
|
-
void
|
|
10970
|
+
void notebookPanel.content.scrollToCell(cell, position);
|
|
10376
10971
|
};
|
|
10377
10972
|
|
|
10378
10973
|
|
|
@@ -10683,7 +11278,8 @@ const STRIPE_PAYMENT_LINK = "https://jl76z192i0.execute-api.us-east-1.amazonaws.
|
|
|
10683
11278
|
__webpack_require__.r(__webpack_exports__);
|
|
10684
11279
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
10685
11280
|
/* harmony export */ getOperatingSystem: () => (/* binding */ getOperatingSystem),
|
|
10686
|
-
/* harmony export */ isChromeBasedBrowser: () => (/* binding */ isChromeBasedBrowser)
|
|
11281
|
+
/* harmony export */ isChromeBasedBrowser: () => (/* binding */ isChromeBasedBrowser),
|
|
11282
|
+
/* harmony export */ isElectronBasedFrontend: () => (/* binding */ isElectronBasedFrontend)
|
|
10687
11283
|
/* harmony export */ });
|
|
10688
11284
|
/*
|
|
10689
11285
|
* Copyright (c) Saga Inc.
|
|
@@ -10700,6 +11296,14 @@ const getOperatingSystem = () => {
|
|
|
10700
11296
|
const isChromeBasedBrowser = () => {
|
|
10701
11297
|
return /chrome/i.test(navigator.userAgent) && !/edge|edg/i.test(navigator.userAgent);
|
|
10702
11298
|
};
|
|
11299
|
+
const isElectronBasedFrontend = () => {
|
|
11300
|
+
/*
|
|
11301
|
+
Checks if the user is using an Electron-based browser.
|
|
11302
|
+
This tells us that they are using Mito Desktop or JupyterLab Desktop.
|
|
11303
|
+
*/
|
|
11304
|
+
const userAgent = navigator.userAgent.toLowerCase();
|
|
11305
|
+
return userAgent.includes('electron');
|
|
11306
|
+
};
|
|
10703
11307
|
|
|
10704
11308
|
|
|
10705
11309
|
/***/ }),
|
|
@@ -11272,15 +11876,15 @@ class BaseWebsocketClient {
|
|
|
11272
11876
|
|
|
11273
11877
|
/***/ }),
|
|
11274
11878
|
|
|
11275
|
-
/***/ "./lib/websockets/
|
|
11276
|
-
|
|
11277
|
-
!*** ./lib/websockets/
|
|
11278
|
-
|
|
11879
|
+
/***/ "./lib/websockets/appDeploy/appDeployWebsocketClient.js":
|
|
11880
|
+
/*!**************************************************************!*\
|
|
11881
|
+
!*** ./lib/websockets/appDeploy/appDeployWebsocketClient.js ***!
|
|
11882
|
+
\**************************************************************/
|
|
11279
11883
|
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
11280
11884
|
|
|
11281
11885
|
__webpack_require__.r(__webpack_exports__);
|
|
11282
11886
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
11283
|
-
/* harmony export */
|
|
11887
|
+
/* harmony export */ AppDeployWebsocketClient: () => (/* binding */ AppDeployWebsocketClient)
|
|
11284
11888
|
/* harmony export */ });
|
|
11285
11889
|
/* harmony import */ var _BaseWebsocketClient__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../BaseWebsocketClient */ "./lib/websockets/BaseWebsocketClient.js");
|
|
11286
11890
|
/*
|
|
@@ -11293,7 +11897,7 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
11293
11897
|
*
|
|
11294
11898
|
* It communicates with the backend over a WebSocket for app building functionality.
|
|
11295
11899
|
*/
|
|
11296
|
-
class
|
|
11900
|
+
class AppDeployWebsocketClient extends _BaseWebsocketClient__WEBPACK_IMPORTED_MODULE_0__.BaseWebsocketClient {
|
|
11297
11901
|
/**
|
|
11298
11902
|
* Create a new app builder client.
|
|
11299
11903
|
*/
|
|
@@ -11302,7 +11906,7 @@ class AppBuilderWebsocketClient extends _BaseWebsocketClient__WEBPACK_IMPORTED_M
|
|
|
11302
11906
|
/**
|
|
11303
11907
|
* The service URL for the websocket endpoint.
|
|
11304
11908
|
*/
|
|
11305
|
-
this.SERVICE_URL = 'mito-ai/app-
|
|
11909
|
+
this.SERVICE_URL = 'mito-ai/app-deploy';
|
|
11306
11910
|
}
|
|
11307
11911
|
/**
|
|
11308
11912
|
* App builder messages stream.
|
|
@@ -11467,11 +12071,13 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
11467
12071
|
/* harmony export */ CompletionWebsocketClient: () => (/* binding */ CompletionWebsocketClient)
|
|
11468
12072
|
/* harmony export */ });
|
|
11469
12073
|
/* harmony import */ var _BaseWebsocketClient__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../BaseWebsocketClient */ "./lib/websockets/BaseWebsocketClient.js");
|
|
12074
|
+
/* harmony import */ var _utils_user__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../utils/user */ "./lib/utils/user.js");
|
|
11470
12075
|
/*
|
|
11471
12076
|
* Copyright (c) Saga Inc.
|
|
11472
12077
|
* Distributed under the terms of the GNU Affero General Public License v3.0 License.
|
|
11473
12078
|
*/
|
|
11474
12079
|
|
|
12080
|
+
|
|
11475
12081
|
/**
|
|
11476
12082
|
* Mito AI completion client
|
|
11477
12083
|
*
|
|
@@ -11487,6 +12093,7 @@ class CompletionWebsocketClient extends _BaseWebsocketClient__WEBPACK_IMPORTED_M
|
|
|
11487
12093
|
* The service URL for the websocket endpoint.
|
|
11488
12094
|
*/
|
|
11489
12095
|
this.SERVICE_URL = 'mito-ai/completions';
|
|
12096
|
+
this.isElectron = (0,_utils_user__WEBPACK_IMPORTED_MODULE_1__.isElectronBasedFrontend)();
|
|
11490
12097
|
}
|
|
11491
12098
|
/**
|
|
11492
12099
|
* Completion chunk stream.
|
|
@@ -11558,6 +12165,17 @@ class CompletionWebsocketClient extends _BaseWebsocketClient__WEBPACK_IMPORTED_M
|
|
|
11558
12165
|
// default: /* no-op */
|
|
11559
12166
|
}
|
|
11560
12167
|
}
|
|
12168
|
+
// Override sendMessage to automatically add environment info
|
|
12169
|
+
sendMessage(message) {
|
|
12170
|
+
// Add environment info to all messages
|
|
12171
|
+
const messageWithEnvironment = {
|
|
12172
|
+
...message,
|
|
12173
|
+
environment: {
|
|
12174
|
+
isElectron: this.isElectron,
|
|
12175
|
+
}
|
|
12176
|
+
};
|
|
12177
|
+
return super.sendMessage(messageWithEnvironment);
|
|
12178
|
+
}
|
|
11561
12179
|
}
|
|
11562
12180
|
|
|
11563
12181
|
|
|
@@ -12758,6 +13376,8 @@ ___CSS_LOADER_EXPORT___.push([module.id, `/*
|
|
|
12758
13376
|
margin: 0;
|
|
12759
13377
|
width: 100%;
|
|
12760
13378
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
|
|
13379
|
+
overflow-y: auto;
|
|
13380
|
+
max-height: 350px;
|
|
12761
13381
|
}
|
|
12762
13382
|
|
|
12763
13383
|
.chat-dropdown-item {
|
|
@@ -12842,7 +13462,7 @@ ___CSS_LOADER_EXPORT___.push([module.id, `/*
|
|
|
12842
13462
|
.chat-dropdown-search-input::placeholder {
|
|
12843
13463
|
color: var(--jp-content-font-color3);
|
|
12844
13464
|
}
|
|
12845
|
-
`, "",{"version":3,"sources":["webpack://./style/ChatDropdown.css"],"names":[],"mappings":"AAAA;;;EAGE;;AAEF;EACE,4CAA4C;EAC5C,kBAAkB;EAClB,aAAa;EACb,YAAY;EACZ,kBAAkB;;EAElB,uBAAuB;EACvB,aAAa;EACb,sBAAsB;EACtB,WAAW;EACX,yCAAyC;EACzC,kBAAkB;AACpB;;AAEA;EACE,kBAAkB;EAClB,WAAW;EACX,kBAAkB;EAClB,yCAAyC;EACzC,qBAAqB;EACrB,UAAU;EACV,SAAS;EACT,WAAW;EACX,wCAAwC;
|
|
13465
|
+
`, "",{"version":3,"sources":["webpack://./style/ChatDropdown.css"],"names":[],"mappings":"AAAA;;;EAGE;;AAEF;EACE,4CAA4C;EAC5C,kBAAkB;EAClB,aAAa;EACb,YAAY;EACZ,kBAAkB;;EAElB,uBAAuB;EACvB,aAAa;EACb,sBAAsB;EACtB,WAAW;EACX,yCAAyC;EACzC,kBAAkB;AACpB;;AAEA;EACE,kBAAkB;EAClB,WAAW;EACX,kBAAkB;EAClB,yCAAyC;EACzC,qBAAqB;EACrB,UAAU;EACV,SAAS;EACT,WAAW;EACX,wCAAwC;EACxC,gBAAgB;EAChB,iBAAiB;AACnB;;AAEA;EACE,YAAY;EACZ,eAAe;EACf,aAAa;EACb,mBAAmB;EACnB,QAAQ;EACR,oCAAoC;EACpC,gBAAgB;EAChB,uBAAuB;EACvB,mBAAmB;AACrB;;AAEA;;EAEE,yCAAyC;AAC3C;;AAEA;EACE,6BAA6B;EAC7B,uCAAuC;EACvC,eAAe;EACf,WAAW;EACX,mBAAmB;EACnB,gBAAgB;EAChB,uBAAuB;AACzB;;AAEA;EACE,eAAe;EACf,aAAa;EACb,mBAAmB;EACnB,mBAAmB;EACnB,gBAAgB;EAChB,uBAAuB;AACzB;;AAEA;EACE,8BAA8B;EAC9B,eAAe;EACf,gBAAgB;EAChB,mBAAmB;EACnB,gBAAgB;EAChB,uBAAuB;AACzB;;AAEA;EACE,YAAY;EACZ,mBAAmB;AACrB;;AAEA;EACE,yBAAyB;AAC3B;;AAEA;EACE,YAAY;EACZ,yCAAyC;EACzC,2BAA2B;EAC3B,4BAA4B;AAC9B;;AAEA;EACE,WAAW;EACX,gBAAgB;EAChB,kBAAkB;EAClB,eAAe;EACf,qCAAqC;EACrC,yCAAyC;EACzC,oCAAoC;EACpC,aAAa;EACb,YAAY;EACZ,sBAAsB;AACxB;;AAEA;EACE,aAAa;EACb,YAAY;AACd;;AAEA;EACE,oCAAoC;AACtC","sourcesContent":["/*\n * Copyright (c) Saga Inc.\n * Distributed under the terms of the GNU Affero General Public License v3.0 License.\n */\n\n.chat-dropdown {\n /* Position the dropdown in the right place*/\n position: absolute;\n z-index: 9999;\n bottom: 100%;\n margin-bottom: 5px;\n\n /* Style the dropdown */\n display: flex;\n flex-direction: column;\n width: 100%;\n border: 1px solid var(--jp-border-color1);\n border-radius: 5px;\n}\n\n.chat-dropdown-list {\n position: relative;\n border: 0px;\n border-radius: 5px;\n background-color: var(--jp-layout-color1);\n list-style-type: none;\n padding: 0;\n margin: 0;\n width: 100%;\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);\n overflow-y: auto;\n max-height: 350px;\n}\n\n.chat-dropdown-item {\n padding: 8px;\n cursor: pointer;\n display: flex;\n align-items: center;\n gap: 8px;\n color: var(--jp-content-font-color1);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.chat-dropdown-item:hover,\n.chat-dropdown-item.selected {\n background-color: var(--jp-layout-color3);\n}\n\n.chat-dropdown-item-type {\n color: var(--jp-brand-color1);\n font-family: var(--jp-code-font-family);\n min-width: 35px;\n width: 35px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.chat-dropdown-item-name {\n font-size: 15px;\n display: flex;\n align-items: center;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.chat-dropdown-item-parent-df {\n color: var(--muted-text-color);\n font-size: 12px;\n margin-left: 4px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.dropdown-item-disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.dropdown-item-disabled:hover {\n background-color: inherit;\n}\n\n.chat-dropdown-search {\n padding: 8px;\n background-color: var(--jp-layout-color1);\n border-top-left-radius: 5px;\n border-top-right-radius: 5px;\n}\n\n.chat-dropdown-search-input {\n width: 100%;\n padding: 6px 8px;\n border-radius: 3px;\n font-size: 12px;\n font-family: var(--jp-ui-font-family);\n background-color: var(--jp-layout-color1);\n color: var(--jp-content-font-color1);\n outline: none;\n border: none;\n box-sizing: border-box;\n}\n\n.chat-dropdown-search-input:focus {\n outline: none;\n border: none;\n}\n\n.chat-dropdown-search-input::placeholder {\n color: var(--jp-content-font-color3);\n}\n"],"sourceRoot":""}]);
|
|
12846
13466
|
// Exports
|
|
12847
13467
|
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);
|
|
12848
13468
|
|
|
@@ -12888,6 +13508,10 @@ ___CSS_LOADER_EXPORT___.push([module.id, `/*
|
|
|
12888
13508
|
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
|
12889
13509
|
}
|
|
12890
13510
|
|
|
13511
|
+
.chat-input-container.editing {
|
|
13512
|
+
margin-top: 0;
|
|
13513
|
+
}
|
|
13514
|
+
|
|
12891
13515
|
.chat-input-text-area-container {
|
|
12892
13516
|
position: relative;
|
|
12893
13517
|
height: min-content;
|
|
@@ -12899,7 +13523,7 @@ ___CSS_LOADER_EXPORT___.push([module.id, `/*
|
|
|
12899
13523
|
resize: none;
|
|
12900
13524
|
width: 100%;
|
|
12901
13525
|
padding: 10px;
|
|
12902
|
-
overflow-y:
|
|
13526
|
+
overflow-y: auto;
|
|
12903
13527
|
box-sizing: border-box;
|
|
12904
13528
|
flex-shrink: 0 !important;
|
|
12905
13529
|
background-color: var(--chat-user-message-background-color);
|
|
@@ -12968,7 +13592,7 @@ ___CSS_LOADER_EXPORT___.push([module.id, `/*
|
|
|
12968
13592
|
|
|
12969
13593
|
.context-button:disabled:hover {
|
|
12970
13594
|
background-color: var(--jp-layout-color2);
|
|
12971
|
-
}`, "",{"version":3,"sources":["webpack://./style/ChatInput.css"],"names":[],"mappings":"AAAA;;;EAGE;;AAEF;EACE,gBAAgB;EAChB,SAAS;EACT,cAAc;EACd,gBAAgB;EAChB,2DAA2D;EAC3D;;;iCAG+B;EAC/B,WAAW;EACX,mBAAmB;EACnB,iDAAiD;AACnD;;AAEA;EACE,kBAAkB;EAClB,mBAAmB;AACrB;;AAEA;EACE,aAAa;EACb,YAAY;EACZ,YAAY;EACZ,WAAW;EACX,aAAa;EACb,
|
|
13595
|
+
}`, "",{"version":3,"sources":["webpack://./style/ChatInput.css"],"names":[],"mappings":"AAAA;;;EAGE;;AAEF;EACE,gBAAgB;EAChB,SAAS;EACT,cAAc;EACd,gBAAgB;EAChB,2DAA2D;EAC3D;;;iCAG+B;EAC/B,WAAW;EACX,mBAAmB;EACnB,iDAAiD;AACnD;;AAEA;EACE,aAAa;AACf;;AAEA;EACE,kBAAkB;EAClB,mBAAmB;AACrB;;AAEA;EACE,aAAa;EACb,YAAY;EACZ,YAAY;EACZ,WAAW;EACX,aAAa;EACb,gBAAgB;EAChB,sBAAsB;EACtB,yBAAyB;EACzB,2DAA2D;EAC3D,eAAe;EACf,gBAAgB;EAChB,qCAAqC;EACrC,gBAAgB;EAChB,iDAAiD;AACnD;;AAEA;EACE,aAAa;AACf;;AAEA;EACE,2BAA2B;EAC3B;;;iCAG+B;AACjC;;AAEA;EACE,+BAA+B;AACjC;;AAEA;EACE,+BAA+B;EAC/B,2BAA2B;AAC7B;;AAEA;EACE,+BAA+B;AACjC;;AAEA;EACE,aAAa;EACb,mBAAmB;EACnB,yCAAyC;EACzC,yCAAyC;EACzC,kBAAkB;EAClB,gBAAgB;EAChB,eAAe;EACf,yCAAyC;EACzC,eAAe;EACf,oCAAoC;EACpC,sCAAsC;AACxC;;AAEA;EACE,yCAAyC;AAC3C;;AAEA,0BAA0B;AAC1B;EACE,YAAY;EACZ,mBAAmB;EACnB,yCAAyC;AAC3C;;AAEA;EACE,YAAY;EACZ,mBAAmB;EACnB,yCAAyC;AAC3C;;AAEA;EACE,yCAAyC;AAC3C","sourcesContent":["/*\n * Copyright (c) Saga Inc.\n * Distributed under the terms of the GNU Affero General Public License v3.0 License.\n */\n\n.chat-input-container {\n position: sticky;\n bottom: 0;\n margin: 10px 0;\n margin-top: auto;\n background-color: var(--chat-user-message-background-color);\n box-shadow: \n 0 4px 12px rgba(0, 0, 0, 0.08),\n 0 2px 4px rgba(0, 0, 0, 0.06),\n 0 0 0 1px rgba(0, 0, 0, 0.02);\n width: 100%;\n border-radius: 12px;\n transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.chat-input-container.editing {\n margin-top: 0;\n}\n\n.chat-input-text-area-container {\n position: relative;\n height: min-content;\n}\n\n.chat-input {\n outline: none;\n border: none;\n resize: none;\n width: 100%;\n padding: 10px;\n overflow-y: auto;\n box-sizing: border-box;\n flex-shrink: 0 !important;\n background-color: var(--chat-user-message-background-color);\n font-size: 12px;\n font-weight: 400;\n font-family: var(--jp-ui-font-family);\n line-height: 1.2;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.active-cell-preview-container {\n padding: 10px;\n}\n\n.chat-input-container:focus-within {\n transform: translateY(-1px);\n box-shadow: \n 0 2px 8px rgba(0, 0, 0, 0.12),\n 0 8px 16px rgba(0, 0, 0, 0.08),\n 0 0 0 1px rgba(0, 0, 0, 0.04);\n}\n\n.chat-input:focus {\n color: var(--jp-ui-font-color1);\n}\n\n.chat-input::placeholder {\n color: var(--jp-ui-font-color2);\n transition: color 0.2s ease;\n}\n\n.chat-input:focus::placeholder {\n color: var(--jp-ui-font-color3);\n}\n\n.context-button {\n display: flex;\n align-items: center;\n background-color: var(--jp-layout-color2);\n border: 1px solid var(--jp-border-color1);\n border-radius: 3px;\n padding: 4px 8px;\n font-size: 12px;\n height: var(--chat-context-button-height);\n cursor: pointer;\n color: var(--jp-content-font-color1);\n transition: background-color 0.2s ease;\n}\n\n.context-button:hover {\n background-color: var(--jp-layout-color3);\n}\n\n/* Disabled state styles */\n.chat-input:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n background-color: var(--jp-layout-color2);\n}\n\n.context-button:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n background-color: var(--jp-layout-color2);\n}\n\n.context-button:disabled:hover {\n background-color: var(--jp-layout-color2);\n}"],"sourceRoot":""}]);
|
|
12972
13596
|
// Exports
|
|
12973
13597
|
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);
|
|
12974
13598
|
|
|
@@ -14241,6 +14865,142 @@ ___CSS_LOADER_EXPORT___.push([module.id, `/*
|
|
|
14241
14865
|
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);
|
|
14242
14866
|
|
|
14243
14867
|
|
|
14868
|
+
/***/ }),
|
|
14869
|
+
|
|
14870
|
+
/***/ "./node_modules/css-loader/dist/cjs.js!./style/FilesSelector.css":
|
|
14871
|
+
/*!***********************************************************************!*\
|
|
14872
|
+
!*** ./node_modules/css-loader/dist/cjs.js!./style/FilesSelector.css ***!
|
|
14873
|
+
\***********************************************************************/
|
|
14874
|
+
/***/ ((module, __webpack_exports__, __webpack_require__) => {
|
|
14875
|
+
|
|
14876
|
+
__webpack_require__.r(__webpack_exports__);
|
|
14877
|
+
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
14878
|
+
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
|
|
14879
|
+
/* harmony export */ });
|
|
14880
|
+
/* harmony import */ var _node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../node_modules/css-loader/dist/runtime/sourceMaps.js */ "./node_modules/css-loader/dist/runtime/sourceMaps.js");
|
|
14881
|
+
/* harmony import */ var _node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__);
|
|
14882
|
+
/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../node_modules/css-loader/dist/runtime/api.js */ "./node_modules/css-loader/dist/runtime/api.js");
|
|
14883
|
+
/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__);
|
|
14884
|
+
// Imports
|
|
14885
|
+
|
|
14886
|
+
|
|
14887
|
+
var ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default()));
|
|
14888
|
+
// Module
|
|
14889
|
+
___CSS_LOADER_EXPORT___.push([module.id, `/*
|
|
14890
|
+
* Copyright (c) Saga Inc.
|
|
14891
|
+
* Distributed under the terms of the GNU Affero General Public License v3.0 License.
|
|
14892
|
+
*/
|
|
14893
|
+
|
|
14894
|
+
|
|
14895
|
+
.file-list {
|
|
14896
|
+
list-style: none;
|
|
14897
|
+
padding-left: 0;
|
|
14898
|
+
margin: 0;
|
|
14899
|
+
}
|
|
14900
|
+
|
|
14901
|
+
.file-list li {
|
|
14902
|
+
margin-bottom: 6px;
|
|
14903
|
+
}
|
|
14904
|
+
|
|
14905
|
+
.modal-footer {
|
|
14906
|
+
margin-top: 16px;
|
|
14907
|
+
display: flex;
|
|
14908
|
+
justify-content: flex-end;
|
|
14909
|
+
}
|
|
14910
|
+
|
|
14911
|
+
.files-selector-submit-button {
|
|
14912
|
+
margin-top: 8px;
|
|
14913
|
+
background-color: var(--purple-400) !important;
|
|
14914
|
+
color: var(--purple-700) !important;
|
|
14915
|
+
border: none !important;
|
|
14916
|
+
border-radius: 4px !important;
|
|
14917
|
+
font-weight: 500 !important;
|
|
14918
|
+
padding: 8px 16px !important;
|
|
14919
|
+
width: 100% !important;
|
|
14920
|
+
max-width: 100% !important;
|
|
14921
|
+
box-sizing: border-box !important;
|
|
14922
|
+
}
|
|
14923
|
+
|
|
14924
|
+
.files-selector-submit-button:hover {
|
|
14925
|
+
background-color: var(--purple-500) !important;
|
|
14926
|
+
}
|
|
14927
|
+
|
|
14928
|
+
.file-list input[type="checkbox"],
|
|
14929
|
+
.select-all input[type="checkbox"]{
|
|
14930
|
+
transform: scale(1.3);
|
|
14931
|
+
margin-right: 6px;
|
|
14932
|
+
accent-color: var(--purple-500);
|
|
14933
|
+
}
|
|
14934
|
+
|
|
14935
|
+
.file-list svg {
|
|
14936
|
+
color: grey;
|
|
14937
|
+
margin-right: 4px;
|
|
14938
|
+
vertical-align: middle;
|
|
14939
|
+
}
|
|
14940
|
+
|
|
14941
|
+
.select-all label {
|
|
14942
|
+
font-weight: 500;
|
|
14943
|
+
display: flex;
|
|
14944
|
+
align-items: center;
|
|
14945
|
+
gap: 6px;
|
|
14946
|
+
}
|
|
14947
|
+
|
|
14948
|
+
/* Modal header */
|
|
14949
|
+
.modal-header {
|
|
14950
|
+
display: flex;
|
|
14951
|
+
align-items: center;
|
|
14952
|
+
justify-content: space-between;
|
|
14953
|
+
gap: 8px;
|
|
14954
|
+
margin-bottom: 1px;
|
|
14955
|
+
}
|
|
14956
|
+
|
|
14957
|
+
.modal-title {
|
|
14958
|
+
margin: 0;
|
|
14959
|
+
font-size: 1.2rem;
|
|
14960
|
+
}
|
|
14961
|
+
|
|
14962
|
+
|
|
14963
|
+
.modal-subtext {
|
|
14964
|
+
font-size: 0.7rem;
|
|
14965
|
+
color: #555;
|
|
14966
|
+
margin: 0;
|
|
14967
|
+
font-style: italic;
|
|
14968
|
+
}
|
|
14969
|
+
|
|
14970
|
+
.modal-subheader{
|
|
14971
|
+
margin-bottom: 7px;
|
|
14972
|
+
}
|
|
14973
|
+
|
|
14974
|
+
/* Checkbox label for spacing */
|
|
14975
|
+
.checkbox-label {
|
|
14976
|
+
display: flex;
|
|
14977
|
+
align-items: center;
|
|
14978
|
+
gap: 6px;
|
|
14979
|
+
}
|
|
14980
|
+
|
|
14981
|
+
/* Scrollable file list */
|
|
14982
|
+
.file-list-scrollable {
|
|
14983
|
+
max-height: 300px;
|
|
14984
|
+
overflow-y: auto;
|
|
14985
|
+
margin-top: 8px;
|
|
14986
|
+
}
|
|
14987
|
+
|
|
14988
|
+
/* File list items */
|
|
14989
|
+
.file-list {
|
|
14990
|
+
list-style: none;
|
|
14991
|
+
padding-left: 0;
|
|
14992
|
+
margin: 0;
|
|
14993
|
+
}
|
|
14994
|
+
|
|
14995
|
+
/* Select all section */
|
|
14996
|
+
.files-selector-select-all {
|
|
14997
|
+
margin-bottom: 8px;
|
|
14998
|
+
}
|
|
14999
|
+
`, "",{"version":3,"sources":["webpack://./style/FilesSelector.css"],"names":[],"mappings":"AAAA;;;EAGE;;;AAGF;EACE,gBAAgB;EAChB,eAAe;EACf,SAAS;AACX;;AAEA;EACE,kBAAkB;AACpB;;AAEA;EACE,gBAAgB;EAChB,aAAa;EACb,yBAAyB;AAC3B;;AAEA;EACE,eAAe;EACf,8CAA8C;EAC9C,mCAAmC;EACnC,uBAAuB;EACvB,6BAA6B;EAC7B,2BAA2B;EAC3B,4BAA4B;EAC5B,sBAAsB;EACtB,0BAA0B;EAC1B,iCAAiC;AACnC;;AAEA;EACE,8CAA8C;AAChD;;AAEA;;EAEE,qBAAqB;EACrB,iBAAiB;EACjB,+BAA+B;AACjC;;AAEA;EACE,WAAW;EACX,iBAAiB;EACjB,sBAAsB;AACxB;;AAEA;EACE,gBAAgB;EAChB,aAAa;EACb,mBAAmB;EACnB,QAAQ;AACV;;AAEA,iBAAiB;AACjB;EACE,aAAa;EACb,mBAAmB;EACnB,8BAA8B;EAC9B,QAAQ;EACR,kBAAkB;AACpB;;AAEA;EACE,SAAS;EACT,iBAAiB;AACnB;;;AAGA;EACE,iBAAiB;EACjB,WAAW;EACX,SAAS;EACT,kBAAkB;AACpB;;AAEA;EACE,kBAAkB;AACpB;;AAEA,+BAA+B;AAC/B;EACE,aAAa;EACb,mBAAmB;EACnB,QAAQ;AACV;;AAEA,yBAAyB;AACzB;EACE,iBAAiB;EACjB,gBAAgB;EAChB,eAAe;AACjB;;AAEA,oBAAoB;AACpB;EACE,gBAAgB;EAChB,eAAe;EACf,SAAS;AACX;;AAEA,uBAAuB;AACvB;EACE,kBAAkB;AACpB","sourcesContent":["/*\n * Copyright (c) Saga Inc.\n * Distributed under the terms of the GNU Affero General Public License v3.0 License.\n */\n\n\n.file-list {\n list-style: none;\n padding-left: 0;\n margin: 0;\n}\n\n.file-list li {\n margin-bottom: 6px;\n}\n\n.modal-footer {\n margin-top: 16px;\n display: flex;\n justify-content: flex-end;\n}\n\n.files-selector-submit-button {\n margin-top: 8px;\n background-color: var(--purple-400) !important;\n color: var(--purple-700) !important;\n border: none !important;\n border-radius: 4px !important;\n font-weight: 500 !important;\n padding: 8px 16px !important;\n width: 100% !important;\n max-width: 100% !important;\n box-sizing: border-box !important;\n}\n\n.files-selector-submit-button:hover {\n background-color: var(--purple-500) !important;\n}\n\n.file-list input[type=\"checkbox\"],\n.select-all input[type=\"checkbox\"]{\n transform: scale(1.3);\n margin-right: 6px;\n accent-color: var(--purple-500);\n}\n\n.file-list svg {\n color: grey;\n margin-right: 4px;\n vertical-align: middle;\n}\n\n.select-all label {\n font-weight: 500;\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n/* Modal header */\n.modal-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n margin-bottom: 1px;\n}\n\n.modal-title {\n margin: 0;\n font-size: 1.2rem;\n}\n\n\n.modal-subtext {\n font-size: 0.7rem;\n color: #555;\n margin: 0;\n font-style: italic;\n}\n\n.modal-subheader{\n margin-bottom: 7px;\n}\n\n/* Checkbox label for spacing */\n.checkbox-label {\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n/* Scrollable file list */\n.file-list-scrollable {\n max-height: 300px;\n overflow-y: auto;\n margin-top: 8px;\n}\n\n/* File list items */\n.file-list {\n list-style: none;\n padding-left: 0;\n margin: 0;\n}\n\n/* Select all section */\n.files-selector-select-all {\n margin-bottom: 8px;\n}\n"],"sourceRoot":""}]);
|
|
15000
|
+
// Exports
|
|
15001
|
+
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);
|
|
15002
|
+
|
|
15003
|
+
|
|
14244
15004
|
/***/ }),
|
|
14245
15005
|
|
|
14246
15006
|
/***/ "./node_modules/css-loader/dist/cjs.js!./style/IconButton.css":
|
|
@@ -15460,6 +16220,7 @@ ___CSS_LOADER_EXPORT___.push([module.id, `/*
|
|
|
15460
16220
|
align-items: center;
|
|
15461
16221
|
gap: 4px;
|
|
15462
16222
|
padding: 8px 10px;
|
|
16223
|
+
overflow-x: hidden;
|
|
15463
16224
|
}
|
|
15464
16225
|
|
|
15465
16226
|
/* Consistent spacing for all children of context container */
|
|
@@ -15478,14 +16239,15 @@ ___CSS_LOADER_EXPORT___.push([module.id, `/*
|
|
|
15478
16239
|
|
|
15479
16240
|
font-size: 12px;
|
|
15480
16241
|
height: 20px;
|
|
15481
|
-
width:
|
|
16242
|
+
max-width: 100%;
|
|
16243
|
+
min-width: 0;
|
|
15482
16244
|
|
|
15483
16245
|
border: 1px solid var(--jp-border-color1);
|
|
15484
16246
|
cursor: pointer;
|
|
16247
|
+
}
|
|
15485
16248
|
|
|
15486
|
-
|
|
15487
|
-
|
|
15488
|
-
}
|
|
16249
|
+
.selected-context-container:hover {
|
|
16250
|
+
background-color: var(--jp-layout-color3);
|
|
15489
16251
|
}
|
|
15490
16252
|
|
|
15491
16253
|
.selected-context-container .rule-name {
|
|
@@ -15504,7 +16266,7 @@ ___CSS_LOADER_EXPORT___.push([module.id, `/*
|
|
|
15504
16266
|
width: 12px;
|
|
15505
16267
|
max-height: 14px;
|
|
15506
16268
|
color: var(--jp-content-font-color3);
|
|
15507
|
-
}`, "",{"version":3,"sources":["webpack://./style/SelectedContextContainer.css"],"names":[],"mappings":"AAAA;;;EAGE;;AAEF;EACE,aAAa;EACb,eAAe;EACf,mBAAmB;EACnB,QAAQ;EACR,iBAAiB;
|
|
16269
|
+
}`, "",{"version":3,"sources":["webpack://./style/SelectedContextContainer.css"],"names":[],"mappings":"AAAA;;;EAGE;;AAEF;EACE,aAAa;EACb,eAAe;EACf,mBAAmB;EACnB,QAAQ;EACR,iBAAiB;EACjB,kBAAkB;AACpB;;AAEA,6DAA6D;AAC7D;EACE,WAAW;AACb;;AAEA;EACE,aAAa;EACb,mBAAmB;EACnB,kBAAkB;EAClB,yCAAyC;EACzC,kBAAkB;EAClB,gBAAgB;EAChB,WAAW;;EAEX,eAAe;EACf,YAAY;EACZ,eAAe;EACf,YAAY;;EAEZ,yCAAyC;EACzC,eAAe;AACjB;;AAEA;EACE,yCAAyC;AAC3C;;AAEA;EACE,gBAAgB;EAChB,oCAAoC;EACpC,mBAAmB;EACnB,gBAAgB;EAChB,uBAAuB;EACvB,gBAAgB;AAClB;;AAEA;EACE,aAAa;EACb,sBAAsB;EACtB,uBAAuB;EACvB,WAAW;EACX,gBAAgB;EAChB,oCAAoC;AACtC","sourcesContent":["/*\n * Copyright (c) Saga Inc.\n * Distributed under the terms of the GNU Affero General Public License v3.0 License.\n */\n\n.context-container {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 4px;\n padding: 8px 10px;\n overflow-x: hidden;\n}\n\n/* Consistent spacing for all children of context container */\n.context-container>* {\n margin: 2px;\n}\n\n.selected-context-container {\n display: flex;\n align-items: center;\n text-align: center;\n background-color: var(--jp-layout-color2);\n border-radius: 3px;\n padding: 4px 8px;\n margin: 2px;\n\n font-size: 12px;\n height: 20px;\n max-width: 100%;\n min-width: 0;\n\n border: 1px solid var(--jp-border-color1);\n cursor: pointer;\n}\n\n.selected-context-container:hover {\n background-color: var(--jp-layout-color3);\n}\n\n.selected-context-container .rule-name {\n margin-left: 6px;\n color: var(--jp-content-font-color1);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n max-width: 200px;\n}\n\n.selected-context-container .icon {\n display: flex;\n flex-direction: column;\n justify-content: center;\n width: 12px;\n max-height: 14px;\n color: var(--jp-content-font-color3);\n}"],"sourceRoot":""}]);
|
|
15508
16270
|
// Exports
|
|
15509
16271
|
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);
|
|
15510
16272
|
|
|
@@ -15627,6 +16389,65 @@ a {
|
|
|
15627
16389
|
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);
|
|
15628
16390
|
|
|
15629
16391
|
|
|
16392
|
+
/***/ }),
|
|
16393
|
+
|
|
16394
|
+
/***/ "./node_modules/css-loader/dist/cjs.js!./style/StreamlitPreviewPlugin.css":
|
|
16395
|
+
/*!********************************************************************************!*\
|
|
16396
|
+
!*** ./node_modules/css-loader/dist/cjs.js!./style/StreamlitPreviewPlugin.css ***!
|
|
16397
|
+
\********************************************************************************/
|
|
16398
|
+
/***/ ((module, __webpack_exports__, __webpack_require__) => {
|
|
16399
|
+
|
|
16400
|
+
__webpack_require__.r(__webpack_exports__);
|
|
16401
|
+
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
16402
|
+
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
|
|
16403
|
+
/* harmony export */ });
|
|
16404
|
+
/* harmony import */ var _node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../node_modules/css-loader/dist/runtime/sourceMaps.js */ "./node_modules/css-loader/dist/runtime/sourceMaps.js");
|
|
16405
|
+
/* harmony import */ var _node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__);
|
|
16406
|
+
/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../node_modules/css-loader/dist/runtime/api.js */ "./node_modules/css-loader/dist/runtime/api.js");
|
|
16407
|
+
/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__);
|
|
16408
|
+
// Imports
|
|
16409
|
+
|
|
16410
|
+
|
|
16411
|
+
var ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default()));
|
|
16412
|
+
// Module
|
|
16413
|
+
___CSS_LOADER_EXPORT___.push([module.id, `/*
|
|
16414
|
+
* Copyright (c) Saga Inc.
|
|
16415
|
+
* Distributed under the terms of the GNU Affero General Public License v3.0 License.
|
|
16416
|
+
*/
|
|
16417
|
+
|
|
16418
|
+
.mito-deploy-button {
|
|
16419
|
+
display: flex !important;
|
|
16420
|
+
align-items: center !important;
|
|
16421
|
+
gap: 6px !important;
|
|
16422
|
+
padding: 4px 8px !important;
|
|
16423
|
+
color: var(--jp-ui-font-color1) !important;
|
|
16424
|
+
background-color: var(--jp-layout-color2) !important;
|
|
16425
|
+
}
|
|
16426
|
+
|
|
16427
|
+
.mito-deploy-button:hover {
|
|
16428
|
+
background-color: var(--jp-layout-color3) !important;
|
|
16429
|
+
}
|
|
16430
|
+
|
|
16431
|
+
.mito-deploy-button .mito-ai-deploy-icon {
|
|
16432
|
+
display: flex !important;
|
|
16433
|
+
align-items: center !important;
|
|
16434
|
+
height: 10px !important;
|
|
16435
|
+
width: 10px !important;
|
|
16436
|
+
font-size: 12px !important;
|
|
16437
|
+
}
|
|
16438
|
+
|
|
16439
|
+
.mito-deploy-button::slotted(svg),
|
|
16440
|
+
.mito-deploy-button svg {
|
|
16441
|
+
width: 12px !important;
|
|
16442
|
+
height: 12px !important;
|
|
16443
|
+
max-width: 12px !important;
|
|
16444
|
+
max-height: 12px !important;
|
|
16445
|
+
margin-right: 4px !important;
|
|
16446
|
+
}`, "",{"version":3,"sources":["webpack://./style/StreamlitPreviewPlugin.css"],"names":[],"mappings":"AAAA;;;EAGE;;AAEF;IACI,wBAAwB;IACxB,8BAA8B;IAC9B,mBAAmB;IACnB,2BAA2B;IAC3B,0CAA0C;IAC1C,oDAAoD;AACxD;;AAEA;IACI,oDAAoD;AACxD;;AAEA;IACI,wBAAwB;IACxB,8BAA8B;IAC9B,uBAAuB;IACvB,sBAAsB;IACtB,0BAA0B;AAC9B;;AAEA;;IAEI,sBAAsB;IACtB,uBAAuB;IACvB,0BAA0B;IAC1B,2BAA2B;IAC3B,4BAA4B;AAChC","sourcesContent":["/*\n * Copyright (c) Saga Inc.\n * Distributed under the terms of the GNU Affero General Public License v3.0 License.\n */\n\n.mito-deploy-button {\n display: flex !important;\n align-items: center !important;\n gap: 6px !important;\n padding: 4px 8px !important;\n color: var(--jp-ui-font-color1) !important;\n background-color: var(--jp-layout-color2) !important;\n}\n\n.mito-deploy-button:hover {\n background-color: var(--jp-layout-color3) !important;\n}\n\n.mito-deploy-button .mito-ai-deploy-icon {\n display: flex !important;\n align-items: center !important;\n height: 10px !important;\n width: 10px !important;\n font-size: 12px !important;\n}\n\n.mito-deploy-button::slotted(svg),\n.mito-deploy-button svg {\n width: 12px !important;\n height: 12px !important;\n max-width: 12px !important;\n max-height: 12px !important;\n margin-right: 4px !important;\n}"],"sourceRoot":""}]);
|
|
16447
|
+
// Exports
|
|
16448
|
+
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);
|
|
16449
|
+
|
|
16450
|
+
|
|
15630
16451
|
/***/ }),
|
|
15631
16452
|
|
|
15632
16453
|
/***/ "./node_modules/css-loader/dist/cjs.js!./style/TextAndIconButton.css":
|
|
@@ -15904,6 +16725,16 @@ ___CSS_LOADER_EXPORT___.push([module.id, `/*
|
|
|
15904
16725
|
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);
|
|
15905
16726
|
|
|
15906
16727
|
|
|
16728
|
+
/***/ }),
|
|
16729
|
+
|
|
16730
|
+
/***/ "./src/icons/App/DeployIcon.svg":
|
|
16731
|
+
/*!**************************************!*\
|
|
16732
|
+
!*** ./src/icons/App/DeployIcon.svg ***!
|
|
16733
|
+
\**************************************/
|
|
16734
|
+
/***/ ((module) => {
|
|
16735
|
+
|
|
16736
|
+
module.exports = "<svg width=\"1298\" height=\"1286\" viewBox=\"0 0 1298 1286\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <g fill=\"currentColor\">\n <path d=\"M689.8 1007.36C644.524 1028.32 598.8 1047.93 552.76 1066.2L569.733 1285.77C638.785 1254.45 799 1157.24 926.04 893.279C871.201 922.393 816.352 948.581 769.52 970.929C743.254 983.518 716.602 995.58 689.806 1007.36L689.8 1007.36Z\" />\n <path d=\"M815.76 382.387C791.224 382.387 766.698 391.626 748.02 410.084C729.994 427.923 720.056 451.62 720.056 476.824C720.056 502.021 729.983 525.725 748.029 543.564C785.379 580.501 846.166 580.491 883.496 543.564C883.496 543.554 883.507 543.554 883.507 543.554C901.533 525.715 911.48 502.018 911.48 476.814C911.48 451.616 901.542 427.912 883.507 410.073C864.84 391.615 840.304 382.385 815.761 382.385L815.76 382.387Z\" />\n <path d=\"M349.453 462.747C364.328 432.924 380.213 401.747 397.229 370.408C130.563 495.835 32.0558 654.008 0.21582 722.461L220.562 739.112C243.614 682.175 268.75 625.664 296.073 569.925C312.661 535.961 330.401 499.685 349.448 462.748L349.453 462.747Z\" />\n <path d=\"M914.027 33.9479L1263.4 379.428C1280.5 311.901 1289.8 244.215 1294.2 180.815C1294.57 175.502 1294.94 170.2 1295.24 164.841C1295.7 156.815 1296.08 148.893 1296.39 141.029C1296.74 132.003 1297.02 122.915 1297.19 113.789C1297.32 107.513 1297.42 101.3 1297.45 95.1639C1297.53 82.6117 1297.5 70.0025 1297.27 57.2892C1297.21 54.4143 1297.14 51.6017 1297.07 48.7632C1296.68 33.4872 1296.14 18.1379 1295.28 2.66453C1193.44 -3.4552 1054.16 -1.29387 914.028 33.9565L914.027 33.9479Z\" />\n <path d=\"M1106.33 687.12C1113.39 679.36 1120.28 671.423 1126.96 663.235C1127.83 662.162 1128.78 661.11 1129.65 660.021C1136.68 651.261 1143.42 642.172 1150.03 632.933C1152.32 629.735 1154.57 626.506 1156.79 623.272C1161.92 615.824 1166.89 608.209 1171.74 600.46C1174.87 595.46 1177.89 590.408 1180.87 585.345C1184.4 579.345 1187.85 573.272 1191.24 567.105C1194.19 561.694 1197.13 556.282 1199.93 550.802C1202.02 546.729 1203.99 542.542 1206.02 538.401C1211.38 527.391 1216.53 516.287 1221.32 505.079C1222.07 503.318 1222.81 501.542 1223.56 499.766C1232.09 479.354 1239.68 458.667 1246.47 437.829L855.11 50.802C755.386 82.99 670.87 130.214 602.99 191.362C601.24 192.935 599.49 194.523 597.751 196.122C588.876 204.31 580.215 212.685 571.939 221.362C569.001 224.461 566.163 227.748 563.277 230.951C497.903 303.211 443.179 397.524 396.451 488.218C386.039 509.119 376.139 529.354 366.951 548.182C330.524 622.468 297.377 699.395 268.399 776.848C266.362 782.312 262.612 786.697 257.961 789.734C237.472 842.307 218.81 895.171 202.3 948.107L340.153 1084.43C395.164 1067.65 450.101 1048.65 504.7 1027.74C507.538 1024.61 510.887 1021.9 515.075 1020.37C566.689 1001.51 618.023 980.661 668.621 958.427C678.861 953.677 689.111 948.953 699.299 944.062C828.601 882.912 975.019 813.661 1075.33 718.903C1083.84 710.892 1092.02 702.491 1100.07 693.929C1102.19 691.669 1104.26 689.393 1106.34 687.122L1106.33 687.12ZM921.187 581.344C892.114 610.104 853.911 624.48 815.723 624.48C777.535 624.48 739.348 610.105 710.275 581.355C682.051 553.443 666.515 516.328 666.515 476.828C666.515 437.328 682.067 400.213 710.264 372.301C768.426 314.791 863.038 314.812 921.171 372.291C949.411 400.203 964.947 437.318 964.947 476.818C964.947 516.307 949.406 553.432 921.182 581.344L921.187 581.344Z\" />\n <path d=\"M147.088 1138.72L198.905 982.058L302.981 1084.64L147.088 1138.72Z\" />\n </g>\n</svg>\n";
|
|
16737
|
+
|
|
15907
16738
|
/***/ }),
|
|
15908
16739
|
|
|
15909
16740
|
/***/ "./src/icons/AppBuilderExcludeCellIcon.svg":
|
|
@@ -16936,6 +17767,60 @@ var update = _node_modules_style_loader_dist_runtime_injectStylesIntoStyleTag_js
|
|
|
16936
17767
|
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (_node_modules_css_loader_dist_cjs_js_ErrorMimeRendererPlugin_css__WEBPACK_IMPORTED_MODULE_6__["default"] && _node_modules_css_loader_dist_cjs_js_ErrorMimeRendererPlugin_css__WEBPACK_IMPORTED_MODULE_6__["default"].locals ? _node_modules_css_loader_dist_cjs_js_ErrorMimeRendererPlugin_css__WEBPACK_IMPORTED_MODULE_6__["default"].locals : undefined);
|
|
16937
17768
|
|
|
16938
17769
|
|
|
17770
|
+
/***/ }),
|
|
17771
|
+
|
|
17772
|
+
/***/ "./style/FilesSelector.css":
|
|
17773
|
+
/*!*********************************!*\
|
|
17774
|
+
!*** ./style/FilesSelector.css ***!
|
|
17775
|
+
\*********************************/
|
|
17776
|
+
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
17777
|
+
|
|
17778
|
+
__webpack_require__.r(__webpack_exports__);
|
|
17779
|
+
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
17780
|
+
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
|
|
17781
|
+
/* harmony export */ });
|
|
17782
|
+
/* harmony import */ var _node_modules_style_loader_dist_runtime_injectStylesIntoStyleTag_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! !../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js */ "./node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js");
|
|
17783
|
+
/* harmony import */ var _node_modules_style_loader_dist_runtime_injectStylesIntoStyleTag_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_style_loader_dist_runtime_injectStylesIntoStyleTag_js__WEBPACK_IMPORTED_MODULE_0__);
|
|
17784
|
+
/* harmony import */ var _node_modules_style_loader_dist_runtime_styleDomAPI_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! !../node_modules/style-loader/dist/runtime/styleDomAPI.js */ "./node_modules/style-loader/dist/runtime/styleDomAPI.js");
|
|
17785
|
+
/* harmony import */ var _node_modules_style_loader_dist_runtime_styleDomAPI_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_style_loader_dist_runtime_styleDomAPI_js__WEBPACK_IMPORTED_MODULE_1__);
|
|
17786
|
+
/* harmony import */ var _node_modules_style_loader_dist_runtime_insertBySelector_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! !../node_modules/style-loader/dist/runtime/insertBySelector.js */ "./node_modules/style-loader/dist/runtime/insertBySelector.js");
|
|
17787
|
+
/* harmony import */ var _node_modules_style_loader_dist_runtime_insertBySelector_js__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_node_modules_style_loader_dist_runtime_insertBySelector_js__WEBPACK_IMPORTED_MODULE_2__);
|
|
17788
|
+
/* harmony import */ var _node_modules_style_loader_dist_runtime_setAttributesWithoutAttributes_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! !../node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js */ "./node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js");
|
|
17789
|
+
/* harmony import */ var _node_modules_style_loader_dist_runtime_setAttributesWithoutAttributes_js__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_node_modules_style_loader_dist_runtime_setAttributesWithoutAttributes_js__WEBPACK_IMPORTED_MODULE_3__);
|
|
17790
|
+
/* harmony import */ var _node_modules_style_loader_dist_runtime_insertStyleElement_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! !../node_modules/style-loader/dist/runtime/insertStyleElement.js */ "./node_modules/style-loader/dist/runtime/insertStyleElement.js");
|
|
17791
|
+
/* harmony import */ var _node_modules_style_loader_dist_runtime_insertStyleElement_js__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(_node_modules_style_loader_dist_runtime_insertStyleElement_js__WEBPACK_IMPORTED_MODULE_4__);
|
|
17792
|
+
/* harmony import */ var _node_modules_style_loader_dist_runtime_styleTagTransform_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! !../node_modules/style-loader/dist/runtime/styleTagTransform.js */ "./node_modules/style-loader/dist/runtime/styleTagTransform.js");
|
|
17793
|
+
/* harmony import */ var _node_modules_style_loader_dist_runtime_styleTagTransform_js__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(_node_modules_style_loader_dist_runtime_styleTagTransform_js__WEBPACK_IMPORTED_MODULE_5__);
|
|
17794
|
+
/* harmony import */ var _node_modules_css_loader_dist_cjs_js_FilesSelector_css__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! !!../node_modules/css-loader/dist/cjs.js!./FilesSelector.css */ "./node_modules/css-loader/dist/cjs.js!./style/FilesSelector.css");
|
|
17795
|
+
|
|
17796
|
+
|
|
17797
|
+
|
|
17798
|
+
|
|
17799
|
+
|
|
17800
|
+
|
|
17801
|
+
|
|
17802
|
+
|
|
17803
|
+
|
|
17804
|
+
|
|
17805
|
+
|
|
17806
|
+
var options = {};
|
|
17807
|
+
|
|
17808
|
+
options.styleTagTransform = (_node_modules_style_loader_dist_runtime_styleTagTransform_js__WEBPACK_IMPORTED_MODULE_5___default());
|
|
17809
|
+
options.setAttributes = (_node_modules_style_loader_dist_runtime_setAttributesWithoutAttributes_js__WEBPACK_IMPORTED_MODULE_3___default());
|
|
17810
|
+
|
|
17811
|
+
options.insert = _node_modules_style_loader_dist_runtime_insertBySelector_js__WEBPACK_IMPORTED_MODULE_2___default().bind(null, "head");
|
|
17812
|
+
|
|
17813
|
+
options.domAPI = (_node_modules_style_loader_dist_runtime_styleDomAPI_js__WEBPACK_IMPORTED_MODULE_1___default());
|
|
17814
|
+
options.insertStyleElement = (_node_modules_style_loader_dist_runtime_insertStyleElement_js__WEBPACK_IMPORTED_MODULE_4___default());
|
|
17815
|
+
|
|
17816
|
+
var update = _node_modules_style_loader_dist_runtime_injectStylesIntoStyleTag_js__WEBPACK_IMPORTED_MODULE_0___default()(_node_modules_css_loader_dist_cjs_js_FilesSelector_css__WEBPACK_IMPORTED_MODULE_6__["default"], options);
|
|
17817
|
+
|
|
17818
|
+
|
|
17819
|
+
|
|
17820
|
+
|
|
17821
|
+
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (_node_modules_css_loader_dist_cjs_js_FilesSelector_css__WEBPACK_IMPORTED_MODULE_6__["default"] && _node_modules_css_loader_dist_cjs_js_FilesSelector_css__WEBPACK_IMPORTED_MODULE_6__["default"].locals ? _node_modules_css_loader_dist_cjs_js_FilesSelector_css__WEBPACK_IMPORTED_MODULE_6__["default"].locals : undefined);
|
|
17822
|
+
|
|
17823
|
+
|
|
16939
17824
|
/***/ }),
|
|
16940
17825
|
|
|
16941
17826
|
/***/ "./style/IconButton.css":
|
|
@@ -17530,6 +18415,60 @@ var update = _node_modules_style_loader_dist_runtime_injectStylesIntoStyleTag_js
|
|
|
17530
18415
|
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (_node_modules_css_loader_dist_cjs_js_SettingsWidget_css__WEBPACK_IMPORTED_MODULE_6__["default"] && _node_modules_css_loader_dist_cjs_js_SettingsWidget_css__WEBPACK_IMPORTED_MODULE_6__["default"].locals ? _node_modules_css_loader_dist_cjs_js_SettingsWidget_css__WEBPACK_IMPORTED_MODULE_6__["default"].locals : undefined);
|
|
17531
18416
|
|
|
17532
18417
|
|
|
18418
|
+
/***/ }),
|
|
18419
|
+
|
|
18420
|
+
/***/ "./style/StreamlitPreviewPlugin.css":
|
|
18421
|
+
/*!******************************************!*\
|
|
18422
|
+
!*** ./style/StreamlitPreviewPlugin.css ***!
|
|
18423
|
+
\******************************************/
|
|
18424
|
+
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
18425
|
+
|
|
18426
|
+
__webpack_require__.r(__webpack_exports__);
|
|
18427
|
+
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
18428
|
+
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
|
|
18429
|
+
/* harmony export */ });
|
|
18430
|
+
/* harmony import */ var _node_modules_style_loader_dist_runtime_injectStylesIntoStyleTag_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! !../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js */ "./node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js");
|
|
18431
|
+
/* harmony import */ var _node_modules_style_loader_dist_runtime_injectStylesIntoStyleTag_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_style_loader_dist_runtime_injectStylesIntoStyleTag_js__WEBPACK_IMPORTED_MODULE_0__);
|
|
18432
|
+
/* harmony import */ var _node_modules_style_loader_dist_runtime_styleDomAPI_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! !../node_modules/style-loader/dist/runtime/styleDomAPI.js */ "./node_modules/style-loader/dist/runtime/styleDomAPI.js");
|
|
18433
|
+
/* harmony import */ var _node_modules_style_loader_dist_runtime_styleDomAPI_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_style_loader_dist_runtime_styleDomAPI_js__WEBPACK_IMPORTED_MODULE_1__);
|
|
18434
|
+
/* harmony import */ var _node_modules_style_loader_dist_runtime_insertBySelector_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! !../node_modules/style-loader/dist/runtime/insertBySelector.js */ "./node_modules/style-loader/dist/runtime/insertBySelector.js");
|
|
18435
|
+
/* harmony import */ var _node_modules_style_loader_dist_runtime_insertBySelector_js__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_node_modules_style_loader_dist_runtime_insertBySelector_js__WEBPACK_IMPORTED_MODULE_2__);
|
|
18436
|
+
/* harmony import */ var _node_modules_style_loader_dist_runtime_setAttributesWithoutAttributes_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! !../node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js */ "./node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js");
|
|
18437
|
+
/* harmony import */ var _node_modules_style_loader_dist_runtime_setAttributesWithoutAttributes_js__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_node_modules_style_loader_dist_runtime_setAttributesWithoutAttributes_js__WEBPACK_IMPORTED_MODULE_3__);
|
|
18438
|
+
/* harmony import */ var _node_modules_style_loader_dist_runtime_insertStyleElement_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! !../node_modules/style-loader/dist/runtime/insertStyleElement.js */ "./node_modules/style-loader/dist/runtime/insertStyleElement.js");
|
|
18439
|
+
/* harmony import */ var _node_modules_style_loader_dist_runtime_insertStyleElement_js__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(_node_modules_style_loader_dist_runtime_insertStyleElement_js__WEBPACK_IMPORTED_MODULE_4__);
|
|
18440
|
+
/* harmony import */ var _node_modules_style_loader_dist_runtime_styleTagTransform_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! !../node_modules/style-loader/dist/runtime/styleTagTransform.js */ "./node_modules/style-loader/dist/runtime/styleTagTransform.js");
|
|
18441
|
+
/* harmony import */ var _node_modules_style_loader_dist_runtime_styleTagTransform_js__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(_node_modules_style_loader_dist_runtime_styleTagTransform_js__WEBPACK_IMPORTED_MODULE_5__);
|
|
18442
|
+
/* harmony import */ var _node_modules_css_loader_dist_cjs_js_StreamlitPreviewPlugin_css__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! !!../node_modules/css-loader/dist/cjs.js!./StreamlitPreviewPlugin.css */ "./node_modules/css-loader/dist/cjs.js!./style/StreamlitPreviewPlugin.css");
|
|
18443
|
+
|
|
18444
|
+
|
|
18445
|
+
|
|
18446
|
+
|
|
18447
|
+
|
|
18448
|
+
|
|
18449
|
+
|
|
18450
|
+
|
|
18451
|
+
|
|
18452
|
+
|
|
18453
|
+
|
|
18454
|
+
var options = {};
|
|
18455
|
+
|
|
18456
|
+
options.styleTagTransform = (_node_modules_style_loader_dist_runtime_styleTagTransform_js__WEBPACK_IMPORTED_MODULE_5___default());
|
|
18457
|
+
options.setAttributes = (_node_modules_style_loader_dist_runtime_setAttributesWithoutAttributes_js__WEBPACK_IMPORTED_MODULE_3___default());
|
|
18458
|
+
|
|
18459
|
+
options.insert = _node_modules_style_loader_dist_runtime_insertBySelector_js__WEBPACK_IMPORTED_MODULE_2___default().bind(null, "head");
|
|
18460
|
+
|
|
18461
|
+
options.domAPI = (_node_modules_style_loader_dist_runtime_styleDomAPI_js__WEBPACK_IMPORTED_MODULE_1___default());
|
|
18462
|
+
options.insertStyleElement = (_node_modules_style_loader_dist_runtime_insertStyleElement_js__WEBPACK_IMPORTED_MODULE_4___default());
|
|
18463
|
+
|
|
18464
|
+
var update = _node_modules_style_loader_dist_runtime_injectStylesIntoStyleTag_js__WEBPACK_IMPORTED_MODULE_0___default()(_node_modules_css_loader_dist_cjs_js_StreamlitPreviewPlugin_css__WEBPACK_IMPORTED_MODULE_6__["default"], options);
|
|
18465
|
+
|
|
18466
|
+
|
|
18467
|
+
|
|
18468
|
+
|
|
18469
|
+
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (_node_modules_css_loader_dist_cjs_js_StreamlitPreviewPlugin_css__WEBPACK_IMPORTED_MODULE_6__["default"] && _node_modules_css_loader_dist_cjs_js_StreamlitPreviewPlugin_css__WEBPACK_IMPORTED_MODULE_6__["default"].locals ? _node_modules_css_loader_dist_cjs_js_StreamlitPreviewPlugin_css__WEBPACK_IMPORTED_MODULE_6__["default"].locals : undefined);
|
|
18470
|
+
|
|
18471
|
+
|
|
17533
18472
|
/***/ }),
|
|
17534
18473
|
|
|
17535
18474
|
/***/ "./style/TextAndIconButton.css":
|
|
@@ -17749,4 +18688,4 @@ var update = _node_modules_style_loader_dist_runtime_injectStylesIntoStyleTag_js
|
|
|
17749
18688
|
/***/ })
|
|
17750
18689
|
|
|
17751
18690
|
}]);
|
|
17752
|
-
//# sourceMappingURL=lib_index_js.
|
|
18691
|
+
//# sourceMappingURL=lib_index_js.0c3368195d954d2ed033.js.map
|