mito-ai 0.1.51__py3-none-any.whl → 0.1.53__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.
Files changed (40) hide show
  1. mito_ai/_version.py +1 -1
  2. mito_ai/anthropic_client.py +4 -3
  3. mito_ai/constants.py +1 -1
  4. mito_ai/tests/test_constants.py +1 -1
  5. mito_ai/utils/anthropic_utils.py +28 -3
  6. mito_ai/utils/tokens.py +29 -0
  7. {mito_ai-0.1.51.data → mito_ai-0.1.53.data}/data/share/jupyter/labextensions/mito_ai/build_log.json +111 -103
  8. {mito_ai-0.1.51.data → mito_ai-0.1.53.data}/data/share/jupyter/labextensions/mito_ai/package.json +2 -2
  9. {mito_ai-0.1.51.data → mito_ai-0.1.53.data}/data/share/jupyter/labextensions/mito_ai/schemas/mito_ai/package.json.orig +1 -1
  10. mito_ai-0.1.51.data/data/share/jupyter/labextensions/mito_ai/static/lib_index_js.c0b356ea4ace64bf1f03.js → mito_ai-0.1.53.data/data/share/jupyter/labextensions/mito_ai/static/lib_index_js.4b7cd47a24bb24ef84ea.js +572 -179
  11. mito_ai-0.1.53.data/data/share/jupyter/labextensions/mito_ai/static/lib_index_js.4b7cd47a24bb24ef84ea.js.map +1 -0
  12. mito_ai-0.1.51.data/data/share/jupyter/labextensions/mito_ai/static/remoteEntry.d467572621b790a8240e.js → mito_ai-0.1.53.data/data/share/jupyter/labextensions/mito_ai/static/remoteEntry.4395ab9342efa39fc0a2.js +17 -17
  13. mito_ai-0.1.51.data/data/share/jupyter/labextensions/mito_ai/static/remoteEntry.d467572621b790a8240e.js.map → mito_ai-0.1.53.data/data/share/jupyter/labextensions/mito_ai/static/remoteEntry.4395ab9342efa39fc0a2.js.map +1 -1
  14. {mito_ai-0.1.51.dist-info → mito_ai-0.1.53.dist-info}/METADATA +1 -1
  15. {mito_ai-0.1.51.dist-info → mito_ai-0.1.53.dist-info}/RECORD +39 -38
  16. mito_ai-0.1.51.data/data/share/jupyter/labextensions/mito_ai/static/lib_index_js.c0b356ea4ace64bf1f03.js.map +0 -1
  17. {mito_ai-0.1.51.data → mito_ai-0.1.53.data}/data/etc/jupyter/jupyter_server_config.d/mito_ai.json +0 -0
  18. {mito_ai-0.1.51.data → mito_ai-0.1.53.data}/data/share/jupyter/labextensions/mito_ai/schemas/mito_ai/toolbar-buttons.json +0 -0
  19. {mito_ai-0.1.51.data → mito_ai-0.1.53.data}/data/share/jupyter/labextensions/mito_ai/static/node_modules_process_browser_js.4b128e94d31a81ebd209.js +0 -0
  20. {mito_ai-0.1.51.data → mito_ai-0.1.53.data}/data/share/jupyter/labextensions/mito_ai/static/node_modules_process_browser_js.4b128e94d31a81ebd209.js.map +0 -0
  21. {mito_ai-0.1.51.data → mito_ai-0.1.53.data}/data/share/jupyter/labextensions/mito_ai/static/style.js +0 -0
  22. {mito_ai-0.1.51.data → mito_ai-0.1.53.data}/data/share/jupyter/labextensions/mito_ai/static/style_index_js.5876024bb17dbd6a3ee6.js +0 -0
  23. {mito_ai-0.1.51.data → mito_ai-0.1.53.data}/data/share/jupyter/labextensions/mito_ai/static/style_index_js.5876024bb17dbd6a3ee6.js.map +0 -0
  24. {mito_ai-0.1.51.data → mito_ai-0.1.53.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
  25. {mito_ai-0.1.51.data → mito_ai-0.1.53.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
  26. {mito_ai-0.1.51.data → mito_ai-0.1.53.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
  27. {mito_ai-0.1.51.data → mito_ai-0.1.53.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
  28. {mito_ai-0.1.51.data → mito_ai-0.1.53.data}/data/share/jupyter/labextensions/mito_ai/static/vendors-node_modules_aws-amplify_dist_esm_index_mjs.6bac1a8c4cc93f15f6b7.js +0 -0
  29. {mito_ai-0.1.51.data → mito_ai-0.1.53.data}/data/share/jupyter/labextensions/mito_ai/static/vendors-node_modules_aws-amplify_dist_esm_index_mjs.6bac1a8c4cc93f15f6b7.js.map +0 -0
  30. {mito_ai-0.1.51.data → mito_ai-0.1.53.data}/data/share/jupyter/labextensions/mito_ai/static/vendors-node_modules_aws-amplify_ui-react_dist_esm_index_mjs.4fcecd65bef9e9847609.js +0 -0
  31. {mito_ai-0.1.51.data → mito_ai-0.1.53.data}/data/share/jupyter/labextensions/mito_ai/static/vendors-node_modules_aws-amplify_ui-react_dist_esm_index_mjs.4fcecd65bef9e9847609.js.map +0 -0
  32. {mito_ai-0.1.51.data → mito_ai-0.1.53.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
  33. {mito_ai-0.1.51.data → mito_ai-0.1.53.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
  34. {mito_ai-0.1.51.data → mito_ai-0.1.53.data}/data/share/jupyter/labextensions/mito_ai/static/vendors-node_modules_semver_index_js.3f6754ac5116d47de76b.js +0 -0
  35. {mito_ai-0.1.51.data → mito_ai-0.1.53.data}/data/share/jupyter/labextensions/mito_ai/static/vendors-node_modules_semver_index_js.3f6754ac5116d47de76b.js.map +0 -0
  36. {mito_ai-0.1.51.data → mito_ai-0.1.53.data}/data/share/jupyter/labextensions/mito_ai/static/vendors-node_modules_vscode-diff_dist_index_js.ea55f1f9346638aafbcf.js +0 -0
  37. {mito_ai-0.1.51.data → mito_ai-0.1.53.data}/data/share/jupyter/labextensions/mito_ai/static/vendors-node_modules_vscode-diff_dist_index_js.ea55f1f9346638aafbcf.js.map +0 -0
  38. {mito_ai-0.1.51.dist-info → mito_ai-0.1.53.dist-info}/WHEEL +0 -0
  39. {mito_ai-0.1.51.dist-info → mito_ai-0.1.53.dist-info}/entry_points.txt +0 -0
  40. {mito_ai-0.1.51.dist-info → mito_ai-0.1.53.dist-info}/licenses/LICENSE +0 -0
@@ -666,22 +666,18 @@ __webpack_require__.r(__webpack_exports__);
666
666
 
667
667
 
668
668
 
669
- const AgentChangeControls = ({ reviewAgentChanges, app, notebookTracker, setHasCheckpoint, setDisplayedNextStepsIfAvailable, setShowRevertQuestionnaire, chatTaskpaneMessagesRef, acceptAllAICode, rejectAllAICode, getChangeCounts, getReviewProgress, setAgentReviewStatus, agentReviewStatus, }) => {
670
- const [changeCounts, setChangeCounts] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(null);
669
+ const AgentChangeControls = ({ reviewAgentChanges, app, notebookTracker, setHasCheckpoint, setDisplayedNextStepsIfAvailable, setShowRevertQuestionnaire, chatTaskpaneMessagesRef, acceptAllAICode, rejectAllAICode, getReviewProgress, setAgentReviewStatus, agentReviewStatus, }) => {
671
670
  const [reviewProgress, setReviewProgress] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(null);
672
671
  // Update counts when review starts
673
672
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
674
673
  if (agentReviewStatus === 'in-agent-code-review') {
675
- const counts = getChangeCounts();
676
- setChangeCounts(counts);
677
674
  const progress = getReviewProgress();
678
675
  setReviewProgress(progress);
679
676
  }
680
677
  else {
681
- setChangeCounts(null);
682
678
  setReviewProgress(null);
683
679
  }
684
- }, [agentReviewStatus, getChangeCounts, getReviewProgress]);
680
+ }, [agentReviewStatus, getReviewProgress]);
685
681
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
686
682
  // Update progress periodically during review to reflect when cells are reviewed.
687
683
  // We use polling here instead of event-driven updates because it's simpler and more robust -
@@ -702,16 +698,11 @@ const AgentChangeControls = ({ reviewAgentChanges, app, notebookTracker, setHasC
702
698
  }, [agentReviewStatus]);
703
699
  const handleReviewChanges = () => {
704
700
  reviewAgentChanges();
705
- // reviewAgentChanges populates changedCellsRef synchronously, so we can get counts immediately
706
- const counts = getChangeCounts();
707
- // Only set status if there are actually changes to review
708
- if (counts.total > 0) {
709
- setAgentReviewStatus('in-agent-code-review');
710
- // Scroll to show the new review controls after the UI updates
711
- setTimeout(() => {
712
- (0,_utils_scroll__WEBPACK_IMPORTED_MODULE_2__.scrollToDiv)(chatTaskpaneMessagesRef);
713
- }, 0);
714
- }
701
+ setAgentReviewStatus('in-agent-code-review');
702
+ // Scroll to show the new review controls after the UI updates
703
+ setTimeout(() => {
704
+ (0,_utils_scroll__WEBPACK_IMPORTED_MODULE_2__.scrollToDiv)(chatTaskpaneMessagesRef);
705
+ }, 0);
715
706
  };
716
707
  const handleAcceptAll = () => {
717
708
  acceptAllAICode();
@@ -738,22 +729,6 @@ const AgentChangeControls = ({ reviewAgentChanges, app, notebookTracker, setHasC
738
729
  if (agentReviewStatus === 'in-agent-code-review') {
739
730
  return (react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { className: 'message message-assistant-chat' },
740
731
  react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { className: "agent-change-controls-container" },
741
- changeCounts && (react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { className: "agent-change-counts" },
742
- react__WEBPACK_IMPORTED_MODULE_0___default().createElement("span", { className: "agent-change-count" },
743
- react__WEBPACK_IMPORTED_MODULE_0___default().createElement("span", { className: "agent-change-count-number agent-change-count-added" },
744
- changeCounts.added,
745
- " \u00A0"),
746
- react__WEBPACK_IMPORTED_MODULE_0___default().createElement("span", { className: "agent-change-count-text" }, changeCounts.added === 1 ? 'cell added' : 'cells added')),
747
- react__WEBPACK_IMPORTED_MODULE_0___default().createElement("span", { className: "agent-change-count" },
748
- react__WEBPACK_IMPORTED_MODULE_0___default().createElement("span", { className: "agent-change-count-number agent-change-count-modified" },
749
- changeCounts.modified,
750
- " \u00A0"),
751
- react__WEBPACK_IMPORTED_MODULE_0___default().createElement("span", { className: "agent-change-count-text" }, changeCounts.modified === 1 ? 'cell modified' : 'cells modified')),
752
- react__WEBPACK_IMPORTED_MODULE_0___default().createElement("span", { className: "agent-change-count" },
753
- react__WEBPACK_IMPORTED_MODULE_0___default().createElement("span", { className: "agent-change-count-number agent-change-count-removed" },
754
- changeCounts.removed,
755
- " \u00A0"),
756
- react__WEBPACK_IMPORTED_MODULE_0___default().createElement("span", { className: "agent-change-count-text" }, changeCounts.removed === 1 ? 'cell removed' : 'cells removed')))),
757
732
  react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { className: "agent-change-controls-buttons" },
758
733
  react__WEBPACK_IMPORTED_MODULE_0___default().createElement("button", { className: "button-base button-green", title: "Accept all changes", onClick: handleAcceptAll }, "Accept all"),
759
734
  react__WEBPACK_IMPORTED_MODULE_0___default().createElement("button", { className: "button-base button-red", onClick: handleRejectAll }, "Reject All")),
@@ -772,6 +747,43 @@ const AgentChangeControls = ({ reviewAgentChanges, app, notebookTracker, setHasC
772
747
  /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (AgentChangeControls);
773
748
 
774
749
 
750
+ /***/ }),
751
+
752
+ /***/ "./lib/Extensions/AiChat/ChatMessage/AgentChangeSummary.js":
753
+ /*!*****************************************************************!*\
754
+ !*** ./lib/Extensions/AiChat/ChatMessage/AgentChangeSummary.js ***!
755
+ \*****************************************************************/
756
+ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
757
+
758
+ __webpack_require__.r(__webpack_exports__);
759
+ /* harmony export */ __webpack_require__.d(__webpack_exports__, {
760
+ /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
761
+ /* harmony export */ });
762
+ /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ "webpack/sharing/consume/default/react");
763
+ /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
764
+ /* harmony import */ var _style_AgentChangeControls_css__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../../style/AgentChangeControls.css */ "./style/AgentChangeControls.css");
765
+ /*
766
+ * Copyright (c) Saga Inc.
767
+ * Distributed under the terms of the GNU Affero General Public License v3.0 License.
768
+ */
769
+
770
+
771
+ const AgentChangeSummary = ({ getChangeCounts, }) => {
772
+ const changeCounts = getChangeCounts();
773
+ return (react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { className: "agent-change-counts" },
774
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement("span", { className: "agent-change-count" },
775
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement("span", { className: "agent-change-count-number agent-change-count-added" }, changeCounts.added),
776
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement("span", { className: "agent-change-count-text" }, changeCounts.added === 1 ? 'cell added' : 'cells added')),
777
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement("span", { className: "agent-change-count" },
778
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement("span", { className: "agent-change-count-number agent-change-count-modified" }, changeCounts.modified),
779
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement("span", { className: "agent-change-count-text" }, changeCounts.modified === 1 ? 'cell modified' : 'cells modified')),
780
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement("span", { className: "agent-change-count" },
781
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement("span", { className: "agent-change-count-number agent-change-count-removed" }, changeCounts.removed),
782
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement("span", { className: "agent-change-count-text" }, changeCounts.removed === 1 ? 'cell removed' : 'cells removed'))));
783
+ };
784
+ /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (AgentChangeSummary);
785
+
786
+
775
787
  /***/ }),
776
788
 
777
789
  /***/ "./lib/Extensions/AiChat/ChatMessage/AlertBlock.js":
@@ -3041,7 +3053,7 @@ const ChatTaskpane = ({ notebookTracker, renderMimeRegistry, contextManager, str
3041
3053
  react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { className: "chat-loading-message" },
3042
3054
  "Thinking ",
3043
3055
  react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_components_LoadingDots__WEBPACK_IMPORTED_MODULE_37__["default"], null)),
3044
- react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_components_AgentReviewPanel__WEBPACK_IMPORTED_MODULE_38__["default"], { hasCheckpoint: hasCheckpoint, agentModeEnabled: agentModeEnabled, agentExecutionStatus: agentExecution.agentExecutionStatus, displayOptimizedChatHistoryLength: displayOptimizedChatHistory.length, showRevertQuestionnaire: showRevertQuestionnaire, reviewAgentChanges: agentReview.reviewAgentChanges, acceptAllAICode: agentReview.acceptAllAICode, rejectAllAICode: agentReview.rejectAllAICode, getChangeCounts: agentReview.getChangeCounts, getReviewProgress: agentReview.getReviewProgress, setHasCheckpoint: setHasCheckpoint, setDisplayedNextStepsIfAvailable: setDisplayedNextStepsIfAvailable, setShowRevertQuestionnaire: setShowRevertQuestionnaire, getDuplicateChatHistoryManager: getDuplicateChatHistoryManager, setChatHistoryManager: setChatHistoryManager, app: app, notebookTracker: notebookTracker, chatTaskpaneMessagesRef: chatTaskpaneMessagesRef, agentReviewStatus: agentReviewStatus, setAgentReviewStatus: setAgentReviewStatus })),
3056
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_components_AgentReviewPanel__WEBPACK_IMPORTED_MODULE_38__["default"], { hasCheckpoint: hasCheckpoint, agentModeEnabled: agentModeEnabled, agentExecutionStatus: agentExecution.agentExecutionStatus, showRevertQuestionnaire: showRevertQuestionnaire, reviewAgentChanges: agentReview.reviewAgentChanges, acceptAllAICode: agentReview.acceptAllAICode, rejectAllAICode: agentReview.rejectAllAICode, getChangeCounts: agentReview.getChangeCounts, getReviewProgress: agentReview.getReviewProgress, hasChanges: agentReview.hasChanges, setHasCheckpoint: setHasCheckpoint, setDisplayedNextStepsIfAvailable: setDisplayedNextStepsIfAvailable, setShowRevertQuestionnaire: setShowRevertQuestionnaire, getDuplicateChatHistoryManager: getDuplicateChatHistoryManager, setChatHistoryManager: setChatHistoryManager, app: app, notebookTracker: notebookTracker, chatTaskpaneMessagesRef: chatTaskpaneMessagesRef, agentReviewStatus: agentReviewStatus, setAgentReviewStatus: setAgentReviewStatus })),
3045
3057
  displayOptimizedChatHistory.length === 0 && (react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { className: "suggestions-container" },
3046
3058
  react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_ChatMessage_ScrollableSuggestions__WEBPACK_IMPORTED_MODULE_39__["default"], { onSelectSuggestion: (prompt) => {
3047
3059
  if (agentModeEnabled) {
@@ -3557,8 +3569,9 @@ __webpack_require__.r(__webpack_exports__);
3557
3569
  /* harmony export */ });
3558
3570
  /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ "webpack/sharing/consume/default/react");
3559
3571
  /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
3560
- /* harmony import */ var _ChatMessage_AgentChangeControls__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../ChatMessage/AgentChangeControls */ "./lib/Extensions/AiChat/ChatMessage/AgentChangeControls.js");
3561
- /* harmony import */ var _ChatMessage_RevertQuestionnaire__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../ChatMessage/RevertQuestionnaire */ "./lib/Extensions/AiChat/ChatMessage/RevertQuestionnaire.js");
3572
+ /* harmony import */ var _ChatMessage_AgentChangeControls__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../ChatMessage/AgentChangeControls */ "./lib/Extensions/AiChat/ChatMessage/AgentChangeControls.js");
3573
+ /* harmony import */ var _ChatMessage_AgentChangeSummary__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../ChatMessage/AgentChangeSummary */ "./lib/Extensions/AiChat/ChatMessage/AgentChangeSummary.js");
3574
+ /* harmony import */ var _ChatMessage_RevertQuestionnaire__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../ChatMessage/RevertQuestionnaire */ "./lib/Extensions/AiChat/ChatMessage/RevertQuestionnaire.js");
3562
3575
  /*
3563
3576
  * Copyright (c) Saga Inc.
3564
3577
  * Distributed under the terms of the GNU Affero General Public License v3.0 License.
@@ -3566,13 +3579,16 @@ __webpack_require__.r(__webpack_exports__);
3566
3579
 
3567
3580
 
3568
3581
 
3569
- const AgentReviewPanel = ({ agentReviewStatus, setAgentReviewStatus, hasCheckpoint, agentModeEnabled, agentExecutionStatus, displayOptimizedChatHistoryLength, showRevertQuestionnaire, reviewAgentChanges, acceptAllAICode, rejectAllAICode, getChangeCounts, getReviewProgress, setHasCheckpoint, setDisplayedNextStepsIfAvailable, setShowRevertQuestionnaire, getDuplicateChatHistoryManager, setChatHistoryManager, app, notebookTracker, chatTaskpaneMessagesRef }) => {
3582
+
3583
+ const AgentReviewPanel = ({ agentReviewStatus, setAgentReviewStatus, hasCheckpoint, agentModeEnabled, agentExecutionStatus, showRevertQuestionnaire, reviewAgentChanges, acceptAllAICode, rejectAllAICode, getChangeCounts, getReviewProgress, hasChanges, setHasCheckpoint, setDisplayedNextStepsIfAvailable, setShowRevertQuestionnaire, getDuplicateChatHistoryManager, setChatHistoryManager, app, notebookTracker, chatTaskpaneMessagesRef }) => {
3584
+ const agentFinished = hasCheckpoint && agentModeEnabled && agentExecutionStatus === 'idle';
3585
+ const shouldShowAgentChangeControls = agentFinished && hasChanges();
3586
+ const shouldShowSummary = agentFinished && (agentReviewStatus === 'pre-agent-code-review' || agentReviewStatus === 'in-agent-code-review');
3570
3587
  return (react__WEBPACK_IMPORTED_MODULE_0___default().createElement((react__WEBPACK_IMPORTED_MODULE_0___default().Fragment), null,
3571
- hasCheckpoint &&
3572
- agentModeEnabled &&
3573
- agentExecutionStatus === 'idle' &&
3574
- displayOptimizedChatHistoryLength > 0 && (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_ChatMessage_AgentChangeControls__WEBPACK_IMPORTED_MODULE_1__["default"], { reviewAgentChanges: reviewAgentChanges, app: app, notebookTracker: notebookTracker, setHasCheckpoint: setHasCheckpoint, setDisplayedNextStepsIfAvailable: setDisplayedNextStepsIfAvailable, setShowRevertQuestionnaire: setShowRevertQuestionnaire, chatTaskpaneMessagesRef: chatTaskpaneMessagesRef, acceptAllAICode: acceptAllAICode, rejectAllAICode: rejectAllAICode, getChangeCounts: getChangeCounts, getReviewProgress: getReviewProgress, agentReviewStatus: agentReviewStatus, setAgentReviewStatus: setAgentReviewStatus })),
3575
- showRevertQuestionnaire && (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_ChatMessage_RevertQuestionnaire__WEBPACK_IMPORTED_MODULE_2__["default"], { onDestroy: () => setShowRevertQuestionnaire(false), getDuplicateChatHistoryManager: getDuplicateChatHistoryManager, setChatHistoryManager: setChatHistoryManager }))));
3588
+ shouldShowSummary && (react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { className: 'message message-assistant-chat' },
3589
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_ChatMessage_AgentChangeSummary__WEBPACK_IMPORTED_MODULE_1__["default"], { getChangeCounts: getChangeCounts }))),
3590
+ shouldShowAgentChangeControls && (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_ChatMessage_AgentChangeControls__WEBPACK_IMPORTED_MODULE_2__["default"], { reviewAgentChanges: reviewAgentChanges, app: app, notebookTracker: notebookTracker, setHasCheckpoint: setHasCheckpoint, setDisplayedNextStepsIfAvailable: setDisplayedNextStepsIfAvailable, setShowRevertQuestionnaire: setShowRevertQuestionnaire, chatTaskpaneMessagesRef: chatTaskpaneMessagesRef, acceptAllAICode: acceptAllAICode, rejectAllAICode: rejectAllAICode, getReviewProgress: getReviewProgress, agentReviewStatus: agentReviewStatus, setAgentReviewStatus: setAgentReviewStatus })),
3591
+ showRevertQuestionnaire && (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_ChatMessage_RevertQuestionnaire__WEBPACK_IMPORTED_MODULE_3__["default"], { onDestroy: () => setShowRevertQuestionnaire(false), getDuplicateChatHistoryManager: getDuplicateChatHistoryManager, setChatHistoryManager: setChatHistoryManager }))));
3576
3592
  };
3577
3593
  /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (AgentReviewPanel);
3578
3594
 
@@ -3884,9 +3900,9 @@ __webpack_require__.r(__webpack_exports__);
3884
3900
  /* harmony export */ });
3885
3901
  /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ "webpack/sharing/consume/default/react");
3886
3902
  /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
3887
- /* harmony import */ var _AgentReviewUtils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../AgentReviewUtils */ "./lib/Extensions/AiChat/AgentReviewUtils.js");
3903
+ /* harmony import */ var _AgentReviewUtils__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../AgentReviewUtils */ "./lib/Extensions/AiChat/AgentReviewUtils.js");
3888
3904
  /* harmony import */ var _utils_codeDiff__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../../utils/codeDiff */ "./lib/utils/codeDiff.js");
3889
- /* harmony import */ var _utils_notebook__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../../utils/notebook */ "./lib/utils/notebook.js");
3905
+ /* harmony import */ var _utils_notebook__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../utils/notebook */ "./lib/utils/notebook.js");
3890
3906
  /*
3891
3907
  * Copyright (c) Saga Inc.
3892
3908
  * Distributed under the terms of the GNU Affero General Public License v3.0 License.
@@ -3922,47 +3938,19 @@ const useAgentReview = ({ app, agentTargetNotebookPanelRef, codeDiffStripesCompa
3922
3938
  total: cells.length
3923
3939
  };
3924
3940
  };
3925
- const acceptAICodeInAgentMode = () => {
3926
- var _a, _b;
3927
- const activeCellId = (_b = (_a = agentTargetNotebookPanelRef === null || agentTargetNotebookPanelRef === void 0 ? void 0 : agentTargetNotebookPanelRef.current) === null || _a === void 0 ? void 0 : _a.content.activeCell) === null || _b === void 0 ? void 0 : _b.model.id;
3928
- if (!activeCellId || !hasUnreviewedChanges(activeCellId)) {
3929
- return;
3930
- }
3931
- (0,_AgentReviewUtils__WEBPACK_IMPORTED_MODULE_1__.acceptSingleCellEdit)(activeCellId, agentTargetNotebookPanelRef === null || agentTargetNotebookPanelRef === void 0 ? void 0 : agentTargetNotebookPanelRef.current, notebookSnapshotAfterAgentExecutionRef.current, codeDiffStripesCompartments, changedCellsRef.current, setAgentReviewStatus);
3932
- updateCellToolbarButtons();
3933
- };
3934
- const rejectAICodeInAgentMode = () => {
3935
- var _a, _b;
3936
- const activeCellId = (_b = (_a = agentTargetNotebookPanelRef === null || agentTargetNotebookPanelRef === void 0 ? void 0 : agentTargetNotebookPanelRef.current) === null || _a === void 0 ? void 0 : _a.content.activeCell) === null || _b === void 0 ? void 0 : _b.model.id;
3937
- if (!activeCellId || !hasUnreviewedChanges(activeCellId)) {
3938
- return;
3939
- }
3940
- (0,_AgentReviewUtils__WEBPACK_IMPORTED_MODULE_1__.rejectSingleCellEdit)(activeCellId, agentTargetNotebookPanelRef === null || agentTargetNotebookPanelRef === void 0 ? void 0 : agentTargetNotebookPanelRef.current, codeDiffStripesCompartments, changedCellsRef.current, setAgentReviewStatus, agentTargetNotebookPanelRef || undefined);
3941
- updateCellToolbarButtons();
3942
- };
3943
- const acceptAllAICode = () => {
3944
- (0,_AgentReviewUtils__WEBPACK_IMPORTED_MODULE_1__.acceptAllCellEdits)(agentTargetNotebookPanelRef === null || agentTargetNotebookPanelRef === void 0 ? void 0 : agentTargetNotebookPanelRef.current, notebookSnapshotAfterAgentExecutionRef.current, codeDiffStripesCompartments, changedCellsRef.current);
3945
- updateCellToolbarButtons();
3946
- };
3947
- const rejectAllAICode = () => {
3948
- (0,_AgentReviewUtils__WEBPACK_IMPORTED_MODULE_1__.rejectAllCellEdits)(agentTargetNotebookPanelRef === null || agentTargetNotebookPanelRef === void 0 ? void 0 : agentTargetNotebookPanelRef.current, codeDiffStripesCompartments, changedCellsRef.current);
3949
- updateCellToolbarButtons();
3950
- };
3951
- const reviewAgentChanges = () => {
3941
+ // Helper function to detect and count changes between snapshots
3942
+ // This populates changedCellsRef and changeCountsRef without applying visual diffs
3943
+ const detectChanges = () => {
3952
3944
  var _a;
3953
3945
  if (!(agentTargetNotebookPanelRef === null || agentTargetNotebookPanelRef === void 0 ? void 0 : agentTargetNotebookPanelRef.current)) {
3954
- return;
3946
+ return [];
3955
3947
  }
3956
- // Make the notebook panel the active notebook panel
3957
- app.shell.activateById(agentTargetNotebookPanelRef.current.id);
3958
- const currentNotebookSnapshot = (0,_utils_notebook__WEBPACK_IMPORTED_MODULE_2__.getAIOptimizedCellsInNotebookPanel)(agentTargetNotebookPanelRef.current);
3959
- notebookSnapshotAfterAgentExecutionRef.current = currentNotebookSnapshot;
3948
+ const currentNotebookSnapshot = (0,_utils_notebook__WEBPACK_IMPORTED_MODULE_1__.getAIOptimizedCellsInNotebookPanel)(agentTargetNotebookPanelRef.current);
3960
3949
  if (!notebookSnapshotPreAgentExecutionRef.current || !currentNotebookSnapshot) {
3961
- return;
3950
+ return [];
3962
3951
  }
3963
3952
  // Clear and populate the changed cells array
3964
3953
  const changedCells = [];
3965
- changedCellsRef.current = changedCells;
3966
3954
  // Initialize counters
3967
3955
  let added = 0;
3968
3956
  let modified = 0;
@@ -4015,6 +4003,50 @@ const useAgentReview = ({ app, agentTargetNotebookPanelRef, codeDiffStripesCompa
4015
4003
  removed,
4016
4004
  total: changedCells.length
4017
4005
  };
4006
+ return changedCells;
4007
+ };
4008
+ const hasChanges = () => {
4009
+ detectChanges();
4010
+ // changeCountsRef is populated by detectChanges()
4011
+ return changeCountsRef.current.total > 0;
4012
+ };
4013
+ const acceptAICodeInAgentMode = () => {
4014
+ var _a, _b;
4015
+ const activeCellId = (_b = (_a = agentTargetNotebookPanelRef === null || agentTargetNotebookPanelRef === void 0 ? void 0 : agentTargetNotebookPanelRef.current) === null || _a === void 0 ? void 0 : _a.content.activeCell) === null || _b === void 0 ? void 0 : _b.model.id;
4016
+ if (!activeCellId || !hasUnreviewedChanges(activeCellId)) {
4017
+ return;
4018
+ }
4019
+ (0,_AgentReviewUtils__WEBPACK_IMPORTED_MODULE_2__.acceptSingleCellEdit)(activeCellId, agentTargetNotebookPanelRef === null || agentTargetNotebookPanelRef === void 0 ? void 0 : agentTargetNotebookPanelRef.current, notebookSnapshotAfterAgentExecutionRef.current, codeDiffStripesCompartments, changedCellsRef.current, setAgentReviewStatus);
4020
+ updateCellToolbarButtons();
4021
+ };
4022
+ const rejectAICodeInAgentMode = () => {
4023
+ var _a, _b;
4024
+ const activeCellId = (_b = (_a = agentTargetNotebookPanelRef === null || agentTargetNotebookPanelRef === void 0 ? void 0 : agentTargetNotebookPanelRef.current) === null || _a === void 0 ? void 0 : _a.content.activeCell) === null || _b === void 0 ? void 0 : _b.model.id;
4025
+ if (!activeCellId || !hasUnreviewedChanges(activeCellId)) {
4026
+ return;
4027
+ }
4028
+ (0,_AgentReviewUtils__WEBPACK_IMPORTED_MODULE_2__.rejectSingleCellEdit)(activeCellId, agentTargetNotebookPanelRef === null || agentTargetNotebookPanelRef === void 0 ? void 0 : agentTargetNotebookPanelRef.current, codeDiffStripesCompartments, changedCellsRef.current, setAgentReviewStatus, agentTargetNotebookPanelRef || undefined);
4029
+ updateCellToolbarButtons();
4030
+ };
4031
+ const acceptAllAICode = () => {
4032
+ (0,_AgentReviewUtils__WEBPACK_IMPORTED_MODULE_2__.acceptAllCellEdits)(agentTargetNotebookPanelRef === null || agentTargetNotebookPanelRef === void 0 ? void 0 : agentTargetNotebookPanelRef.current, notebookSnapshotAfterAgentExecutionRef.current, codeDiffStripesCompartments, changedCellsRef.current);
4033
+ updateCellToolbarButtons();
4034
+ };
4035
+ const rejectAllAICode = () => {
4036
+ (0,_AgentReviewUtils__WEBPACK_IMPORTED_MODULE_2__.rejectAllCellEdits)(agentTargetNotebookPanelRef === null || agentTargetNotebookPanelRef === void 0 ? void 0 : agentTargetNotebookPanelRef.current, codeDiffStripesCompartments, changedCellsRef.current);
4037
+ updateCellToolbarButtons();
4038
+ };
4039
+ const reviewAgentChanges = () => {
4040
+ if (!(agentTargetNotebookPanelRef === null || agentTargetNotebookPanelRef === void 0 ? void 0 : agentTargetNotebookPanelRef.current)) {
4041
+ return;
4042
+ }
4043
+ // Make the notebook panel the active notebook panel
4044
+ app.shell.activateById(agentTargetNotebookPanelRef.current.id);
4045
+ const currentNotebookSnapshot = (0,_utils_notebook__WEBPACK_IMPORTED_MODULE_1__.getAIOptimizedCellsInNotebookPanel)(agentTargetNotebookPanelRef.current);
4046
+ notebookSnapshotAfterAgentExecutionRef.current = currentNotebookSnapshot;
4047
+ // Detect changes and populate refs
4048
+ const changedCells = detectChanges();
4049
+ changedCellsRef.current = changedCells;
4018
4050
  if (changedCells.length === 0) {
4019
4051
  console.log('No changes detected between snapshots');
4020
4052
  return;
@@ -4024,16 +4056,16 @@ const useAgentReview = ({ app, agentTargetNotebookPanelRef, codeDiffStripesCompa
4024
4056
  // Calculate the code diffs
4025
4057
  const { unifiedCodeString, unifiedDiffs } = (0,_utils_codeDiff__WEBPACK_IMPORTED_MODULE_3__.getCodeDiffsAndUnifiedCodeString)(change.originalCode, change.currentCode);
4026
4058
  // Write the unified code string to the cell
4027
- (0,_utils_notebook__WEBPACK_IMPORTED_MODULE_2__.writeCodeToCellByIDInNotebookPanel)(agentTargetNotebookPanelRef.current, unifiedCodeString, change.cellId);
4059
+ (0,_utils_notebook__WEBPACK_IMPORTED_MODULE_1__.writeCodeToCellByIDInNotebookPanel)(agentTargetNotebookPanelRef.current, unifiedCodeString, change.cellId);
4028
4060
  // Apply diff stripes to this cell
4029
4061
  (0,_utils_codeDiff__WEBPACK_IMPORTED_MODULE_3__.applyDiffStripesToCell)(agentTargetNotebookPanelRef.current, change.cellId, unifiedDiffs, codeDiffStripesCompartments.current);
4030
4062
  // Highlight the cell to draw attention
4031
- (0,_utils_notebook__WEBPACK_IMPORTED_MODULE_2__.highlightCodeCellInNotebookPanel)(agentTargetNotebookPanelRef.current, change.cellId);
4063
+ (0,_utils_notebook__WEBPACK_IMPORTED_MODULE_1__.highlightCodeCellInNotebookPanel)(agentTargetNotebookPanelRef.current, change.cellId);
4032
4064
  });
4033
4065
  // Scroll to the first changed cell
4034
4066
  const firstChangedCell = changedCells[0];
4035
4067
  if (firstChangedCell && agentTargetNotebookPanelRef.current) {
4036
- (0,_utils_notebook__WEBPACK_IMPORTED_MODULE_2__.scrollToCell)(agentTargetNotebookPanelRef.current, firstChangedCell.cellId, undefined, 'start');
4068
+ (0,_utils_notebook__WEBPACK_IMPORTED_MODULE_1__.scrollToCell)(agentTargetNotebookPanelRef.current, firstChangedCell.cellId, undefined, 'start');
4037
4069
  }
4038
4070
  // Update toolbar buttons to show accept/reject buttons for cells with diffs
4039
4071
  updateCellToolbarButtons();
@@ -4061,7 +4093,8 @@ const useAgentReview = ({ app, agentTargetNotebookPanelRef, codeDiffStripesCompa
4061
4093
  setNotebookSnapshotPreAgentExecution,
4062
4094
  hasUnreviewedChanges,
4063
4095
  getChangeCounts,
4064
- getReviewProgress
4096
+ getReviewProgress,
4097
+ hasChanges
4065
4098
  };
4066
4099
  };
4067
4100
 
@@ -5249,15 +5282,16 @@ __webpack_require__.r(__webpack_exports__);
5249
5282
  /* harmony export */ });
5250
5283
  /* harmony import */ var _jupyterlab_apputils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @jupyterlab/apputils */ "webpack/sharing/consume/default/@jupyterlab/apputils");
5251
5284
  /* harmony import */ var _jupyterlab_apputils__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_jupyterlab_apputils__WEBPACK_IMPORTED_MODULE_0__);
5252
- /* harmony import */ var _requirementsUtils__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./requirementsUtils */ "./lib/Extensions/AppDeploy/requirementsUtils.js");
5253
- /* harmony import */ var _fileUtils__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./fileUtils */ "./lib/Extensions/AppDeploy/fileUtils.js");
5285
+ /* harmony import */ var _requirementsUtils__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./requirementsUtils */ "./lib/Extensions/AppDeploy/requirementsUtils.js");
5286
+ /* harmony import */ var _fileUtils__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./fileUtils */ "./lib/Extensions/AppDeploy/fileUtils.js");
5254
5287
  /* harmony import */ var _lumino_coreutils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @lumino/coreutils */ "webpack/sharing/consume/default/@lumino/coreutils");
5255
5288
  /* harmony import */ var _lumino_coreutils__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_lumino_coreutils__WEBPACK_IMPORTED_MODULE_1__);
5256
- /* harmony import */ var _DeployAppNotification__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./DeployAppNotification */ "./lib/Extensions/AppDeploy/DeployAppNotification.js");
5289
+ /* harmony import */ var _DeployAppNotification__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./DeployAppNotification */ "./lib/Extensions/AppDeploy/DeployAppNotification.js");
5257
5290
  /* harmony import */ var _auth__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./auth */ "./lib/Extensions/AppDeploy/auth.js");
5258
5291
  /* harmony import */ var _authPopupUtils__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./authPopupUtils */ "./lib/Extensions/AppDeploy/authPopupUtils.js");
5259
- /* harmony import */ var _FilesSelectorUtils__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./FilesSelectorUtils */ "./lib/Extensions/AppDeploy/FilesSelectorUtils.js");
5292
+ /* harmony import */ var _FilesSelectorUtils__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./FilesSelectorUtils */ "./lib/Extensions/AppDeploy/FilesSelectorUtils.js");
5260
5293
  /* harmony import */ var _utils_notebookMetadata__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../utils/notebookMetadata */ "./lib/utils/notebookMetadata.js");
5294
+ /* harmony import */ var _AppPreview_utils__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../AppPreview/utils */ "./lib/Extensions/AppPreview/utils.js");
5261
5295
  /*
5262
5296
  * Copyright (c) Saga Inc.
5263
5297
  * Distributed under the terms of the GNU Affero General Public License v3.0 License.
@@ -5271,6 +5305,7 @@ __webpack_require__.r(__webpack_exports__);
5271
5305
 
5272
5306
 
5273
5307
 
5308
+
5274
5309
  /*
5275
5310
  This function generates the requirements.txt file needed to host the streamlit app,
5276
5311
  and deploys it!
@@ -5305,16 +5340,17 @@ const deployStreamlitApp = async (notebookPanel, appDeployService, appManagerSer
5305
5340
  }
5306
5341
  const notebookPath = notebookPanel.context.path;
5307
5342
  const notebookID = (0,_utils_notebookMetadata__WEBPACK_IMPORTED_MODULE_4__.getNotebookIDAndSetIfNonexistant)(notebookPanel);
5343
+ const appFilename = notebookID ? (0,_AppPreview_utils__WEBPACK_IMPORTED_MODULE_5__.getAppNameFromNotebookID)(notebookID) : 'app.py';
5308
5344
  const notificationId = _jupyterlab_apputils__WEBPACK_IMPORTED_MODULE_0__.Notification.emit('Step 1/7: Gathering requirements...', 'in-progress', {
5309
5345
  autoClose: false
5310
5346
  });
5311
5347
  // Build the requirements.txt file
5312
- const requirementsContent = await (0,_requirementsUtils__WEBPACK_IMPORTED_MODULE_5__.generateRequirementsTxt)(notebookPanel);
5348
+ const requirementsContent = await (0,_requirementsUtils__WEBPACK_IMPORTED_MODULE_6__.generateRequirementsTxt)(notebookPanel, appFilename);
5313
5349
  // Save the files to the current directory
5314
- await (0,_fileUtils__WEBPACK_IMPORTED_MODULE_6__.saveFileWithKernel)(notebookPanel, './requirements.txt', requirementsContent);
5350
+ await (0,_fileUtils__WEBPACK_IMPORTED_MODULE_7__.saveFileWithKernel)(notebookPanel, './requirements.txt', requirementsContent);
5315
5351
  try {
5316
5352
  _jupyterlab_apputils__WEBPACK_IMPORTED_MODULE_0__.Notification.dismiss(notificationId);
5317
- selectedFiles = await (0,_FilesSelectorUtils__WEBPACK_IMPORTED_MODULE_7__.fileSelectorPopup)(notebookPanel);
5353
+ selectedFiles = await (0,_FilesSelectorUtils__WEBPACK_IMPORTED_MODULE_8__.fileSelectorPopup)(notebookPanel);
5318
5354
  }
5319
5355
  catch (error) {
5320
5356
  const errorMsg = 'Files selection failed: ' + error;
@@ -5359,7 +5395,7 @@ const deployStreamlitApp = async (notebookPanel, appDeployService, appManagerSer
5359
5395
  else {
5360
5396
  console.log("App deployment response:", response);
5361
5397
  const url = response.url;
5362
- (0,_DeployAppNotification__WEBPACK_IMPORTED_MODULE_8__.deployAppNotification)(url, appManagerService, newNotificationId);
5398
+ (0,_DeployAppNotification__WEBPACK_IMPORTED_MODULE_9__.deployAppNotification)(url, appManagerService, newNotificationId);
5363
5399
  }
5364
5400
  }
5365
5401
  catch (error) {
@@ -5704,9 +5740,9 @@ __webpack_require__.r(__webpack_exports__);
5704
5740
  * Distributed under the terms of the GNU Affero General Public License v3.0 License.
5705
5741
  */
5706
5742
 
5707
- const userPoolIdDev = 'us-east-1_Kk0f9mOfx';
5708
- const userPoolClientIdDev = '6ara3u3l8sss738hrhbq1qtiqf';
5709
- // TODO: modify to prod user ID and client ID on after creating teh cognito resources in prod
5743
+ const userPoolIdDev = 'us-east-1_s2V9RiyOa';
5744
+ const userPoolClientIdDev = '2sunerv2m6gp1qk3hib4t8oblh';
5745
+ // TODO: modify to prod user ID and client ID on after creating the cognito resources in prod
5710
5746
  const userPoolId = userPoolIdDev;
5711
5747
  const userPoolClientId = userPoolClientIdDev;
5712
5748
  const configureAmplify = () => {
@@ -5808,37 +5844,47 @@ __webpack_require__.r(__webpack_exports__);
5808
5844
  * Distributed under the terms of the GNU Affero General Public License v3.0 License.
5809
5845
  */
5810
5846
  // Function to generate requirements.txt content using the kernel with pipreqs
5811
- const generateRequirementsTxt = async (notebookPanel) => {
5847
+ const generateRequirementsTxt = async (notebookPanel, appFilename) => {
5812
5848
  // Initialize with fallback requirements in case kernel execution fails
5813
5849
  let requirementsContent = 'streamlit>=1.28.0';
5814
5850
  try {
5815
5851
  // Use the kernel to execute Python code using pipreqs
5816
5852
  const session = notebookPanel.sessionContext.session;
5817
5853
  if (session) {
5818
- const appPyPath = `app.py`;
5819
- // Create Python code to run pipreqs on the app.py file
5854
+ const sanitizedAppFilename = JSON.stringify(appFilename);
5855
+ // Create Python code to run pipreqs on the app file
5820
5856
  const pythonCode = `
5821
5857
  import subprocess
5822
5858
  import os
5859
+ import tempfile
5860
+ import shutil
5823
5861
 
5824
- # Check if app.py exists in the notebook directory
5825
- app_py_path = os.path.join(os.getcwd(), "${appPyPath}")
5862
+ # Check if the Streamlit app file exists in the notebook directory
5863
+ app_py_filename = ${sanitizedAppFilename}
5864
+ app_py_path = os.path.join(os.getcwd(), app_py_filename)
5826
5865
  if not os.path.exists(app_py_path):
5827
- print(f"Error: app.py not found at {app_py_path}")
5866
+ print(f"Error: {app_py_filename} not found at {app_py_path}")
5828
5867
  exit(1)
5868
+ notebook_dir = os.path.dirname(app_py_path)
5829
5869
 
5830
- # Make sure pipreqs is installed. Then
5831
- # 1. Create a requirements.in file
5832
- # 2. From the requirements.in file, generate the requirements.txt file with the canonical PyPI name of the packages
5833
- # and the versions as they exist on the user's terminal
5834
5870
  try:
5835
- # Run pipreqs on the directory containing app.py
5836
- notebook_dir = os.path.dirname(app_py_path)
5837
- generate_req_in_file = subprocess.run(
5838
- ['pipreqs', '--encoding=utf-8', '--savepath', 'requirements.in', '--force', notebook_dir],
5839
- capture_output=True,
5840
- text=True
5841
- )
5871
+ # Create a temporary directory and copy the app file into it
5872
+ with tempfile.TemporaryDirectory() as tmpdir:
5873
+ tmp_app_path = os.path.join(tmpdir, app_py_filename)
5874
+ shutil.copy(app_py_path, tmp_app_path)
5875
+
5876
+ # Run pipreqs on the temporary directory
5877
+ generate_req_in_file = subprocess.run(
5878
+ [
5879
+ 'pipreqs',
5880
+ '--encoding=utf-8',
5881
+ '--savepath', os.path.join(notebook_dir, 'requirements.in'),
5882
+ '--force',
5883
+ tmpdir
5884
+ ],
5885
+ capture_output=True,
5886
+ text=True
5887
+ )
5842
5888
 
5843
5889
  print("Log: ", generate_req_in_file.stderr)
5844
5890
 
@@ -5952,9 +5998,11 @@ __webpack_require__.r(__webpack_exports__);
5952
5998
  /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
5953
5999
  /* harmony import */ var _jupyterlab_ui_components__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @jupyterlab/ui-components */ "webpack/sharing/consume/default/@jupyterlab/ui-components");
5954
6000
  /* harmony import */ var _jupyterlab_ui_components__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_jupyterlab_ui_components__WEBPACK_IMPORTED_MODULE_1__);
5955
- /* harmony import */ var _AppDeploy_auth__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../AppDeploy/auth */ "./lib/Extensions/AppDeploy/auth.js");
5956
- /* harmony import */ var _ListAppsAPI__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./ListAppsAPI */ "./lib/Extensions/AppManager/ListAppsAPI.js");
6001
+ /* harmony import */ var _AppDeploy_auth__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../AppDeploy/auth */ "./lib/Extensions/AppDeploy/auth.js");
6002
+ /* harmony import */ var _ListAppsAPI__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./ListAppsAPI */ "./lib/Extensions/AppManager/ListAppsAPI.js");
6003
+ /* harmony import */ var _AppDeploy_authPopupUtils__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../AppDeploy/authPopupUtils */ "./lib/Extensions/AppDeploy/authPopupUtils.js");
5957
6004
  /* harmony import */ var _style_AppsList_css__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../../style/AppsList.css */ "./style/AppsList.css");
6005
+ /* harmony import */ var _style_button_css__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../../style/button.css */ "./style/button.css");
5958
6006
  /*
5959
6007
  * Copyright (c) Saga Inc.
5960
6008
  * Distributed under the terms of the GNU Affero General Public License v3.0 License.
@@ -5965,48 +6013,46 @@ __webpack_require__.r(__webpack_exports__);
5965
6013
 
5966
6014
 
5967
6015
 
6016
+
6017
+
5968
6018
  const AppsList = ({ appManagerService }) => {
5969
6019
  const [apps, setApps] = react__WEBPACK_IMPORTED_MODULE_0__.useState([]);
5970
6020
  const [loading, setLoading] = react__WEBPACK_IMPORTED_MODULE_0__.useState(true);
5971
6021
  const [error, setError] = react__WEBPACK_IMPORTED_MODULE_0__.useState(null);
5972
- // Fetch apps on component mount
5973
- react__WEBPACK_IMPORTED_MODULE_0__.useEffect(() => {
5974
- const loadApps = async () => {
5975
- try {
5976
- console.log('[AppsList] Starting to load apps...');
5977
- setLoading(true);
5978
- setError(null);
5979
- console.log('[AppsList] Calling fetchUserApps...');
5980
- const response = await (0,_ListAppsAPI__WEBPACK_IMPORTED_MODULE_3__.fetchUserApps)(appManagerService);
5981
- console.log('[AppsList] fetchUserApps response:', response);
5982
- if ((0,_ListAppsAPI__WEBPACK_IMPORTED_MODULE_3__.isGetAppsSuccess)(response)) {
5983
- setApps(response.apps);
5984
- }
5985
- else {
5986
- setError(response.errorMessage || 'Failed to load apps');
5987
- setApps([]);
5988
- }
6022
+ const refreshApps = async () => {
6023
+ try {
6024
+ console.log('[AppsList] Refreshing apps...');
6025
+ setLoading(true);
6026
+ setError(null);
6027
+ const response = await (0,_ListAppsAPI__WEBPACK_IMPORTED_MODULE_4__.fetchUserApps)(appManagerService);
6028
+ console.log('[AppsList] fetchUserApps response:', response);
6029
+ if ((0,_ListAppsAPI__WEBPACK_IMPORTED_MODULE_4__.isGetAppsSuccess)(response)) {
6030
+ setApps(response.apps);
5989
6031
  }
5990
- catch (err) {
5991
- console.error('[AppsList] Error loading apps:', err);
5992
- setError(err instanceof Error ? err.message : 'An unexpected error occurred');
6032
+ else {
6033
+ setError(response.errorMessage || 'Failed to load apps');
5993
6034
  setApps([]);
5994
6035
  }
5995
- finally {
5996
- setLoading(false);
5997
- }
5998
- };
5999
- console.log('[AppsList] Component mounted, calling loadApps...');
6000
- void loadApps();
6001
- }, [appManagerService]);
6002
- const refreshApps = async () => {
6003
- const response = await (0,_ListAppsAPI__WEBPACK_IMPORTED_MODULE_3__.fetchUserApps)(appManagerService);
6004
- if ((0,_ListAppsAPI__WEBPACK_IMPORTED_MODULE_3__.isGetAppsSuccess)(response)) {
6005
- setApps(response.apps);
6006
- setError(null);
6007
6036
  }
6008
- else {
6009
- setError(response.errorMessage || 'Failed to refresh apps');
6037
+ catch (err) {
6038
+ console.error('[AppsList] Error loading apps:', err);
6039
+ setError(err instanceof Error ? err.message : 'An unexpected error occurred');
6040
+ setApps([]);
6041
+ }
6042
+ finally {
6043
+ setLoading(false);
6044
+ }
6045
+ };
6046
+ react__WEBPACK_IMPORTED_MODULE_0__.useEffect(() => {
6047
+ void refreshApps();
6048
+ }, []);
6049
+ const handleLogin = async () => {
6050
+ try {
6051
+ await (0,_AppDeploy_authPopupUtils__WEBPACK_IMPORTED_MODULE_5__.showAuthenticationPopup)();
6052
+ await refreshApps();
6053
+ }
6054
+ catch (err) {
6055
+ console.warn('[AppsList] Login popup closed or failed:', err);
6010
6056
  }
6011
6057
  };
6012
6058
  const copyToClipboard = async (url, appName) => {
@@ -6047,15 +6093,26 @@ const AppsList = ({ appManagerService }) => {
6047
6093
  react__WEBPACK_IMPORTED_MODULE_0__.createElement("h3", { className: "apps-list-title" }, "Your Apps"),
6048
6094
  react__WEBPACK_IMPORTED_MODULE_0__.createElement("div", { className: "apps-list-actions" },
6049
6095
  react__WEBPACK_IMPORTED_MODULE_0__.createElement("button", { onClick: refreshApps, disabled: loading, className: "apps-list-button", title: "Refresh apps" }, loading ? 'Loading...' : 'Refresh'),
6050
- react__WEBPACK_IMPORTED_MODULE_0__.createElement("button", { onClick: () => {
6096
+ react__WEBPACK_IMPORTED_MODULE_0__.createElement("button", { onClick: async () => {
6051
6097
  console.log('Logout clicked');
6052
- void (0,_AppDeploy_auth__WEBPACK_IMPORTED_MODULE_4__.logoutAndClearJWTTokens)();
6098
+ try {
6099
+ await (0,_AppDeploy_auth__WEBPACK_IMPORTED_MODULE_6__.logoutAndClearJWTTokens)();
6100
+ }
6101
+ catch (err) {
6102
+ console.error('[AppsList] Error during logout:', err);
6103
+ }
6104
+ finally {
6105
+ await refreshApps();
6106
+ }
6053
6107
  }, className: "apps-list-button", title: "Logout" }, "Logout"))),
6054
- 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" },
6055
- "Error: ",
6056
- error,
6057
- react__WEBPACK_IMPORTED_MODULE_0__.createElement("div", { className: "apps-list-error-actions" },
6058
- react__WEBPACK_IMPORTED_MODULE_0__.createElement("button", { onClick: refreshApps, className: "apps-list-button primary" }, "Try Again")))) : apps.length === 0 ? (react__WEBPACK_IMPORTED_MODULE_0__.createElement("div", { className: "apps-list-empty" }, "No apps deployed yet")) : (react__WEBPACK_IMPORTED_MODULE_0__.createElement("div", null, apps.map((app) => (react__WEBPACK_IMPORTED_MODULE_0__.createElement("div", { key: app.name, className: "app-item" },
6108
+ react__WEBPACK_IMPORTED_MODULE_0__.createElement("div", { className: "apps-list-content" }, loading ? (react__WEBPACK_IMPORTED_MODULE_0__.createElement("div", { className: "apps-list-loading" }, "Loading apps...")) : error ? (error === 'User not authenticated' ? (react__WEBPACK_IMPORTED_MODULE_0__.createElement("div", { className: "apps-list-auth-message" },
6109
+ react__WEBPACK_IMPORTED_MODULE_0__.createElement("div", { className: "apps-list-auth-text" }, "User not authenticated"),
6110
+ react__WEBPACK_IMPORTED_MODULE_0__.createElement("button", { onClick: handleLogin, className: "button-base button-purple apps-list-auth-login-button" }, "Login"))) : (react__WEBPACK_IMPORTED_MODULE_0__.createElement("div", { className: "apps-list-error" },
6111
+ react__WEBPACK_IMPORTED_MODULE_0__.createElement(react__WEBPACK_IMPORTED_MODULE_0__.Fragment, null,
6112
+ "Error: ",
6113
+ error,
6114
+ react__WEBPACK_IMPORTED_MODULE_0__.createElement("div", { className: "apps-list-error-actions" },
6115
+ react__WEBPACK_IMPORTED_MODULE_0__.createElement("button", { onClick: refreshApps, className: "apps-list-button primary" }, "Try Again")))))) : apps.length === 0 ? (react__WEBPACK_IMPORTED_MODULE_0__.createElement("div", { className: "apps-list-empty" }, "No apps deployed yet")) : (react__WEBPACK_IMPORTED_MODULE_0__.createElement("div", null, apps.map((app) => (react__WEBPACK_IMPORTED_MODULE_0__.createElement("div", { key: app.name, className: "app-item" },
6059
6116
  react__WEBPACK_IMPORTED_MODULE_0__.createElement("div", { className: "app-item-header" },
6060
6117
  react__WEBPACK_IMPORTED_MODULE_0__.createElement("div", { className: "app-item-content" },
6061
6118
  react__WEBPACK_IMPORTED_MODULE_0__.createElement("div", { className: "app-item-name" }, app.name),
@@ -6068,7 +6125,7 @@ const AppsList = ({ appManagerService }) => {
6068
6125
  react__WEBPACK_IMPORTED_MODULE_0__.createElement("div", { className: "app-item-url-container" },
6069
6126
  react__WEBPACK_IMPORTED_MODULE_0__.createElement("div", { className: "app-item-url" }, app.url),
6070
6127
  react__WEBPACK_IMPORTED_MODULE_0__.createElement("button", { onClick: () => copyToClipboard(app.url, app.name), className: "app-item-copy-button", title: `Copy URL for ${app.name}` },
6071
- react__WEBPACK_IMPORTED_MODULE_0__.createElement(_jupyterlab_ui_components__WEBPACK_IMPORTED_MODULE_1__.copyIcon.react, { width: "14px", height: "14px", fill: "var(--jp-ui-font-color2)" }))))))))));
6128
+ react__WEBPACK_IMPORTED_MODULE_0__.createElement(_jupyterlab_ui_components__WEBPACK_IMPORTED_MODULE_1__.copyIcon.react, { width: "14px", height: "14px", fill: "var(--jp-ui-font-color2)" })))))))))));
6072
6129
  };
6073
6130
 
6074
6131
 
@@ -10233,9 +10290,13 @@ __webpack_require__.r(__webpack_exports__);
10233
10290
  /* harmony export */ });
10234
10291
  /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ "webpack/sharing/consume/default/react");
10235
10292
  /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
10236
- /* harmony import */ var _style_ModelSelector_css__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../style/ModelSelector.css */ "./style/ModelSelector.css");
10237
- /* harmony import */ var _icons_NucleausIcon__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../icons/NucleausIcon */ "./lib/icons/NucleausIcon.js");
10238
- /* harmony import */ var _utils_models__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../utils/models */ "./lib/utils/models.js");
10293
+ /* harmony import */ var react_dom__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! react-dom */ "webpack/sharing/consume/default/react-dom");
10294
+ /* harmony import */ var react_dom__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(react_dom__WEBPACK_IMPORTED_MODULE_1__);
10295
+ /* harmony import */ var _style_ModelSelector_css__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../style/ModelSelector.css */ "./style/ModelSelector.css");
10296
+ /* harmony import */ var _icons_NucleausIcon__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../icons/NucleausIcon */ "./lib/icons/NucleausIcon.js");
10297
+ /* harmony import */ var _icons_BrainIcon__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../icons/BrainIcon */ "./lib/icons/BrainIcon.js");
10298
+ /* harmony import */ var _icons_LightningIcon__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../icons/LightningIcon */ "./lib/icons/LightningIcon.js");
10299
+ /* harmony import */ var _utils_models__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../utils/models */ "./lib/utils/models.js");
10239
10300
  /*
10240
10301
  * Copyright (c) Saga Inc.
10241
10302
  * Distributed under the terms of the GNU Affero General Public License v3.0 License.
@@ -10244,17 +10305,94 @@ __webpack_require__.r(__webpack_exports__);
10244
10305
 
10245
10306
 
10246
10307
 
10308
+
10309
+
10310
+
10247
10311
  const MODEL_MAPPINGS = [
10248
- { displayName: 'GPT 4.1', fullName: 'gpt-4.1' },
10249
- { displayName: _utils_models__WEBPACK_IMPORTED_MODULE_2__.CLAUDE_SONNET_DISPLAY_NAME, fullName: _utils_models__WEBPACK_IMPORTED_MODULE_2__.CLAUDE_SONNET_MODEL_NAME },
10250
- { displayName: 'Gemini 2.5 Pro', fullName: 'gemini-2.5-pro-preview-03-25' }
10312
+ {
10313
+ displayName: 'GPT 4.1',
10314
+ fullName: 'gpt-4.1',
10315
+ type: 'smart',
10316
+ goodFor: [
10317
+ 'Complex data analysis',
10318
+ 'Advanced debugging',
10319
+ 'Statistical analysis and modeling',
10320
+ 'Multi-step data workflows'
10321
+ ],
10322
+ provider: 'OpenAI',
10323
+ tokenLimit: '1M',
10324
+ speed: 'Medium',
10325
+ complexityHandling: 'High'
10326
+ },
10327
+ {
10328
+ displayName: _utils_models__WEBPACK_IMPORTED_MODULE_3__.CLAUDE_HAIKU_DISPLAY_NAME,
10329
+ fullName: _utils_models__WEBPACK_IMPORTED_MODULE_3__.CLAUDE_HAIKU_MODEL_NAME,
10330
+ type: 'fast',
10331
+ goodFor: [
10332
+ 'Quick data exploration',
10333
+ 'Pandas operations',
10334
+ 'Basic data cleaning',
10335
+ 'Fast code iterations'
10336
+ ],
10337
+ provider: 'Anthropic',
10338
+ tokenLimit: '200K',
10339
+ speed: 'Fast',
10340
+ complexityHandling: 'Medium'
10341
+ },
10342
+ {
10343
+ displayName: _utils_models__WEBPACK_IMPORTED_MODULE_3__.CLAUDE_SONNET_DISPLAY_NAME,
10344
+ fullName: _utils_models__WEBPACK_IMPORTED_MODULE_3__.CLAUDE_SONNET_MODEL_NAME,
10345
+ type: 'smart',
10346
+ goodFor: [
10347
+ 'Complex data analysis',
10348
+ 'Advanced debugging',
10349
+ 'Statistical analysis and modeling',
10350
+ 'Multi-step data workflows'
10351
+ ],
10352
+ provider: 'Anthropic',
10353
+ tokenLimit: '1M',
10354
+ speed: 'Medium',
10355
+ complexityHandling: 'High'
10356
+ },
10357
+ {
10358
+ displayName: 'Gemini 2.5 Pro',
10359
+ fullName: 'gemini-2.5-pro-preview-03-25',
10360
+ type: 'smart',
10361
+ goodFor: [
10362
+ 'Complex data analysis',
10363
+ 'Advanced debugging',
10364
+ 'Statistical analysis and modeling',
10365
+ 'Multi-step data workflows'
10366
+ ],
10367
+ provider: 'Google',
10368
+ tokenLimit: '1M',
10369
+ speed: 'Medium',
10370
+ complexityHandling: 'High'
10371
+ },
10372
+ {
10373
+ displayName: 'Gemini 3 Pro',
10374
+ fullName: 'gemini-3-pro-preview',
10375
+ type: 'smart',
10376
+ goodFor: [
10377
+ 'Most complex data analysis',
10378
+ 'Advanced debugging',
10379
+ 'Statistical analysis and modeling',
10380
+ 'Multi-step data workflows'
10381
+ ],
10382
+ provider: 'Google',
10383
+ tokenLimit: '1M',
10384
+ speed: 'Slow',
10385
+ complexityHandling: 'High'
10386
+ }
10251
10387
  ];
10252
10388
  const ALL_MODEL_DISPLAY_NAMES = MODEL_MAPPINGS.map(mapping => mapping.displayName);
10253
10389
  // Maximum length for displayed model name before truncating
10254
- const DEFAULT_MODEL = _utils_models__WEBPACK_IMPORTED_MODULE_2__.CLAUDE_SONNET_DISPLAY_NAME;
10390
+ const DEFAULT_MODEL = _utils_models__WEBPACK_IMPORTED_MODULE_3__.CLAUDE_SONNET_DISPLAY_NAME;
10255
10391
  const ModelSelector = ({ onConfigChange }) => {
10256
10392
  const [selectedModel, setSelectedModel] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(DEFAULT_MODEL);
10257
10393
  const [isOpen, setIsOpen] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(false);
10394
+ const [hoveredModel, setHoveredModel] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(null);
10395
+ const dropdownRef = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(null);
10258
10396
  // Load config from localStorage on component mount and notify parent
10259
10397
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
10260
10398
  var _a;
@@ -10307,17 +10445,60 @@ const ModelSelector = ({ onConfigChange }) => {
10307
10445
  document.removeEventListener('mousedown', handleClickOutside);
10308
10446
  };
10309
10447
  }, []);
10448
+ // Set CSS custom properties for tooltip positioning
10449
+ (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
10450
+ if (isOpen && dropdownRef.current) {
10451
+ const rect = dropdownRef.current.getBoundingClientRect();
10452
+ // Align bottom of tooltip with bottom of dropdown (which is at rect.top)
10453
+ // Tooltip height is approximately 180px
10454
+ const tooltipHeight = 180;
10455
+ const tooltipBottom = rect.top;
10456
+ const tooltipTop = tooltipBottom - tooltipHeight;
10457
+ document.documentElement.style.setProperty('--tooltip-top', `${tooltipTop - 32}px`);
10458
+ document.documentElement.style.setProperty('--tooltip-left', `${rect.left + 160}px`);
10459
+ }
10460
+ }, [isOpen]);
10310
10461
  return (react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { className: "model-selector" },
10311
- react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { className: `model-selector-dropdown`, onClick: () => setIsOpen(!isOpen), title: selectedModel, "data-testid": "model-selector" },
10462
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { ref: dropdownRef, className: `model-selector-dropdown`, onClick: () => setIsOpen(!isOpen), "data-testid": "model-selector" },
10312
10463
  react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { className: "selected-model" },
10313
10464
  react__WEBPACK_IMPORTED_MODULE_0___default().createElement("span", { className: "model-icon" },
10314
- react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_icons_NucleausIcon__WEBPACK_IMPORTED_MODULE_3__["default"], { height: 10, width: 10 })),
10465
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_icons_NucleausIcon__WEBPACK_IMPORTED_MODULE_4__["default"], { height: 10, width: 10 })),
10315
10466
  react__WEBPACK_IMPORTED_MODULE_0___default().createElement("span", { className: "model-name" }, selectedModel),
10316
10467
  react__WEBPACK_IMPORTED_MODULE_0___default().createElement("span", { className: "dropdown-arrow" }, "\u25BC")),
10317
- isOpen && (react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { className: `model-options dropup`, style: { minWidth: '150px' } }, ALL_MODEL_DISPLAY_NAMES.map(model => (react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { key: model, className: `model-option ${model === selectedModel ? 'selected' : ''}`, onClick: (e) => {
10318
- e.stopPropagation();
10319
- handleModelChange(model);
10320
- }, title: model, "data-testid": "model-option" }, model))))))));
10468
+ isOpen && (react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { className: `model-options dropup`, style: { minWidth: '150px' }, onMouseLeave: () => setHoveredModel(null) }, ALL_MODEL_DISPLAY_NAMES.map(model => {
10469
+ const modelMapping = MODEL_MAPPINGS.find(m => m.displayName === model);
10470
+ return (react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { key: model, className: `model-option ${model === selectedModel ? 'selected' : ''}`, onClick: (e) => {
10471
+ e.stopPropagation();
10472
+ handleModelChange(model);
10473
+ }, onMouseEnter: () => setHoveredModel(modelMapping || null), "data-testid": "model-option" },
10474
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement("span", { className: "model-option-name" }, model),
10475
+ (modelMapping === null || modelMapping === void 0 ? void 0 : modelMapping.type) === 'smart' && (react__WEBPACK_IMPORTED_MODULE_0___default().createElement("span", { className: "model-type-icon" },
10476
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_icons_BrainIcon__WEBPACK_IMPORTED_MODULE_5__["default"], { height: 12, width: 12 }))),
10477
+ (modelMapping === null || modelMapping === void 0 ? void 0 : modelMapping.type) === 'fast' && (react__WEBPACK_IMPORTED_MODULE_0___default().createElement("span", { className: "model-type-icon" },
10478
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_icons_LightningIcon__WEBPACK_IMPORTED_MODULE_6__["default"], { height: 12, width: 12 })))));
10479
+ })))),
10480
+ isOpen && hoveredModel && react_dom__WEBPACK_IMPORTED_MODULE_1___default().createPortal(react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { className: "model-tooltip" },
10481
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { className: "model-tooltip-content" },
10482
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { className: "model-tooltip-header" },
10483
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { className: "model-tooltip-title-row" },
10484
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement("span", { className: "model-tooltip-title-icon" }, hoveredModel.type === 'smart' ? (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_icons_BrainIcon__WEBPACK_IMPORTED_MODULE_5__["default"], { height: 16, width: 16 })) : (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_icons_LightningIcon__WEBPACK_IMPORTED_MODULE_6__["default"], { height: 16, width: 16 }))),
10485
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { className: "model-tooltip-title" }, hoveredModel.displayName)),
10486
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { className: "model-tooltip-metadata" },
10487
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { className: "model-tooltip-metadata-item" },
10488
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement("span", { className: "model-tooltip-metadata-label" }, "Provider:"),
10489
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement("span", { className: "model-tooltip-metadata-value" }, hoveredModel.provider)),
10490
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { className: "model-tooltip-metadata-item" },
10491
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement("span", { className: "model-tooltip-metadata-label" }, "Tokens:"),
10492
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement("span", { className: "model-tooltip-metadata-value" }, hoveredModel.tokenLimit)),
10493
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { className: "model-tooltip-metadata-item" },
10494
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement("span", { className: "model-tooltip-metadata-label" }, "Speed:"),
10495
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement("span", { className: "model-tooltip-metadata-value" }, hoveredModel.speed)),
10496
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { className: "model-tooltip-metadata-item" },
10497
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement("span", { className: "model-tooltip-metadata-label" }, "Complexity:"),
10498
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement("span", { className: "model-tooltip-metadata-value" }, hoveredModel.complexityHandling)))),
10499
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { className: "model-tooltip-section" },
10500
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { className: "model-tooltip-section-label" }, "Good For:"),
10501
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement("ul", { className: "model-tooltip-bullet-list" }, hoveredModel.goodFor.map((item, index) => (react__WEBPACK_IMPORTED_MODULE_0___default().createElement("li", { key: index, className: "model-tooltip-bullet-item" }, item))))))), document.body)));
10321
10502
  };
10322
10503
  /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (ModelSelector);
10323
10504
 
@@ -10703,6 +10884,31 @@ const AppIcon = () => {
10703
10884
  /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (AppIcon);
10704
10885
 
10705
10886
 
10887
+ /***/ }),
10888
+
10889
+ /***/ "./lib/icons/BrainIcon.js":
10890
+ /*!********************************!*\
10891
+ !*** ./lib/icons/BrainIcon.js ***!
10892
+ \********************************/
10893
+ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
10894
+
10895
+ __webpack_require__.r(__webpack_exports__);
10896
+ /* harmony export */ __webpack_require__.d(__webpack_exports__, {
10897
+ /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
10898
+ /* harmony export */ });
10899
+ /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ "webpack/sharing/consume/default/react");
10900
+ /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
10901
+ /*
10902
+ * Copyright (c) Saga Inc.
10903
+ * Distributed under the terms of the GNU Affero General Public License v3.0 License.
10904
+ */
10905
+
10906
+ const BrainIcon = ({ height = 14, width = 14, fill = 'currentColor' }) => (react__WEBPACK_IMPORTED_MODULE_0___default().createElement("svg", { width: width, height: height, viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg", stroke: fill, strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" },
10907
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement("path", { d: "M12 5a3 3 0 1 0-5.997.142 4 4 0 0 0-2.526 5.77 4 4 0 0 0 .556 6.588 4 4 0 0 0 7.636 2.106 3.2 3.2 0 0 0 .164-.546c.628-.5 1.2-1.1 1.7-1.8a3.2 3.2 0 0 0 .164-.546 4 4 0 0 0 7.636-2.106 4 4 0 0 0 .556-6.588 4 4 0 0 0-2.526-5.77A3 3 0 1 0 12 5Z" }),
10908
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement("path", { d: "M8 12h.01M12 12h.01M16 12h.01M8 8h.01M12 8h.01M16 8h.01M8 16h.01M12 16h.01M16 16h.01" })));
10909
+ /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (BrainIcon);
10910
+
10911
+
10706
10912
  /***/ }),
10707
10913
 
10708
10914
  /***/ "./lib/icons/CodeIcon.js":
@@ -10830,6 +11036,30 @@ const ExpandIcon = ({ isExpanded }) => (react__WEBPACK_IMPORTED_MODULE_0___defau
10830
11036
  /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (ExpandIcon);
10831
11037
 
10832
11038
 
11039
+ /***/ }),
11040
+
11041
+ /***/ "./lib/icons/LightningIcon.js":
11042
+ /*!************************************!*\
11043
+ !*** ./lib/icons/LightningIcon.js ***!
11044
+ \************************************/
11045
+ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
11046
+
11047
+ __webpack_require__.r(__webpack_exports__);
11048
+ /* harmony export */ __webpack_require__.d(__webpack_exports__, {
11049
+ /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
11050
+ /* harmony export */ });
11051
+ /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ "webpack/sharing/consume/default/react");
11052
+ /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
11053
+ /*
11054
+ * Copyright (c) Saga Inc.
11055
+ * Distributed under the terms of the GNU Affero General Public License v3.0 License.
11056
+ */
11057
+
11058
+ const LightningIcon = ({ height = 14, width = 14, fill = 'currentColor' }) => (react__WEBPACK_IMPORTED_MODULE_0___default().createElement("svg", { width: width, height: height, viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg", stroke: fill, strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" },
11059
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement("path", { d: "M13 2L3 14h9l-1 8 10-12h-9l1-8z" })));
11060
+ /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (LightningIcon);
11061
+
11062
+
10833
11063
  /***/ }),
10834
11064
 
10835
11065
  /***/ "./lib/icons/MagicWand.js":
@@ -12679,6 +12909,8 @@ const uploadFileToBackend = async (file, notebookTracker, onFileUploaded) => {
12679
12909
 
12680
12910
  __webpack_require__.r(__webpack_exports__);
12681
12911
  /* harmony export */ __webpack_require__.d(__webpack_exports__, {
12912
+ /* harmony export */ CLAUDE_HAIKU_DISPLAY_NAME: () => (/* binding */ CLAUDE_HAIKU_DISPLAY_NAME),
12913
+ /* harmony export */ CLAUDE_HAIKU_MODEL_NAME: () => (/* binding */ CLAUDE_HAIKU_MODEL_NAME),
12682
12914
  /* harmony export */ CLAUDE_SONNET_DISPLAY_NAME: () => (/* binding */ CLAUDE_SONNET_DISPLAY_NAME),
12683
12915
  /* harmony export */ CLAUDE_SONNET_MODEL_NAME: () => (/* binding */ CLAUDE_SONNET_MODEL_NAME),
12684
12916
  /* harmony export */ GPT_4_1_DISPLAY_NAME: () => (/* binding */ GPT_4_1_DISPLAY_NAME),
@@ -12688,8 +12920,10 @@ __webpack_require__.r(__webpack_exports__);
12688
12920
  * Copyright (c) Saga Inc.
12689
12921
  * Distributed under the terms of the GNU Affero General Public License v3.0 License.
12690
12922
  */
12691
- const CLAUDE_SONNET_DISPLAY_NAME = 'Claude 4.5 Sonnet';
12923
+ const CLAUDE_SONNET_DISPLAY_NAME = 'Claude Sonnet 4.5';
12692
12924
  const CLAUDE_SONNET_MODEL_NAME = 'claude-sonnet-4-5-20250929';
12925
+ const CLAUDE_HAIKU_DISPLAY_NAME = 'Claude Haiku 4.5';
12926
+ const CLAUDE_HAIKU_MODEL_NAME = 'claude-haiku-4-5-20251001';
12693
12927
  const GPT_4_1_DISPLAY_NAME = 'GPT 4.1';
12694
12928
  const GPT_4_1_MODEL_NAME = 'gpt-4.1';
12695
12929
 
@@ -14442,25 +14676,27 @@ ___CSS_LOADER_EXPORT___.push([module.id, `/*
14442
14676
  font-size: 12px;
14443
14677
  margin-bottom: 4px;
14444
14678
  display: flex;
14445
- flex-direction: column;
14446
- gap: 8px;
14447
- align-items: start;
14679
+ flex-direction: row;
14680
+ gap: 16px;
14681
+ align-items: center;
14448
14682
  }
14449
14683
 
14450
14684
  .agent-change-count {
14451
14685
  display: inline-flex;
14452
- align-items: center;
14686
+ align-items: baseline;
14687
+ gap: 4px;
14453
14688
  }
14454
14689
 
14455
14690
  .agent-change-count-number {
14456
- font-weight: 500;
14691
+ font-weight: bold;
14692
+ font-size: 14px;
14457
14693
  display: inline-block;
14458
- min-width: 24px;
14459
14694
  text-align: left;
14460
14695
  }
14461
14696
 
14462
14697
  .agent-change-count-text {
14463
14698
  color: var(--muted-text-color);
14699
+ font-size: 11px;
14464
14700
  }
14465
14701
 
14466
14702
  .agent-change-count-added {
@@ -14497,7 +14733,7 @@ ___CSS_LOADER_EXPORT___.push([module.id, `/*
14497
14733
  align-items: center;
14498
14734
  }
14499
14735
 
14500
- `, "",{"version":3,"sources":["webpack://./style/AgentChangeControls.css"],"names":[],"mappings":"AAAA;;;EAGE;;AAEF;IACI,eAAe;IACf,kBAAkB;IAClB,aAAa;IACb,sBAAsB;IACtB,QAAQ;IACR,kBAAkB;AACtB;;AAEA;IACI,oBAAoB;IACpB,mBAAmB;AACvB;;AAEA;IACI,gBAAgB;IAChB,qBAAqB;IACrB,eAAe;IACf,gBAAgB;AACpB;;AAEA;IACI,8BAA8B;AAClC;;AAEA;IACI,uBAAuB;AAC3B;;AAEA;IACI,wBAAwB;AAC5B;;AAEA;IACI,qBAAqB;AACzB;;AAEA;IACI,8BAA8B;IAC9B,aAAa;AACjB;;AAEA;IACI,eAAe;IACf,8BAA8B;AAClC;;AAEA;IACI,aAAa;IACb,sBAAsB;IACtB,QAAQ;AACZ;;AAEA;IACI,aAAa;IACb,QAAQ;IACR,mBAAmB;AACvB","sourcesContent":["/*\n * Copyright (c) Saga Inc.\n * Distributed under the terms of the GNU Affero General Public License v3.0 License.\n */\n\n.agent-change-counts {\n font-size: 12px;\n margin-bottom: 4px;\n display: flex;\n flex-direction: column;\n gap: 8px;\n align-items: start;\n}\n\n.agent-change-count {\n display: inline-flex;\n align-items: center;\n}\n\n.agent-change-count-number {\n font-weight: 500;\n display: inline-block;\n min-width: 24px;\n text-align: left;\n}\n\n.agent-change-count-text {\n color: var(--muted-text-color);\n}\n\n.agent-change-count-added {\n color: var(--green-700);\n}\n\n.agent-change-count-modified {\n color: var(--yellow-600);\n}\n\n.agent-change-count-removed {\n color: var(--red-700);\n}\n\n.agent-change-count-separator {\n color: var(--muted-text-color);\n margin: 0 4px;\n}\n\n.agent-review-progress {\n font-size: 12px;\n color: var(--muted-text-color);\n}\n\n.agent-change-controls-container {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.agent-change-controls-buttons {\n display: flex;\n gap: 8px;\n align-items: center;\n}\n\n"],"sourceRoot":""}]);
14736
+ `, "",{"version":3,"sources":["webpack://./style/AgentChangeControls.css"],"names":[],"mappings":"AAAA;;;EAGE;;AAEF;IACI,eAAe;IACf,kBAAkB;IAClB,aAAa;IACb,mBAAmB;IACnB,SAAS;IACT,mBAAmB;AACvB;;AAEA;IACI,oBAAoB;IACpB,qBAAqB;IACrB,QAAQ;AACZ;;AAEA;IACI,iBAAiB;IACjB,eAAe;IACf,qBAAqB;IACrB,gBAAgB;AACpB;;AAEA;IACI,8BAA8B;IAC9B,eAAe;AACnB;;AAEA;IACI,uBAAuB;AAC3B;;AAEA;IACI,wBAAwB;AAC5B;;AAEA;IACI,qBAAqB;AACzB;;AAEA;IACI,8BAA8B;IAC9B,aAAa;AACjB;;AAEA;IACI,eAAe;IACf,8BAA8B;AAClC;;AAEA;IACI,aAAa;IACb,sBAAsB;IACtB,QAAQ;AACZ;;AAEA;IACI,aAAa;IACb,QAAQ;IACR,mBAAmB;AACvB","sourcesContent":["/*\n * Copyright (c) Saga Inc.\n * Distributed under the terms of the GNU Affero General Public License v3.0 License.\n */\n\n.agent-change-counts {\n font-size: 12px;\n margin-bottom: 4px;\n display: flex;\n flex-direction: row;\n gap: 16px;\n align-items: center;\n}\n\n.agent-change-count {\n display: inline-flex;\n align-items: baseline;\n gap: 4px;\n}\n\n.agent-change-count-number {\n font-weight: bold;\n font-size: 14px;\n display: inline-block;\n text-align: left;\n}\n\n.agent-change-count-text {\n color: var(--muted-text-color);\n font-size: 11px;\n}\n\n.agent-change-count-added {\n color: var(--green-700);\n}\n\n.agent-change-count-modified {\n color: var(--yellow-600);\n}\n\n.agent-change-count-removed {\n color: var(--red-700);\n}\n\n.agent-change-count-separator {\n color: var(--muted-text-color);\n margin: 0 4px;\n}\n\n.agent-review-progress {\n font-size: 12px;\n color: var(--muted-text-color);\n}\n\n.agent-change-controls-container {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.agent-change-controls-buttons {\n display: flex;\n gap: 8px;\n align-items: center;\n}\n\n"],"sourceRoot":""}]);
14501
14737
  // Exports
14502
14738
  /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);
14503
14739
 
@@ -14871,16 +15107,28 @@ ___CSS_LOADER_EXPORT___.push([module.id, `/*
14871
15107
 
14872
15108
  /* apps-list.css */
14873
15109
  .apps-list-container {
14874
- padding: 16px;
15110
+ display: flex;
15111
+ flex-direction: column;
15112
+ height: 100%;
14875
15113
  font-size: 13px;
14876
15114
  font-family: var(--jp-ui-font-family);
15115
+ overflow: hidden;
14877
15116
  }
14878
15117
 
14879
15118
  .apps-list-header {
14880
15119
  display: flex;
14881
15120
  justify-content: space-between;
14882
15121
  align-items: center;
14883
- margin-bottom: 16px;
15122
+ padding: 16px;
15123
+ flex-shrink: 0;
15124
+ border-bottom: 1px solid var(--jp-border-color2);
15125
+ }
15126
+
15127
+ .apps-list-content {
15128
+ flex: 1;
15129
+ overflow-y: auto;
15130
+ padding: 16px;
15131
+ min-height: 0;
14884
15132
  }
14885
15133
 
14886
15134
  .apps-list-title {
@@ -14940,6 +15188,30 @@ ___CSS_LOADER_EXPORT___.push([module.id, `/*
14940
15188
  margin-top: 8px;
14941
15189
  }
14942
15190
 
15191
+ .apps-list-auth-message {
15192
+ color: var(--jp-ui-font-color1);
15193
+ background-color: var(--jp-layout-color0);
15194
+ border: 1px solid var(--jp-border-color2);
15195
+ border-radius: 4px;
15196
+ padding: 24px 16px;
15197
+ text-align: center;
15198
+ display: flex;
15199
+ flex-direction: column;
15200
+ align-items: center;
15201
+ gap: 12px;
15202
+ }
15203
+
15204
+ .apps-list-auth-text {
15205
+ font-size: 14px;
15206
+ font-weight: bold;
15207
+ font-family: var(--jp-ui-font-family);
15208
+ }
15209
+
15210
+ .apps-list-auth-login-button {
15211
+ font-size: 13px;
15212
+ min-width: 96px;
15213
+ }
15214
+
14943
15215
  .apps-list-empty {
14944
15216
  color: var(--jp-ui-font-color2);
14945
15217
  text-align: center;
@@ -15029,7 +15301,7 @@ ___CSS_LOADER_EXPORT___.push([module.id, `/*
15029
15301
  .app-item-copy-button:hover {
15030
15302
  background-color: var(--jp-layout-color2);
15031
15303
  }
15032
- `, "",{"version":3,"sources":["webpack://./style/AppsList.css"],"names":[],"mappings":"AAAA;;;EAGE;;AAEF,kBAAkB;AAClB;EACE,aAAa;EACb,eAAe;EACf,qCAAqC;AACvC;;AAEA;EACE,aAAa;EACb,8BAA8B;EAC9B,mBAAmB;EACnB,mBAAmB;AACrB;;AAEA;EACE,SAAS;EACT,eAAe;EACf,iBAAiB;EACjB,+BAA+B;AACjC;;AAEA;EACE,aAAa;EACb,QAAQ;AACV;;AAEA;EACE,gBAAgB;EAChB,eAAe;EACf,6BAA6B;EAC7B,+BAA+B;EAC/B,yCAAyC;EACzC,kBAAkB;EAClB,eAAe;EACf,mBAAmB;EACnB,sCAAsC;AACxC;;AAEA;EACE,yCAAyC;AAC3C;;AAEA;EACE,mBAAmB;AACrB;;AAEA;EACE,wCAAwC;EACxC,YAAY;EACZ,YAAY;AACd;;AAEA;EACE,+BAA+B;EAC/B,kBAAkB;EAClB,eAAe;AACjB;;AAEA;EACE,cAAc;EACd,kBAAkB;EAClB,eAAe;EACf,yCAAyC;EACzC,yBAAyB;EACzB,kBAAkB;AACpB;;AAEA;EACE,eAAe;AACjB;;AAEA;EACE,+BAA+B;EAC/B,kBAAkB;EAClB,eAAe;AACjB;;AAEA;EACE,yCAAyC;EACzC,kBAAkB;EAClB,aAAa;EACb,kBAAkB;EAClB,yCAAyC;AAC3C;;AAEA;EACE,aAAa;EACb,8BAA8B;EAC9B,uBAAuB;EACvB,kBAAkB;AACpB;;AAEA;EACE,OAAO;AACT;;AAEA;EACE,iBAAiB;EACjB,+BAA+B;EAC/B,kBAAkB;AACpB;;AAEA;EACE,aAAa;EACb,mBAAmB;EACnB,kBAAkB;AACpB;;AAEA;EACE,qBAAqB;EACrB,UAAU;EACV,WAAW;EACX,kBAAkB;EAClB,iBAAiB;AACnB;;AAEA;EACE,+BAA+B;EAC/B,eAAe;AACjB;;AAEA;EACE,+BAA+B;EAC/B,eAAe;AACjB;;AAEA;EACE,aAAa;EACb,mBAAmB;EACnB,yCAAyC;EACzC,yCAAyC;EACzC,kBAAkB;EAClB,gBAAgB;AAClB;;AAEA;EACE,OAAO;EACP,+BAA+B;EAC/B,eAAe;EACf,gBAAgB;EAChB,uBAAuB;EACvB,mBAAmB;EACnB,uCAAuC;AACzC;;AAEA;EACE,YAAY;EACZ,uBAAuB;EACvB,eAAe;EACf,YAAY;EACZ,aAAa;EACb,mBAAmB;EACnB,uBAAuB;EACvB,gBAAgB;EAChB,kBAAkB;AACpB;;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/* apps-list.css */\n.apps-list-container {\n padding: 16px;\n font-size: 13px;\n font-family: var(--jp-ui-font-family);\n}\n\n.apps-list-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 16px;\n}\n\n.apps-list-title {\n margin: 0;\n font-size: 14px;\n font-weight: bold;\n color: var(--jp-ui-font-color1);\n}\n\n.apps-list-actions {\n display: flex;\n gap: 8px;\n}\n\n.apps-list-button {\n padding: 4px 8px;\n font-size: 11px;\n background-color: transparent;\n color: var(--jp-ui-font-color2);\n border: 1px solid var(--jp-border-color2);\n border-radius: 3px;\n cursor: pointer;\n font-weight: normal;\n transition: background-color 0.2s ease;\n}\n\n.apps-list-button:hover {\n background-color: var(--jp-layout-color2);\n}\n\n.apps-list-button:disabled {\n cursor: not-allowed;\n}\n\n.apps-list-button.primary {\n background-color: var(--jp-brand-color1);\n color: white;\n border: none;\n}\n\n.apps-list-loading {\n color: var(--jp-ui-font-color2);\n text-align: center;\n padding: 20px 0;\n}\n\n.apps-list-error {\n color: #f44336;\n text-align: center;\n padding: 20px 0;\n background-color: var(--jp-layout-color1);\n border: 1px solid #f44336;\n border-radius: 4px;\n}\n\n.apps-list-error-actions {\n margin-top: 8px;\n}\n\n.apps-list-empty {\n color: var(--jp-ui-font-color2);\n text-align: center;\n padding: 20px 0;\n}\n\n.app-item {\n border: 1px solid var(--jp-border-color1);\n border-radius: 4px;\n padding: 12px;\n margin-bottom: 8px;\n background-color: var(--jp-layout-color0);\n}\n\n.app-item-header {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n margin-bottom: 8px;\n}\n\n.app-item-content {\n flex: 1;\n}\n\n.app-item-name {\n font-weight: bold;\n color: var(--jp-ui-font-color1);\n margin-bottom: 4px;\n}\n\n.app-item-status-container {\n display: flex;\n align-items: center;\n margin-bottom: 4px;\n}\n\n.app-item-status-indicator {\n display: inline-block;\n width: 8px;\n height: 8px;\n border-radius: 50%;\n margin-right: 6px;\n}\n\n.app-item-status-text {\n color: var(--jp-ui-font-color2);\n font-size: 12px;\n}\n\n.app-item-last-deployed {\n color: var(--jp-ui-font-color2);\n font-size: 11px;\n}\n\n.app-item-url-container {\n display: flex;\n align-items: center;\n background-color: var(--jp-layout-color1);\n border: 1px solid var(--jp-border-color2);\n border-radius: 3px;\n padding: 6px 8px;\n}\n\n.app-item-url {\n flex: 1;\n color: var(--jp-ui-font-color1);\n font-size: 11px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n font-family: var(--jp-code-font-family);\n}\n\n.app-item-copy-button {\n border: none;\n background: transparent;\n cursor: pointer;\n padding: 2px;\n display: flex;\n align-items: center;\n justify-content: center;\n margin-left: 8px;\n border-radius: 2px;\n}\n\n.app-item-copy-button:hover {\n background-color: var(--jp-layout-color2);\n}\n"],"sourceRoot":""}]);
15304
+ `, "",{"version":3,"sources":["webpack://./style/AppsList.css"],"names":[],"mappings":"AAAA;;;EAGE;;AAEF,kBAAkB;AAClB;EACE,aAAa;EACb,sBAAsB;EACtB,YAAY;EACZ,eAAe;EACf,qCAAqC;EACrC,gBAAgB;AAClB;;AAEA;EACE,aAAa;EACb,8BAA8B;EAC9B,mBAAmB;EACnB,aAAa;EACb,cAAc;EACd,gDAAgD;AAClD;;AAEA;EACE,OAAO;EACP,gBAAgB;EAChB,aAAa;EACb,aAAa;AACf;;AAEA;EACE,SAAS;EACT,eAAe;EACf,iBAAiB;EACjB,+BAA+B;AACjC;;AAEA;EACE,aAAa;EACb,QAAQ;AACV;;AAEA;EACE,gBAAgB;EAChB,eAAe;EACf,6BAA6B;EAC7B,+BAA+B;EAC/B,yCAAyC;EACzC,kBAAkB;EAClB,eAAe;EACf,mBAAmB;EACnB,sCAAsC;AACxC;;AAEA;EACE,yCAAyC;AAC3C;;AAEA;EACE,mBAAmB;AACrB;;AAEA;EACE,wCAAwC;EACxC,YAAY;EACZ,YAAY;AACd;;AAEA;EACE,+BAA+B;EAC/B,kBAAkB;EAClB,eAAe;AACjB;;AAEA;EACE,cAAc;EACd,kBAAkB;EAClB,eAAe;EACf,yCAAyC;EACzC,yBAAyB;EACzB,kBAAkB;AACpB;;AAEA;EACE,eAAe;AACjB;;AAEA;EACE,+BAA+B;EAC/B,yCAAyC;EACzC,yCAAyC;EACzC,kBAAkB;EAClB,kBAAkB;EAClB,kBAAkB;EAClB,aAAa;EACb,sBAAsB;EACtB,mBAAmB;EACnB,SAAS;AACX;;AAEA;EACE,eAAe;EACf,iBAAiB;EACjB,qCAAqC;AACvC;;AAEA;EACE,eAAe;EACf,eAAe;AACjB;;AAEA;EACE,+BAA+B;EAC/B,kBAAkB;EAClB,eAAe;AACjB;;AAEA;EACE,yCAAyC;EACzC,kBAAkB;EAClB,aAAa;EACb,kBAAkB;EAClB,yCAAyC;AAC3C;;AAEA;EACE,aAAa;EACb,8BAA8B;EAC9B,uBAAuB;EACvB,kBAAkB;AACpB;;AAEA;EACE,OAAO;AACT;;AAEA;EACE,iBAAiB;EACjB,+BAA+B;EAC/B,kBAAkB;AACpB;;AAEA;EACE,aAAa;EACb,mBAAmB;EACnB,kBAAkB;AACpB;;AAEA;EACE,qBAAqB;EACrB,UAAU;EACV,WAAW;EACX,kBAAkB;EAClB,iBAAiB;AACnB;;AAEA;EACE,+BAA+B;EAC/B,eAAe;AACjB;;AAEA;EACE,+BAA+B;EAC/B,eAAe;AACjB;;AAEA;EACE,aAAa;EACb,mBAAmB;EACnB,yCAAyC;EACzC,yCAAyC;EACzC,kBAAkB;EAClB,gBAAgB;AAClB;;AAEA;EACE,OAAO;EACP,+BAA+B;EAC/B,eAAe;EACf,gBAAgB;EAChB,uBAAuB;EACvB,mBAAmB;EACnB,uCAAuC;AACzC;;AAEA;EACE,YAAY;EACZ,uBAAuB;EACvB,eAAe;EACf,YAAY;EACZ,aAAa;EACb,mBAAmB;EACnB,uBAAuB;EACvB,gBAAgB;EAChB,kBAAkB;AACpB;;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/* apps-list.css */\n.apps-list-container {\n display: flex;\n flex-direction: column;\n height: 100%;\n font-size: 13px;\n font-family: var(--jp-ui-font-family);\n overflow: hidden;\n}\n\n.apps-list-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 16px;\n flex-shrink: 0;\n border-bottom: 1px solid var(--jp-border-color2);\n}\n\n.apps-list-content {\n flex: 1;\n overflow-y: auto;\n padding: 16px;\n min-height: 0;\n}\n\n.apps-list-title {\n margin: 0;\n font-size: 14px;\n font-weight: bold;\n color: var(--jp-ui-font-color1);\n}\n\n.apps-list-actions {\n display: flex;\n gap: 8px;\n}\n\n.apps-list-button {\n padding: 4px 8px;\n font-size: 11px;\n background-color: transparent;\n color: var(--jp-ui-font-color2);\n border: 1px solid var(--jp-border-color2);\n border-radius: 3px;\n cursor: pointer;\n font-weight: normal;\n transition: background-color 0.2s ease;\n}\n\n.apps-list-button:hover {\n background-color: var(--jp-layout-color2);\n}\n\n.apps-list-button:disabled {\n cursor: not-allowed;\n}\n\n.apps-list-button.primary {\n background-color: var(--jp-brand-color1);\n color: white;\n border: none;\n}\n\n.apps-list-loading {\n color: var(--jp-ui-font-color2);\n text-align: center;\n padding: 20px 0;\n}\n\n.apps-list-error {\n color: #f44336;\n text-align: center;\n padding: 20px 0;\n background-color: var(--jp-layout-color1);\n border: 1px solid #f44336;\n border-radius: 4px;\n}\n\n.apps-list-error-actions {\n margin-top: 8px;\n}\n\n.apps-list-auth-message {\n color: var(--jp-ui-font-color1);\n background-color: var(--jp-layout-color0);\n border: 1px solid var(--jp-border-color2);\n border-radius: 4px;\n padding: 24px 16px;\n text-align: center;\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 12px;\n}\n\n.apps-list-auth-text {\n font-size: 14px;\n font-weight: bold;\n font-family: var(--jp-ui-font-family);\n}\n\n.apps-list-auth-login-button {\n font-size: 13px;\n min-width: 96px;\n}\n\n.apps-list-empty {\n color: var(--jp-ui-font-color2);\n text-align: center;\n padding: 20px 0;\n}\n\n.app-item {\n border: 1px solid var(--jp-border-color1);\n border-radius: 4px;\n padding: 12px;\n margin-bottom: 8px;\n background-color: var(--jp-layout-color0);\n}\n\n.app-item-header {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n margin-bottom: 8px;\n}\n\n.app-item-content {\n flex: 1;\n}\n\n.app-item-name {\n font-weight: bold;\n color: var(--jp-ui-font-color1);\n margin-bottom: 4px;\n}\n\n.app-item-status-container {\n display: flex;\n align-items: center;\n margin-bottom: 4px;\n}\n\n.app-item-status-indicator {\n display: inline-block;\n width: 8px;\n height: 8px;\n border-radius: 50%;\n margin-right: 6px;\n}\n\n.app-item-status-text {\n color: var(--jp-ui-font-color2);\n font-size: 12px;\n}\n\n.app-item-last-deployed {\n color: var(--jp-ui-font-color2);\n font-size: 11px;\n}\n\n.app-item-url-container {\n display: flex;\n align-items: center;\n background-color: var(--jp-layout-color1);\n border: 1px solid var(--jp-border-color2);\n border-radius: 3px;\n padding: 6px 8px;\n}\n\n.app-item-url {\n flex: 1;\n color: var(--jp-ui-font-color1);\n font-size: 11px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n font-family: var(--jp-code-font-family);\n}\n\n.app-item-copy-button {\n border: none;\n background: transparent;\n cursor: pointer;\n padding: 2px;\n display: flex;\n align-items: center;\n justify-content: center;\n margin-left: 8px;\n border-radius: 2px;\n}\n\n.app-item-copy-button:hover {\n background-color: var(--jp-layout-color2);\n}\n"],"sourceRoot":""}]);
15033
15305
  // Exports
15034
15306
  /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);
15035
15307
 
@@ -17675,6 +17947,25 @@ ___CSS_LOADER_EXPORT___.push([module.id, `/*
17675
17947
  transition: background-color 0.2s;
17676
17948
  white-space: nowrap;
17677
17949
  /* Prevent text wrapping */
17950
+ display: flex;
17951
+ align-items: center;
17952
+ justify-content: space-between;
17953
+ gap: 8px;
17954
+ }
17955
+
17956
+ .model-option-name {
17957
+ flex: 1;
17958
+ min-width: 0;
17959
+ overflow: hidden;
17960
+ text-overflow: ellipsis;
17961
+ }
17962
+
17963
+ .model-type-icon {
17964
+ display: flex;
17965
+ align-items: center;
17966
+ justify-content: center;
17967
+ flex-shrink: 0;
17968
+ opacity: 0.7;
17678
17969
  }
17679
17970
 
17680
17971
  .model-option:hover {
@@ -17738,7 +18029,109 @@ ___CSS_LOADER_EXPORT___.push([module.id, `/*
17738
18029
  .model-name {
17739
18030
  display: none;
17740
18031
  }
17741
- }`, "",{"version":3,"sources":["webpack://./style/ModelSelector.css"],"names":[],"mappings":"AAAA;;;EAGE;;AAEF,4DAA4D;;AAE5D;EACE,kBAAkB;EAClB,cAAc;EACd,aAAa;EACb,YAAY,EAAE,mCAAmC;EACjD,aAAa;EACb,mBAAmB,EAAE,sBAAsB;EAC3C,+BAA+B;AACjC;;AAEA;EACE,+BAA+B;AACjC;;AAEA;EACE,kBAAkB;EAClB,YAAY,EAAE,yCAAyC;EACvD,kBAAkB;EAClB,eAAe;EACf,aAAa;EACb,mBAAmB,EAAE,0CAA0C;EAC/D,kBAAkB;EAClB,eAAe;AACjB;;;AAGA;EACE,aAAa;EACb,mBAAmB;EACnB,8BAA8B;EAC9B,WAAW;EACX,YAAY;EACZ,cAAc;EACd,eAAe;EACf,gBAAgB;EAChB,cAAc;EACd,mBAAmB;EACnB,gBAAgB;EAChB,uBAAuB;AACzB;;AAEA;EACE,aAAa;EACb,mBAAmB;EACnB,uBAAuB;EACvB,WAAW;EACX,YAAY;EACZ,cAAc;AAChB;;AAEA;EACE,cAAc;EACd,0BAA0B;EAC1B,gBAAgB;EAChB,cAAc,EAAE,iCAAiC;AACnD;;AAEA,2BAA2B;AAC3B;EACE,kBAAkB;EAClB,YAAY;EACZ,iBAAiB;EACjB,gBAAgB;EAChB,yCAAyC;EACzC,yCAAyC;EACzC,kBAAkB;EAClB,kBAAkB;EAClB,yCAAyC;EACzC,aAAa;EACb,WAAW;AACb;;AAEA;EACE,gBAAgB;EAChB,eAAe;EACf,mCAAmC;EACnC,oCAAoC;EACpC,eAAe;EACf,iCAAiC;EACjC,mBAAmB;EACnB,0BAA0B;AAC5B;;AAEA;EACE,yCAAyC;EACzC,wBAAwB;AAC1B;;AAEA;EACE,yCAAyC;EACzC,wBAAwB;AAC1B;;AAEA,4EAA4E;AAC5E;EACE,YAAY;EACZ,aAAa;EACb,mBAAmB;AACrB;;AAEA;EACE,YAAY;EACZ,kBAAkB;AACpB;;AAEA,iDAAiD;AACjD;EACE,aAAa;EACb,wCAAwC;AAC1C;;AAEA;EACE,qBAAqB;EACrB,gBAAgB;EAChB,gBAAgB;EAChB,uBAAuB;EACvB,mBAAmB;EACnB,sBAAsB;AACxB;;AAEA,qDAAqD;AACrD;EACE,aAAa;AACf;;AAEA;EACE,eAAe;AACjB;;AAEA,2CAA2C;AAC3C;;EAEE,uEAAuE;EACvE;IACE,WAAW;EACb;;EAEA;IACE,eAAe;EACjB;;EAEA;IACE,aAAa;EACf;AACF","sourcesContent":["/*\n * Copyright (c) Saga Inc.\n * Distributed under the terms of the GNU Affero General Public License v3.0 License.\n */\n\n/* ModelSelector.css - responsive design with compact mode */\n\n.model-selector {\n position: relative;\n flex: 0 0 auto;\n margin: 0 8px;\n height: 20px; /* Match height of other elements */\n display: flex;\n align-items: center; /* Center vertically */\n color: var(--jp-ui-font-color2);\n}\n\n.model-selector:hover {\n color: var(--jp-ui-font-color1);\n}\n\n.model-selector-dropdown {\n position: relative;\n height: 20px; /* Fixed height to match other elements */\n border-radius: 4px;\n cursor: pointer;\n display: flex;\n align-items: center; /* Ensure content is vertically centered */\n width: min-content;\n max-width: 18ch;\n}\n\n\n.selected-model {\n display: flex;\n align-items: center;\n justify-content: space-between;\n width: 100%;\n height: 100%;\n padding: 0 8px;\n font-size: 12px;\n font-weight: 500;\n line-height: 1;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.model-icon {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 14px;\n height: 14px;\n line-height: 1;\n}\n\n.dropdown-arrow {\n font-size: 8px;\n transition: transform 0.2s;\n margin-left: 4px;\n flex-shrink: 0; /* Prevent arrow from shrinking */\n}\n\n/* Model options dropdown */\n.model-options {\n position: absolute;\n bottom: 100%;\n max-height: 180px;\n overflow-y: auto;\n background-color: var(--jp-layout-color1);\n border: 1px solid var(--jp-layout-color2);\n border-radius: 4px;\n margin-bottom: 4px;\n box-shadow: 0 -2px 6px rgba(0, 0, 0, 0.1);\n z-index: 1000;\n width: auto;\n}\n\n.model-option {\n padding: 4px 8px;\n font-size: 12px;\n /* Keep this size for readability */\n color: var(--jp-content-font-color1);\n cursor: pointer;\n transition: background-color 0.2s;\n white-space: nowrap;\n /* Prevent text wrapping */\n}\n\n.model-option:hover {\n background-color: var(--jp-layout-color2);\n color: var(--purple-700);\n}\n\n.model-option.selected {\n background-color: var(--jp-layout-color2);\n color: var(--purple-700);\n}\n\n/* When inside chat-controls - ensure proper alignment with other controls */\n.chat-controls .model-selector {\n height: 20px;\n display: flex;\n align-items: center;\n}\n\n.chat-controls .model-selector-dropdown {\n height: 20px;\n align-self: center;\n}\n\n/* Ensure dropdown appears above other elements */\n.model-options {\n z-index: 1010;\n /* Higher z-index to ensure visibility */\n}\n\n.model-name {\n display: inline-block;\n max-width: 120px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n vertical-align: bottom;\n}\n\n/* On wider screens, show only the name of the model*/\n.model-icon {\n display: none;\n}\n\n.model-name {\n display: inline;\n}\n\n/* On compact screens, show only the icon */\n@container (max-width: 260px) {\n\n /* Shift the dropdown to the left to help prevent right-edge overflow */\n .model-options {\n left: -40px;\n }\n\n .model-icon {\n display: inline;\n }\n\n .model-name {\n display: none;\n }\n}"],"sourceRoot":""}]);
18032
+ }
18033
+
18034
+ /* Model tooltip - appears to the right of the dropdown, rendered via portal */
18035
+ .model-tooltip {
18036
+ position: fixed;
18037
+ top: var(--tooltip-top, 200px);
18038
+ left: var(--tooltip-left, 200px);
18039
+ background-color: var(--jp-layout-color1);
18040
+ border: 1px solid var(--jp-layout-color2);
18041
+ border-radius: 4px;
18042
+ padding: 12px;
18043
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
18044
+ z-index: 10000; /* High z-index to appear above Jupyter notebook */
18045
+ width: 280px;
18046
+ pointer-events: none; /* Prevent tooltip from blocking mouse events */
18047
+ }
18048
+
18049
+ .model-tooltip-content {
18050
+ display: flex;
18051
+ flex-direction: column;
18052
+ gap: 12px;
18053
+ }
18054
+
18055
+ .model-tooltip-header {
18056
+ display: flex;
18057
+ flex-direction: column;
18058
+ gap: 8px;
18059
+ }
18060
+
18061
+ .model-tooltip-title-row {
18062
+ display: flex;
18063
+ align-items: center;
18064
+ gap: 6px;
18065
+ }
18066
+
18067
+ .model-tooltip-title-icon {
18068
+ flex-shrink: 0;
18069
+ opacity: 0.8;
18070
+ display: flex;
18071
+ align-items: center;
18072
+ justify-content: center;
18073
+ line-height: 1;
18074
+ }
18075
+
18076
+ .model-tooltip-title {
18077
+ font-size: 14px;
18078
+ font-weight: 600;
18079
+ color: var(--jp-content-font-color1);
18080
+ line-height: 1.2;
18081
+ }
18082
+
18083
+ .model-tooltip-metadata {
18084
+ display: grid;
18085
+ grid-template-columns: 1fr 1fr;
18086
+ gap: 6px 12px;
18087
+ font-size: 11px;
18088
+ }
18089
+
18090
+ .model-tooltip-metadata-item {
18091
+ display: flex;
18092
+ gap: 4px;
18093
+ }
18094
+
18095
+ .model-tooltip-metadata-label {
18096
+ color: var(--jp-content-font-color2);
18097
+ font-weight: 500;
18098
+ }
18099
+
18100
+ .model-tooltip-metadata-value {
18101
+ color: var(--jp-content-font-color1);
18102
+ font-weight: 600;
18103
+ }
18104
+
18105
+ .model-tooltip-section {
18106
+ display: flex;
18107
+ flex-direction: column;
18108
+ gap: 6px;
18109
+ }
18110
+
18111
+ .model-tooltip-section-label {
18112
+ font-size: 11px;
18113
+ font-weight: 600;
18114
+ color: var(--jp-content-font-color1);
18115
+ text-transform: uppercase;
18116
+ letter-spacing: 0.5px;
18117
+ }
18118
+
18119
+ .model-tooltip-bullet-list {
18120
+ margin: 0;
18121
+ padding-left: 16px;
18122
+ list-style-type: disc;
18123
+ }
18124
+
18125
+ .model-tooltip-bullet-item {
18126
+ font-size: 12px;
18127
+ color: var(--jp-content-font-color2);
18128
+ line-height: 1.5;
18129
+ margin-bottom: 4px;
18130
+ }
18131
+
18132
+ .model-tooltip-bullet-item:last-child {
18133
+ margin-bottom: 0;
18134
+ }`, "",{"version":3,"sources":["webpack://./style/ModelSelector.css"],"names":[],"mappings":"AAAA;;;EAGE;;AAEF,4DAA4D;;AAE5D;EACE,kBAAkB;EAClB,cAAc;EACd,aAAa;EACb,YAAY,EAAE,mCAAmC;EACjD,aAAa;EACb,mBAAmB,EAAE,sBAAsB;EAC3C,+BAA+B;AACjC;;AAEA;EACE,+BAA+B;AACjC;;AAEA;EACE,kBAAkB;EAClB,YAAY,EAAE,yCAAyC;EACvD,kBAAkB;EAClB,eAAe;EACf,aAAa;EACb,mBAAmB,EAAE,0CAA0C;EAC/D,kBAAkB;EAClB,eAAe;AACjB;;;AAGA;EACE,aAAa;EACb,mBAAmB;EACnB,8BAA8B;EAC9B,WAAW;EACX,YAAY;EACZ,cAAc;EACd,eAAe;EACf,gBAAgB;EAChB,cAAc;EACd,mBAAmB;EACnB,gBAAgB;EAChB,uBAAuB;AACzB;;AAEA;EACE,aAAa;EACb,mBAAmB;EACnB,uBAAuB;EACvB,WAAW;EACX,YAAY;EACZ,cAAc;AAChB;;AAEA;EACE,cAAc;EACd,0BAA0B;EAC1B,gBAAgB;EAChB,cAAc,EAAE,iCAAiC;AACnD;;AAEA,2BAA2B;AAC3B;EACE,kBAAkB;EAClB,YAAY;EACZ,iBAAiB;EACjB,gBAAgB;EAChB,yCAAyC;EACzC,yCAAyC;EACzC,kBAAkB;EAClB,kBAAkB;EAClB,yCAAyC;EACzC,aAAa;EACb,WAAW;AACb;;AAEA;EACE,gBAAgB;EAChB,eAAe;EACf,mCAAmC;EACnC,oCAAoC;EACpC,eAAe;EACf,iCAAiC;EACjC,mBAAmB;EACnB,0BAA0B;EAC1B,aAAa;EACb,mBAAmB;EACnB,8BAA8B;EAC9B,QAAQ;AACV;;AAEA;EACE,OAAO;EACP,YAAY;EACZ,gBAAgB;EAChB,uBAAuB;AACzB;;AAEA;EACE,aAAa;EACb,mBAAmB;EACnB,uBAAuB;EACvB,cAAc;EACd,YAAY;AACd;;AAEA;EACE,yCAAyC;EACzC,wBAAwB;AAC1B;;AAEA;EACE,yCAAyC;EACzC,wBAAwB;AAC1B;;AAEA,4EAA4E;AAC5E;EACE,YAAY;EACZ,aAAa;EACb,mBAAmB;AACrB;;AAEA;EACE,YAAY;EACZ,kBAAkB;AACpB;;AAEA,iDAAiD;AACjD;EACE,aAAa;EACb,wCAAwC;AAC1C;;AAEA;EACE,qBAAqB;EACrB,gBAAgB;EAChB,gBAAgB;EAChB,uBAAuB;EACvB,mBAAmB;EACnB,sBAAsB;AACxB;;AAEA,qDAAqD;AACrD;EACE,aAAa;AACf;;AAEA;EACE,eAAe;AACjB;;AAEA,2CAA2C;AAC3C;;EAEE,uEAAuE;EACvE;IACE,WAAW;EACb;;EAEA;IACE,eAAe;EACjB;;EAEA;IACE,aAAa;EACf;AACF;;AAEA,8EAA8E;AAC9E;EACE,eAAe;EACf,8BAA8B;EAC9B,gCAAgC;EAChC,yCAAyC;EACzC,yCAAyC;EACzC,kBAAkB;EAClB,aAAa;EACb,yCAAyC;EACzC,cAAc,EAAE,kDAAkD;EAClE,YAAY;EACZ,oBAAoB,EAAE,+CAA+C;AACvE;;AAEA;EACE,aAAa;EACb,sBAAsB;EACtB,SAAS;AACX;;AAEA;EACE,aAAa;EACb,sBAAsB;EACtB,QAAQ;AACV;;AAEA;EACE,aAAa;EACb,mBAAmB;EACnB,QAAQ;AACV;;AAEA;EACE,cAAc;EACd,YAAY;EACZ,aAAa;EACb,mBAAmB;EACnB,uBAAuB;EACvB,cAAc;AAChB;;AAEA;EACE,eAAe;EACf,gBAAgB;EAChB,oCAAoC;EACpC,gBAAgB;AAClB;;AAEA;EACE,aAAa;EACb,8BAA8B;EAC9B,aAAa;EACb,eAAe;AACjB;;AAEA;EACE,aAAa;EACb,QAAQ;AACV;;AAEA;EACE,oCAAoC;EACpC,gBAAgB;AAClB;;AAEA;EACE,oCAAoC;EACpC,gBAAgB;AAClB;;AAEA;EACE,aAAa;EACb,sBAAsB;EACtB,QAAQ;AACV;;AAEA;EACE,eAAe;EACf,gBAAgB;EAChB,oCAAoC;EACpC,yBAAyB;EACzB,qBAAqB;AACvB;;AAEA;EACE,SAAS;EACT,kBAAkB;EAClB,qBAAqB;AACvB;;AAEA;EACE,eAAe;EACf,oCAAoC;EACpC,gBAAgB;EAChB,kBAAkB;AACpB;;AAEA;EACE,gBAAgB;AAClB","sourcesContent":["/*\n * Copyright (c) Saga Inc.\n * Distributed under the terms of the GNU Affero General Public License v3.0 License.\n */\n\n/* ModelSelector.css - responsive design with compact mode */\n\n.model-selector {\n position: relative;\n flex: 0 0 auto;\n margin: 0 8px;\n height: 20px; /* Match height of other elements */\n display: flex;\n align-items: center; /* Center vertically */\n color: var(--jp-ui-font-color2);\n}\n\n.model-selector:hover {\n color: var(--jp-ui-font-color1);\n}\n\n.model-selector-dropdown {\n position: relative;\n height: 20px; /* Fixed height to match other elements */\n border-radius: 4px;\n cursor: pointer;\n display: flex;\n align-items: center; /* Ensure content is vertically centered */\n width: min-content;\n max-width: 18ch;\n}\n\n\n.selected-model {\n display: flex;\n align-items: center;\n justify-content: space-between;\n width: 100%;\n height: 100%;\n padding: 0 8px;\n font-size: 12px;\n font-weight: 500;\n line-height: 1;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.model-icon {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 14px;\n height: 14px;\n line-height: 1;\n}\n\n.dropdown-arrow {\n font-size: 8px;\n transition: transform 0.2s;\n margin-left: 4px;\n flex-shrink: 0; /* Prevent arrow from shrinking */\n}\n\n/* Model options dropdown */\n.model-options {\n position: absolute;\n bottom: 100%;\n max-height: 180px;\n overflow-y: auto;\n background-color: var(--jp-layout-color1);\n border: 1px solid var(--jp-layout-color2);\n border-radius: 4px;\n margin-bottom: 4px;\n box-shadow: 0 -2px 6px rgba(0, 0, 0, 0.1);\n z-index: 1000;\n width: auto;\n}\n\n.model-option {\n padding: 4px 8px;\n font-size: 12px;\n /* Keep this size for readability */\n color: var(--jp-content-font-color1);\n cursor: pointer;\n transition: background-color 0.2s;\n white-space: nowrap;\n /* Prevent text wrapping */\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n}\n\n.model-option-name {\n flex: 1;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.model-type-icon {\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n opacity: 0.7;\n}\n\n.model-option:hover {\n background-color: var(--jp-layout-color2);\n color: var(--purple-700);\n}\n\n.model-option.selected {\n background-color: var(--jp-layout-color2);\n color: var(--purple-700);\n}\n\n/* When inside chat-controls - ensure proper alignment with other controls */\n.chat-controls .model-selector {\n height: 20px;\n display: flex;\n align-items: center;\n}\n\n.chat-controls .model-selector-dropdown {\n height: 20px;\n align-self: center;\n}\n\n/* Ensure dropdown appears above other elements */\n.model-options {\n z-index: 1010;\n /* Higher z-index to ensure visibility */\n}\n\n.model-name {\n display: inline-block;\n max-width: 120px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n vertical-align: bottom;\n}\n\n/* On wider screens, show only the name of the model*/\n.model-icon {\n display: none;\n}\n\n.model-name {\n display: inline;\n}\n\n/* On compact screens, show only the icon */\n@container (max-width: 260px) {\n\n /* Shift the dropdown to the left to help prevent right-edge overflow */\n .model-options {\n left: -40px;\n }\n\n .model-icon {\n display: inline;\n }\n\n .model-name {\n display: none;\n }\n}\n\n/* Model tooltip - appears to the right of the dropdown, rendered via portal */\n.model-tooltip {\n position: fixed;\n top: var(--tooltip-top, 200px);\n left: var(--tooltip-left, 200px);\n background-color: var(--jp-layout-color1);\n border: 1px solid var(--jp-layout-color2);\n border-radius: 4px;\n padding: 12px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);\n z-index: 10000; /* High z-index to appear above Jupyter notebook */\n width: 280px;\n pointer-events: none; /* Prevent tooltip from blocking mouse events */\n}\n\n.model-tooltip-content {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.model-tooltip-header {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.model-tooltip-title-row {\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.model-tooltip-title-icon {\n flex-shrink: 0;\n opacity: 0.8;\n display: flex;\n align-items: center;\n justify-content: center;\n line-height: 1;\n}\n\n.model-tooltip-title {\n font-size: 14px;\n font-weight: 600;\n color: var(--jp-content-font-color1);\n line-height: 1.2;\n}\n\n.model-tooltip-metadata {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 6px 12px;\n font-size: 11px;\n}\n\n.model-tooltip-metadata-item {\n display: flex;\n gap: 4px;\n}\n\n.model-tooltip-metadata-label {\n color: var(--jp-content-font-color2);\n font-weight: 500;\n}\n\n.model-tooltip-metadata-value {\n color: var(--jp-content-font-color1);\n font-weight: 600;\n}\n\n.model-tooltip-section {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.model-tooltip-section-label {\n font-size: 11px;\n font-weight: 600;\n color: var(--jp-content-font-color1);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.model-tooltip-bullet-list {\n margin: 0;\n padding-left: 16px;\n list-style-type: disc;\n}\n\n.model-tooltip-bullet-item {\n font-size: 12px;\n color: var(--jp-content-font-color2);\n line-height: 1.5;\n margin-bottom: 4px;\n}\n\n.model-tooltip-bullet-item:last-child {\n margin-bottom: 0;\n}"],"sourceRoot":""}]);
17742
18135
  // Exports
17743
18136
  /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);
17744
18137
 
@@ -21843,4 +22236,4 @@ var update = _node_modules_style_loader_dist_runtime_injectStylesIntoStyleTag_js
21843
22236
  /***/ })
21844
22237
 
21845
22238
  }]);
21846
- //# sourceMappingURL=lib_index_js.c0b356ea4ace64bf1f03.js.map
22239
+ //# sourceMappingURL=lib_index_js.4b7cd47a24bb24ef84ea.js.map