From 2d1dac5dcb2cf563968f89faedae20f267e2ca6f Mon Sep 17 00:00:00 2001 From: TheGupta2012 Date: Fri, 19 Sep 2025 16:11:30 +0530 Subject: [PATCH 1/2] add qbraid specific changes --- .github/workflows/upload-s3-production.yml | 91 +++++++++++++++++++++ .github/workflows/upload-s3-staging.yml | 92 ++++++++++++++++++++++ README.md | 18 ++--- notebook_intelligence/api.py | 3 + notebook_intelligence/extension.py | 90 +++++++++++++++++++++ src/api.ts | 16 ++++ src/chat-sidebar.tsx | 88 ++++++++++++++++++--- src/index.ts | 9 +++ style/base.css | 55 +++++++++++-- 9 files changed, 437 insertions(+), 25 deletions(-) create mode 100644 .github/workflows/upload-s3-production.yml create mode 100644 .github/workflows/upload-s3-staging.yml diff --git a/.github/workflows/upload-s3-production.yml b/.github/workflows/upload-s3-production.yml new file mode 100644 index 00000000..9d730b7e --- /dev/null +++ b/.github/workflows/upload-s3-production.yml @@ -0,0 +1,91 @@ +name: Upload S3 production (deprecated) + +on: + release: + types: [published] + workflow_dispatch: + +jobs: + build: + name: Build wheel + runs-on: ubuntu-latest + strategy: + matrix: + python-version: ['3.11'] + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: Install node + uses: actions/setup-node@v3 + with: + node-version: '18.x' + - name: Setup Python ${{ matrix.python-version }} + uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python-version }} + architecture: 'x64' + + - name: Get pip cache dir + id: pip-cache + run: echo "dir=$(pip cache dir)" >> $GITHUB_OUTPUT + - name: pip cache + uses: actions/cache@v3 + with: + path: ${{ steps.pip-cache.outputs.dir }} + key: ${{ runner.os }}-pip-${{ matrix.python-version }}-${{ hashFiles('**/setup.py') }} + restore-keys: | + ${{ runner.os }}-pip-${{ matrix.python-version }}- + ${{ runner.os }}-pip- + - name: Get yarn cache directory path + id: yarn-cache-dir-path + run: echo "dir=$(yarn cache dir)" >> $GITHUB_OUTPUT + - name: Setup yarn cache + uses: actions/cache@v3 + id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`) + env: + # Increase this value to reset cache + CACHE_NUMBER: 3 + with: + path: | + ${{ steps.yarn-cache-dir-path.outputs.dir }} + **/node_modules + key: ${{ runner.os }}-yarn-${{ env.CACHE_NUMBER }}-${{ hashFiles('**/yarn.lock') }} + restore-keys: | + ${{ runner.os }}-yarn-${{ env.CACHE_NUMBER }} + ${{ runner.os }}-yarn- + - name: Install dependencies and make wheels dir + run: python -m pip install -U "jupyter_packaging>=0.10,<2" "jupyterlab>=4.0.0,<5" pip wheel build + + - name: Build the extension + run: python -m build + + - uses: actions/upload-artifact@v4 + if: matrix.python-version == '3.11' + with: + name: extension + path: dist/quantum_jobs*.whl + if-no-files-found: error + + deploy: + name: Upload to Amazon S3 + runs-on: ubuntu-latest + + needs: build + + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: Configure AWS credentials + uses: aws-actions/configure-aws-credentials@v2 + with: + aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} + aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + aws-region: us-east-1 + - uses: actions/download-artifact@v4 + with: + name: extension + + - name: Copy wheel file to S3 lab-extensions bucket + run: | + aws s3 rm s3://qbraid-lab-extensions/production/ --recursive --exclude "*" --include "notebook_intelligence*.whl" + aws s3 cp ./ s3://qbraid-lab-extensions/production/ --recursive --exclude "*" --include "notebook_intelligence*.whl" \ No newline at end of file diff --git a/.github/workflows/upload-s3-staging.yml b/.github/workflows/upload-s3-staging.yml new file mode 100644 index 00000000..bf7d7073 --- /dev/null +++ b/.github/workflows/upload-s3-staging.yml @@ -0,0 +1,92 @@ +name: Upload S3 Staging + +on: + push: + branches: + - main + workflow_dispatch: + +jobs: + build: + name: Build wheel + runs-on: ubuntu-latest + strategy: + matrix: + python-version: ['3.11'] + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: Install node + uses: actions/setup-node@v3 + with: + node-version: '18.x' + - name: Setup Python ${{ matrix.python-version }} + uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python-version }} + architecture: 'x64' + + - name: Get pip cache dir + id: pip-cache + run: echo "dir=$(pip cache dir)" >> $GITHUB_OUTPUT + - name: pip cache + uses: actions/cache@v3 + with: + path: ${{ steps.pip-cache.outputs.dir }} + key: ${{ runner.os }}-pip-${{ matrix.python-version }}-${{ hashFiles('**/setup.py') }} + restore-keys: | + ${{ runner.os }}-pip-${{ matrix.python-version }}- + ${{ runner.os }}-pip- + - name: Get yarn cache directory path + id: yarn-cache-dir-path + run: echo "dir=$(yarn cache dir)" >> $GITHUB_OUTPUT + - name: Setup yarn cache + uses: actions/cache@v3 + id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`) + env: + # Increase this value to reset cache + CACHE_NUMBER: 3 + with: + path: | + ${{ steps.yarn-cache-dir-path.outputs.dir }} + **/node_modules + key: ${{ runner.os }}-yarn-${{ env.CACHE_NUMBER }}-${{ hashFiles('**/yarn.lock') }} + restore-keys: | + ${{ runner.os }}-yarn-${{ env.CACHE_NUMBER }} + ${{ runner.os }}-yarn- + - name: Install dependencies and make wheels dir + run: python -m pip install -U "jupyter_packaging>=0.10,<2" "jupyterlab>=4.0.0,<5" pip wheel build + + - name: Build the extension + run: python -m build + + - uses: actions/upload-artifact@v4 + if: matrix.python-version == '3.11' + with: + name: extension + path: dist/notebook_intelligence*.whl + if-no-files-found: error + + deploy: + name: Upload to Amazon S3 + runs-on: ubuntu-latest + + needs: build + + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: Configure AWS credentials + uses: aws-actions/configure-aws-credentials@v2 + with: + aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} + aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + aws-region: us-east-1 + - uses: actions/download-artifact@v4 + with: + name: extension + + - name: Copy wheel file to S3 lab-extensions bucket + run: | + aws s3 rm s3://qbraid-lab-extensions/staging/ --recursive --exclude "*" --include "notebook_intelligence*.whl" + aws s3 cp ./ s3://qbraid-lab-extensions/staging/ --recursive --exclude "*" --include "notebook_intelligence*.whl" \ No newline at end of file diff --git a/README.md b/README.md index 6a170421..9ecb4636 100644 --- a/README.md +++ b/README.md @@ -117,16 +117,16 @@ You can easily add MCP servers to NBI by editing the configuration file [~/.jupy ```json { - "mcpServers": { - "filesystem": { - "command": "npx", - "args": [ - "-y", - "@modelcontextprotocol/server-filesystem", - "/Users/mbektas/mcp-test" - ] - } + "mcpServers": { + "filesystem": { + "command": "npx", + "args": [ + "-y", + "@modelcontextprotocol/server-filesystem", + "/Users/mbektas/mcp-test" + ] } + } } ``` diff --git a/notebook_intelligence/api.py b/notebook_intelligence/api.py index 90c319ac..453c3aeb 100644 --- a/notebook_intelligence/api.py +++ b/notebook_intelligence/api.py @@ -515,12 +515,15 @@ async def _tool_call_loop(tool_call_rounds: list): tool_call_rounds = tool_call_rounds[1:] tool_name = tool_call['function']['name'] + print("Tool name is : ", tool_name) tool_to_call = self._get_tool_by_name(tool_name) if tool_to_call is None: log.error(f"Tool not found: {tool_name}, args: {tool_call['function']['arguments']}") response.stream(MarkdownData("Oops! Failed to find requested tool. Please try again with a different prompt.")) response.finish() return + + print("Tool to call is : ", tool_to_call) if type(tool_call['function']['arguments']) is dict: args = tool_call['function']['arguments'] diff --git a/notebook_intelligence/extension.py b/notebook_intelligence/extension.py index ef511643..858413f3 100644 --- a/notebook_intelligence/extension.py +++ b/notebook_intelligence/extension.py @@ -156,6 +156,94 @@ def post(self): self.finish(json.dumps({"status": "error", "message": str(e)})) return +class CreateDynamicMCPConfigHandler(APIHandler): + @tornado.web.authenticated + def post(self): + try: + # Get the directory where JupyterLab was started (user's working directory) + user_root_dir = NotebookIntelligence.root_dir + + print(f"Creating dynamic MCP config for directory: {user_root_dir}") + + # Create dynamic MCP config with filesystem servers + dynamic_mcp_config = { + "mcpServers": { + "filesystem-pwd": { + "command": "npx", + "args": [ + "-y", + "@modelcontextprotocol/server-filesystem", + user_root_dir + ] + } + } + } + + # Add qBraid environments MCP server + qbraid_envs_dir = os.path.expanduser("~/.qbraid/environments/") + print(f"qBraid environments directory: {qbraid_envs_dir}") + if os.path.exists(qbraid_envs_dir): + # Add filesystem access to environments directory + dynamic_mcp_config["mcpServers"]["qbraid-envs"] = { + "command": "npx", + "args": [ + "-y", + "@modelcontextprotocol/server-filesystem", + qbraid_envs_dir + ] + } + print(f"Added qBraid environments MCP server") + + # TODO: Uncomment and fix the code below to add individual Python execution servers for each qBraid environment + + # # Discover individual environments and add Python execution servers + # try: + # env_count = 0 + # for env_name in os.listdir(qbraid_envs_dir): + # env_path = os.path.join(qbraid_envs_dir, env_name) + # python_executable = os.path.join(env_path, "bin", "python") + + # # Check if this is a valid environment with Python + # if (os.path.isdir(env_path) and + # os.path.exists(python_executable) and + # not env_name.startswith('.')): + + # # Add Python execution server for this environment + # server_name = f"python-{env_name}" + # dynamic_mcp_config["mcpServers"][server_name] = { + # "command": "npx", + # "args": [ + # "-y", + # "@modelcontextprotocol/python-mcp" + # ], + # "env": { + # "PYTHON_EXECUTABLE": python_executable + # } + # } + # env_count += 1 + # print(f"Added Python execution server for environment: {env_name}") + + # print(f"Discovered and added {env_count} qBraid environment Python servers") + # except Exception as e: + # print(f"Error discovering qBraid environments: {e}") + + else: + print(f"qBraid environments directory not found: {qbraid_envs_dir}") + + # Save to user's MCP config (this will merge with existing config) + ai_service_manager.nbi_config.user_mcp = dynamic_mcp_config + ai_service_manager.nbi_config.save() + ai_service_manager.nbi_config.load() + ai_service_manager.update_mcp_servers() + + self.finish(json.dumps({ + "status": "ok", + "message": f"Dynamic MCP config created for directory: {user_root_dir}" + })) + except Exception as e: + self.finish(json.dumps({"status": "error", "message": str(e)})) + return + class EmitTelemetryEventHandler(APIHandler): @tornado.web.authenticated def post(self): @@ -641,6 +729,7 @@ def _setup_handlers(self, web_app): route_pattern_update_provider_models = url_path_join(base_url, "notebook-intelligence", "update-provider-models") route_pattern_reload_mcp_servers = url_path_join(base_url, "notebook-intelligence", "reload-mcp-servers") route_pattern_mcp_config_file = url_path_join(base_url, "notebook-intelligence", "mcp-config-file") + route_pattern_create_dynamic_mcp_config = url_path_join(base_url, "notebook-intelligence", "create-dynamic-mcp-config") route_pattern_emit_telemetry_event = url_path_join(base_url, "notebook-intelligence", "emit-telemetry-event") route_pattern_github_login_status = url_path_join(base_url, "notebook-intelligence", "gh-login-status") route_pattern_github_login = url_path_join(base_url, "notebook-intelligence", "gh-login") @@ -653,6 +742,7 @@ def _setup_handlers(self, web_app): (route_pattern_update_provider_models, UpdateProviderModelsHandler), (route_pattern_reload_mcp_servers, ReloadMCPServersHandler), (route_pattern_mcp_config_file, MCPConfigFileHandler), + (route_pattern_create_dynamic_mcp_config, CreateDynamicMCPConfigHandler), (route_pattern_emit_telemetry_event, EmitTelemetryEventHandler), (route_pattern_github_login_status, GetGitHubLoginStatusHandler), (route_pattern_github_login, PostGitHubLoginHandler), diff --git a/src/api.ts b/src/api.ts index f073ff83..e48a8e91 100644 --- a/src/api.ts +++ b/src/api.ts @@ -288,6 +288,22 @@ export class NBIAPI { }); } + static async createDynamicMCPConfig(): Promise { + return new Promise((resolve, reject) => { + requestAPI('create-dynamic-mcp-config', { + method: 'POST', + body: JSON.stringify({}) + }) + .then(async data => { + resolve(data); + }) + .catch(reason => { + console.error(`Failed to create dynamic MCP config.\n${reason}`); + reject(reason); + }); + }); + } + static async chatRequest( messageId: string, chatId: string, diff --git a/src/chat-sidebar.tsx b/src/chat-sidebar.tsx index 2a3b235f..6012c89a 100644 --- a/src/chat-sidebar.tsx +++ b/src/chat-sidebar.tsx @@ -456,16 +456,18 @@ function ChatResponse(props: any) { )}
- {msg.from === 'user' - ? 'User' - : msg.participant?.name || 'AI Assistant'} -
-
-
Generating
+ {msg.from === 'user' ? '' : msg.participant?.name || 'AI Assistant'}
+ {msg.from !== 'user' && ( +
+
Generating
+
+ )}
{timestamp}
@@ -737,6 +739,48 @@ function SidebarComponent(props: any) { const [currentFileContextTitle, setCurrentFileContextTitle] = useState(''); const telemetryEmitter: ITelemetryEmitter = props.getTelemetryEmitter(); const [chatMode, setChatMode] = useState(NBIAPI.config.defaultChatMode); + // Model selection state + const [availableChatModels, setAvailableChatModels] = useState([]); + const [currentChatModel, setCurrentChatModel] = useState( + NBIAPI.config.chatModel.model + ); + + // Load available models when config changes + useEffect(() => { + const currentProvider = NBIAPI.config.chatModel.provider; + const allChatModels = NBIAPI.config.chatModels || []; + const providerModels = allChatModels.filter( + (model: any) => model.provider === currentProvider + ); + setAvailableChatModels(providerModels); + setCurrentChatModel(NBIAPI.config.chatModel.model); + }, []); + + NBIAPI.configChanged.connect(() => { + const currentProvider = NBIAPI.config.chatModel.provider; + const allChatModels = NBIAPI.config.chatModels || []; + const providerModels = allChatModels.filter( + (model: any) => model.provider === currentProvider + ); + setAvailableChatModels(providerModels); + setCurrentChatModel(NBIAPI.config.chatModel.model); + }); + + // Function to handle model change + const handleModelChange = async (modelId: string) => { + setCurrentChatModel(modelId); + + // Update the configuration + const config = { + chat_model: { + provider: NBIAPI.config.chatModel.provider, + model: modelId, + properties: NBIAPI.config.chatModel.properties || {} + } + }; + + await NBIAPI.setConfig(config); + }; const [toolSelectionTitle, setToolSelectionTitle] = useState('Tool selection'); @@ -1885,6 +1929,32 @@ function SidebarComponent(props: any) { + {availableChatModels.length > 1 && ( + + )} + {availableChatModels.length <= 1 && ( + + {availableChatModels.length === 1 + ? availableChatModels[0].name + : currentChatModel || 'No model'} + + )} {chatMode !== 'ask' && (
= { await NBIAPI.initialize(); + // Create dynamic MCP config after API is initialized + console.log('Creating dynamic MCP config...'); + try { + await NBIAPI.createDynamicMCPConfig(); + console.log('Dynamic MCP config created successfully!'); + } catch (error) { + console.error('Failed to create dynamic MCP config:', error); + } + let openPopover: InlinePromptWidget | null = null; let mcpConfigEditor: MCPConfigEditor | null = null; diff --git a/style/base.css b/style/base.css index 238cd03f..d9de133a 100644 --- a/style/base.css +++ b/style/base.css @@ -15,11 +15,13 @@ height: 25px; padding: 5px 10px; display: flex; + margin: 1%; } .sidebar-title { - font-size: 14px; + font-size: 1.75em; font-weight: bold; + text-align: center; flex-grow: 1; } @@ -31,13 +33,13 @@ .sidebar-user-input { height: auto; - padding: 5px; display: flex; flex-direction: column; background-color: var(--jp-cell-editor-background); border: 2px solid var(--jp-border-color1); margin: 4px; - border-radius: 3px; + border-radius: 8px; + padding: 10px; } /* stylelint-disable */ @@ -55,7 +57,7 @@ /* stylelint-enable */ .sidebar-user-input:focus-within { - border-radius: 2px; + border-radius: 8px; border-color: var(--jp-brand-color1); } @@ -131,6 +133,33 @@ padding: 0 5px; border-color: var(--jp-border-color0); outline: none; + border-radius: 6px; + margin-left: 5px; +} + +.chat-model-select { + height: 24px; + background-color: initial; + color: var(--jp-ui-font-color1); + padding: 0 5px; + border-color: var(--jp-border-color0); + outline: none; + border-radius: 6px; + margin-left: 10px; +} + +.chat-model-display { + height: 24px; + background-color: var(--jp-layout-color2); + color: var(--jp-ui-font-color1); + padding: 3px 8px; + border: 1px solid var(--jp-border-color1); + border-radius: 6px; + margin-left: 5px; + font-size: 12px; + display: inline-block; + line-height: 18px; + cursor: help; } .user-input-footer-button { @@ -167,15 +196,19 @@ } .chat-message { - padding: 5px; + margin: 5px; + border-radius: 8px; + padding: 8px; display: flex; flex-direction: column; + border: 1px solid var(--jp-border-color3); + background-color: var(--jp-layout-color2); + color: var(--jp-ui-font-color1); } .chat-message pre { padding: 3px; border-radius: 3px; - border: 1px solid var(--jp-border-color1); } pre:has(.code-block-header) { @@ -187,6 +220,11 @@ pre:has(.code-block-header) { display: flex; } +.chat-message-user { + margin-left: auto; + max-width: 85%; +} + .chat-message-from { display: flex; align-items: center; @@ -296,9 +334,12 @@ pre:has(.code-block-header) { } .sidebar-greeting { - padding: 5px; + padding: 12px; font-size: 14px; line-height: 20px; + color: var(--jp-ui-font-color1); + border: 1px solid var(--jp-ui-font-color3); + border-radius: 8px; } .user-code-span { From a59a5ef9a01489b1b258e9dca14c88541fb95fe7 Mon Sep 17 00:00:00 2001 From: TheGupta2012 Date: Mon, 22 Sep 2025 13:46:42 +0530 Subject: [PATCH 2/2] refactor package for qbraid --- .github/workflows/build.yml | 14 ++-- .github/workflows/upload-s3-production.yml | 6 +- .github/workflows/upload-s3-staging.yml | 6 +- .gitignore | 4 +- install.json | 4 +- .../server-config/notebook_intelligence.json | 2 +- .../__init__.py | 6 +- .../ai_service_manager.py | 22 ++--- .../api.py | 3 +- .../base_chat_participant.py | 30 +++---- .../built_in_toolsets.py | 34 ++++---- .../config.py | 0 .../extension.py | 36 ++++----- .../github_copilot.py | 5 +- .../github_copilot_chat_participant.py | 4 +- .../github_copilot_llm_provider.py | 5 +- .../litellm_compatible_llm_provider.py | 2 +- .../llm_providers/ollama_llm_provider.py | 4 +- .../openai_compatible_llm_provider.py | 2 +- .../mcp_manager.py | 6 +- .../prompts.py | 3 +- .../util.py | 0 package.json | 37 +++++---- pyproject.toml | 18 ++--- schema/plugin.json | 10 +-- src/api.ts | 2 +- src/chat-sidebar.tsx | 14 ++-- src/handler.ts | 2 +- src/index.ts | 81 ++++++++++--------- src/markdown-renderer.tsx | 17 ++-- src/tokens.ts | 2 +- style/base.css | 1 + yarn.lock | 32 ++++---- 33 files changed, 214 insertions(+), 200 deletions(-) rename {notebook_intelligence => lab_notebook_intelligence}/__init__.py (81%) rename {notebook_intelligence => lab_notebook_intelligence}/ai_service_manager.py (93%) rename {notebook_intelligence => lab_notebook_intelligence}/api.py (99%) rename {notebook_intelligence => lab_notebook_intelligence}/base_chat_participant.py (93%) rename {notebook_intelligence => lab_notebook_intelligence}/built_in_toolsets.py (82%) rename {notebook_intelligence => lab_notebook_intelligence}/config.py (100%) rename {notebook_intelligence => lab_notebook_intelligence}/extension.py (95%) rename {notebook_intelligence => lab_notebook_intelligence}/github_copilot.py (98%) rename {notebook_intelligence => lab_notebook_intelligence}/github_copilot_chat_participant.py (96%) rename {notebook_intelligence => lab_notebook_intelligence}/llm_providers/github_copilot_llm_provider.py (93%) rename {notebook_intelligence => lab_notebook_intelligence}/llm_providers/litellm_compatible_llm_provider.py (96%) rename {notebook_intelligence => lab_notebook_intelligence}/llm_providers/ollama_llm_provider.py (96%) rename {notebook_intelligence => lab_notebook_intelligence}/llm_providers/openai_compatible_llm_provider.py (96%) rename {notebook_intelligence => lab_notebook_intelligence}/mcp_manager.py (98%) rename {notebook_intelligence => lab_notebook_intelligence}/prompts.py (91%) rename {notebook_intelligence => lab_notebook_intelligence}/util.py (100%) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 05b5e3a6..0be6ab5a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -36,10 +36,10 @@ jobs: python -m pip install .[test] jupyter server extension list - jupyter server extension list 2>&1 | grep -ie "notebook_intelligence.*OK" + jupyter server extension list 2>&1 | grep -ie "lab_notebook_intelligence.*OK" jupyter labextension list - jupyter labextension list 2>&1 | grep -ie "@notebook-intelligence/notebook-intelligence.*OK" + jupyter labextension list 2>&1 | grep -ie "@qbraid/lab-notebook-intelligence.*OK" python -m jupyterlab.browser_check - name: Package the extension @@ -48,13 +48,13 @@ jobs: pip install build python -m build - pip uninstall -y "notebook_intelligence" jupyterlab + pip uninstall -y "lab_notebook_intelligence" jupyterlab - name: Upload extension packages uses: actions/upload-artifact@v4 with: name: extension-artifacts - path: dist/notebook_intelligence* + path: dist/lab_notebook_intelligence* if-no-files-found: error test_isolated: @@ -77,14 +77,14 @@ jobs: sudo rm -rf $(which node) sudo rm -rf $(which node) - pip install "jupyterlab>=4.0.0,<5" notebook_intelligence*.whl + pip install "jupyterlab>=4.0.0,<5" lab_notebook_intelligence*.whl jupyter server extension list - jupyter server extension list 2>&1 | grep -ie "notebook_intelligence.*OK" + jupyter server extension list 2>&1 | grep -ie "lab_notebook_intelligence.*OK" jupyter labextension list - jupyter labextension list 2>&1 | grep -ie "@notebook-intelligence/notebook-intelligence.*OK" + jupyter labextension list 2>&1 | grep -ie "@qbraid/lab-notebook-intelligence.*OK" python -m jupyterlab.browser_check --no-browser-test diff --git a/.github/workflows/upload-s3-production.yml b/.github/workflows/upload-s3-production.yml index 9d730b7e..8a62ed17 100644 --- a/.github/workflows/upload-s3-production.yml +++ b/.github/workflows/upload-s3-production.yml @@ -63,7 +63,7 @@ jobs: if: matrix.python-version == '3.11' with: name: extension - path: dist/quantum_jobs*.whl + path: dist/lab_notebook_intelligence*.whl if-no-files-found: error deploy: @@ -87,5 +87,5 @@ jobs: - name: Copy wheel file to S3 lab-extensions bucket run: | - aws s3 rm s3://qbraid-lab-extensions/production/ --recursive --exclude "*" --include "notebook_intelligence*.whl" - aws s3 cp ./ s3://qbraid-lab-extensions/production/ --recursive --exclude "*" --include "notebook_intelligence*.whl" \ No newline at end of file + aws s3 rm s3://qbraid-lab-extensions/production/ --recursive --exclude "*" --include "lab_notebook_intelligence*.whl" + aws s3 cp ./ s3://qbraid-lab-extensions/production/ --recursive --exclude "*" --include "lab_notebook_intelligence*.whl" \ No newline at end of file diff --git a/.github/workflows/upload-s3-staging.yml b/.github/workflows/upload-s3-staging.yml index bf7d7073..da74db58 100644 --- a/.github/workflows/upload-s3-staging.yml +++ b/.github/workflows/upload-s3-staging.yml @@ -64,7 +64,7 @@ jobs: if: matrix.python-version == '3.11' with: name: extension - path: dist/notebook_intelligence*.whl + path: dist/lab_notebook_intelligence*.whl if-no-files-found: error deploy: @@ -88,5 +88,5 @@ jobs: - name: Copy wheel file to S3 lab-extensions bucket run: | - aws s3 rm s3://qbraid-lab-extensions/staging/ --recursive --exclude "*" --include "notebook_intelligence*.whl" - aws s3 cp ./ s3://qbraid-lab-extensions/staging/ --recursive --exclude "*" --include "notebook_intelligence*.whl" \ No newline at end of file + aws s3 rm s3://qbraid-lab-extensions/staging/ --recursive --exclude "*" --include "lab_notebook_intelligence*.whl" + aws s3 cp ./ s3://qbraid-lab-extensions/staging/ --recursive --exclude "*" --include "lab_notebook_intelligence*.whl" \ No newline at end of file diff --git a/.gitignore b/.gitignore index a98459a0..a4cdecb2 100644 --- a/.gitignore +++ b/.gitignore @@ -7,9 +7,9 @@ node_modules/ *.egg-info/ .ipynb_checkpoints *.tsbuildinfo -notebook_intelligence/labextension +lab_notebook_intelligence/labextension # Version file is handled by hatchling -notebook_intelligence/_version.py +lab_notebook_intelligence/_version.py # Created by https://www.gitignore.io/api/python # Edit at https://www.gitignore.io/?templates=python diff --git a/install.json b/install.json index 5055d93c..ee4ee353 100644 --- a/install.json +++ b/install.json @@ -1,5 +1,5 @@ { "packageManager": "python", - "packageName": "notebook_intelligence", - "uninstallInstructions": "Use your Python package manager (pip, conda, etc.) to uninstall the package notebook_intelligence" + "packageName": "lab_notebook_intelligence", + "uninstallInstructions": "Use your Python package manager (pip, conda, etc.) to uninstall the package lab_notebook_intelligence" } diff --git a/jupyter-config/server-config/notebook_intelligence.json b/jupyter-config/server-config/notebook_intelligence.json index cee849a2..d961ae2e 100644 --- a/jupyter-config/server-config/notebook_intelligence.json +++ b/jupyter-config/server-config/notebook_intelligence.json @@ -1,7 +1,7 @@ { "ServerApp": { "jpserver_extensions": { - "notebook_intelligence": true + "lab_notebook_intelligence": true } } } diff --git a/notebook_intelligence/__init__.py b/lab_notebook_intelligence/__init__.py similarity index 81% rename from notebook_intelligence/__init__.py rename to lab_notebook_intelligence/__init__.py index e0e233b4..2aed1ce9 100644 --- a/notebook_intelligence/__init__.py +++ b/lab_notebook_intelligence/__init__.py @@ -7,7 +7,7 @@ # in editable mode with pip. It is highly recommended to install # the package from a stable release or in editable mode: https://pip.pypa.io/en/stable/topics/local-project-installs/#editable-installs import warnings - warnings.warn("Importing 'notebook_intelligence' outside a proper installation.") + warnings.warn("Importing 'lab_notebook_intelligence' outside a proper installation.") __version__ = "dev" import logging @@ -19,12 +19,12 @@ def _jupyter_labextension_paths(): return [{ "src": "labextension", - "dest": "@notebook-intelligence/notebook-intelligence" + "dest": "@qbraid/lab-notebook-intelligence" }] def _jupyter_server_extension_points(): return [{ - "module": "notebook_intelligence", + "module": "lab_notebook_intelligence", "app": NotebookIntelligence }] diff --git a/notebook_intelligence/ai_service_manager.py b/lab_notebook_intelligence/ai_service_manager.py similarity index 93% rename from notebook_intelligence/ai_service_manager.py rename to lab_notebook_intelligence/ai_service_manager.py index 01b2af88..26229230 100644 --- a/notebook_intelligence/ai_service_manager.py +++ b/lab_notebook_intelligence/ai_service_manager.py @@ -6,16 +6,16 @@ import sys from typing import Dict import logging -from notebook_intelligence import github_copilot -from notebook_intelligence.api import ButtonData, ChatModel, EmbeddingModel, InlineCompletionModel, LLMProvider, ChatParticipant, ChatRequest, ChatResponse, CompletionContext, ContextRequest, Host, CompletionContextProvider, MCPServer, MarkdownData, NotebookIntelligenceExtension, TelemetryEvent, TelemetryListener, Tool, Toolset -from notebook_intelligence.base_chat_participant import BaseChatParticipant -from notebook_intelligence.config import NBIConfig -from notebook_intelligence.github_copilot_chat_participant import GithubCopilotChatParticipant -from notebook_intelligence.llm_providers.github_copilot_llm_provider import GitHubCopilotLLMProvider -from notebook_intelligence.llm_providers.litellm_compatible_llm_provider import LiteLLMCompatibleLLMProvider -from notebook_intelligence.llm_providers.ollama_llm_provider import OllamaLLMProvider -from notebook_intelligence.llm_providers.openai_compatible_llm_provider import OpenAICompatibleLLMProvider -from notebook_intelligence.mcp_manager import MCPManager +from lab_notebook_intelligence import github_copilot +from lab_notebook_intelligence.api import ButtonData, ChatModel, EmbeddingModel, InlineCompletionModel, LLMProvider, ChatParticipant, ChatRequest, ChatResponse, CompletionContext, ContextRequest, Host, CompletionContextProvider, MCPServer, MarkdownData, NotebookIntelligenceExtension, TelemetryEvent, TelemetryListener, Tool, Toolset +from lab_notebook_intelligence.base_chat_participant import BaseChatParticipant +from lab_notebook_intelligence.config import NBIConfig +from lab_notebook_intelligence.github_copilot_chat_participant import GithubCopilotChatParticipant +from lab_notebook_intelligence.llm_providers.github_copilot_llm_provider import GitHubCopilotLLMProvider +from lab_notebook_intelligence.llm_providers.litellm_compatible_llm_provider import LiteLLMCompatibleLLMProvider +from lab_notebook_intelligence.llm_providers.ollama_llm_provider import OllamaLLMProvider +from lab_notebook_intelligence.llm_providers.openai_compatible_llm_provider import OpenAICompatibleLLMProvider +from lab_notebook_intelligence.mcp_manager import MCPManager log = logging.getLogger(__name__) @@ -288,7 +288,7 @@ def get_chat_participant(self, prompt: str) -> ChatParticipant: async def handle_chat_request(self, request: ChatRequest, response: ChatResponse, options: dict = {}) -> None: if self.chat_model is None: response.stream(MarkdownData("Chat model is not set!")) - response.stream(ButtonData("Configure", "notebook-intelligence:open-configuration-dialog")) + response.stream(ButtonData("Configure", "lab-notebook-intelligence:open-configuration-dialog")) response.finish() return request.host = self diff --git a/notebook_intelligence/api.py b/lab_notebook_intelligence/api.py similarity index 99% rename from notebook_intelligence/api.py rename to lab_notebook_intelligence/api.py index 453c3aeb..ad18a3f6 100644 --- a/notebook_intelligence/api.py +++ b/lab_notebook_intelligence/api.py @@ -1,7 +1,6 @@ # Copyright (c) Mehmet Bektas import asyncio -import json from typing import Any, Callable, Dict, Union from dataclasses import asdict, dataclass from enum import Enum @@ -10,7 +9,7 @@ import logging from mcp.server.fastmcp.tools import Tool as MCPToolClass -from notebook_intelligence.config import NBIConfig +from lab_notebook_intelligence.config import NBIConfig log = logging.getLogger(__name__) diff --git a/notebook_intelligence/base_chat_participant.py b/lab_notebook_intelligence/base_chat_participant.py similarity index 93% rename from notebook_intelligence/base_chat_participant.py rename to lab_notebook_intelligence/base_chat_participant.py index 7fc683be..ffeabaaa 100644 --- a/notebook_intelligence/base_chat_participant.py +++ b/lab_notebook_intelligence/base_chat_participant.py @@ -3,13 +3,13 @@ import os from typing import Union import json -from notebook_intelligence.api import ChatCommand, ChatParticipant, ChatRequest, ChatResponse, MarkdownData, ProgressData, Tool, ToolPreInvokeResponse -from notebook_intelligence.prompts import Prompts +from lab_notebook_intelligence.api import ChatCommand, ChatParticipant, ChatRequest, ChatResponse, MarkdownData, ProgressData, Tool, ToolPreInvokeResponse +from lab_notebook_intelligence.prompts import Prompts import base64 import logging -from notebook_intelligence.built_in_toolsets import built_in_toolsets +from lab_notebook_intelligence.built_in_toolsets import built_in_toolsets -from notebook_intelligence.util import extract_llm_generated_code +from lab_notebook_intelligence.util import extract_llm_generated_code log = logging.getLogger(__name__) @@ -120,17 +120,17 @@ def pre_invoke(self, request: ChatRequest, tool_args: dict) -> Union[ToolPreInvo async def handle_tool_call(self, request: ChatRequest, response: ChatResponse, tool_context: dict, tool_args: dict) -> str: cell_sources = tool_args.get('cell_sources', []) - ui_cmd_response = await response.run_ui_command('notebook-intelligence:create-new-notebook-from-py', {'code': ''}) + ui_cmd_response = await response.run_ui_command('lab-notebook-intelligence:create-new-notebook-from-py', {'code': ''}) file_path = ui_cmd_response['path'] for cell_source in cell_sources: cell_type = cell_source.get('cell_type') if cell_type == 'markdown': source = cell_source.get('source', '') - ui_cmd_response = await response.run_ui_command('notebook-intelligence:add-markdown-cell-to-notebook', {'markdown': source, 'path': file_path}) + ui_cmd_response = await response.run_ui_command('lab-notebook-intelligence:add-markdown-cell-to-notebook', {'markdown': source, 'path': file_path}) elif cell_type == 'code': source = cell_source.get('source', '') - ui_cmd_response = await response.run_ui_command('notebook-intelligence:add-code-cell-to-notebook', {'code': source, 'path': file_path}) + ui_cmd_response = await response.run_ui_command('lab-notebook-intelligence:add-code-cell-to-notebook', {'code': source, 'path': file_path}) return "Notebook created successfully at {file_path}" @@ -195,7 +195,7 @@ async def handle_tool_call(self, request: ChatRequest, response: ChatResponse, t if notebook_file_path.startswith(server_root_dir): notebook_file_path = os.path.relpath(notebook_file_path, server_root_dir) source = tool_args.get('markdown_cell_source') - ui_cmd_response = await response.run_ui_command('notebook-intelligence:add-markdown-cell-to-notebook', {'markdown': source, 'path': notebook_file_path}) + ui_cmd_response = await response.run_ui_command('lab-notebook-intelligence:add-markdown-cell-to-notebook', {'markdown': source, 'path': notebook_file_path}) return f"Added markdown cell to notebook" class AddCodeCellTool(Tool): @@ -259,7 +259,7 @@ async def handle_tool_call(self, request: ChatRequest, response: ChatResponse, t if notebook_file_path.startswith(server_root_dir): notebook_file_path = os.path.relpath(notebook_file_path, server_root_dir) source = tool_args.get('code_cell_source') - ui_cmd_response = await response.run_ui_command('notebook-intelligence:add-code-cell-to-notebook', {'code': source, 'path': notebook_file_path}) + ui_cmd_response = await response.run_ui_command('lab-notebook-intelligence:add-code-cell-to-notebook', {'code': source, 'path': notebook_file_path}) return "Added code cell added to notebook" # Fallback tool to handle tool errors @@ -304,7 +304,7 @@ def schema(self) -> dict: async def handle_tool_call(self, request: ChatRequest, response: ChatResponse, tool_context: dict, tool_args: dict) -> str: code = tool_args.get('code_cell_source') - ui_cmd_response = await response.run_ui_command('notebook-intelligence:add-code-cell-to-notebook', {'code': code, 'path': tool_context.get('file_path')}) + ui_cmd_response = await response.run_ui_command('lab-notebook-intelligence:add-code-cell-to-notebook', {'code': code, 'path': tool_context.get('file_path')}) return {"result": "Code cell added to notebook"} class BaseChatParticipant(ChatParticipant): @@ -426,14 +426,14 @@ async def handle_ask_mode_chat_request(self, request: ChatRequest, response: Cha chat_model = request.host.chat_model if request.command == 'newNotebook': # create a new notebook - ui_cmd_response = await response.run_ui_command('notebook-intelligence:create-new-notebook-from-py', {'code': ''}) + ui_cmd_response = await response.run_ui_command('lab-notebook-intelligence:create-new-notebook-from-py', {'code': ''}) file_path = ui_cmd_response['path'] code = await self.generate_code_cell(request) markdown = await self.generate_markdown_for_code(request, code) - ui_cmd_response = await response.run_ui_command('notebook-intelligence:add-markdown-cell-to-notebook', {'markdown': markdown, 'path': file_path}) - ui_cmd_response = await response.run_ui_command('notebook-intelligence:add-code-cell-to-notebook', {'code': code, 'path': file_path}) + ui_cmd_response = await response.run_ui_command('lab-notebook-intelligence:add-markdown-cell-to-notebook', {'markdown': markdown, 'path': file_path}) + ui_cmd_response = await response.run_ui_command('lab-notebook-intelligence:add-code-cell-to-notebook', {'code': code, 'path': file_path}) response.stream(MarkdownData(f"Notebook '{file_path}' created and opened successfully")) response.finish() @@ -447,13 +447,13 @@ async def handle_ask_mode_chat_request(self, request: ChatRequest, response: Cha generated = chat_model.completions(messages) code = generated['choices'][0]['message']['content'] code = extract_llm_generated_code(code) - ui_cmd_response = await response.run_ui_command('notebook-intelligence:create-new-file', {'code': code }) + ui_cmd_response = await response.run_ui_command('lab-notebook-intelligence:create-new-file', {'code': code }) file_path = ui_cmd_response['path'] response.stream(MarkdownData(f"File '{file_path}' created successfully")) response.finish() return elif request.command == 'settings': - ui_cmd_response = await response.run_ui_command('notebook-intelligence:open-configuration-dialog') + ui_cmd_response = await response.run_ui_command('lab-notebook-intelligence:open-configuration-dialog') response.stream(MarkdownData(f"Opened the settings dialog")) response.finish() return diff --git a/notebook_intelligence/built_in_toolsets.py b/lab_notebook_intelligence/built_in_toolsets.py similarity index 82% rename from notebook_intelligence/built_in_toolsets.py rename to lab_notebook_intelligence/built_in_toolsets.py index 686c8f01..de129701 100644 --- a/notebook_intelligence/built_in_toolsets.py +++ b/lab_notebook_intelligence/built_in_toolsets.py @@ -1,9 +1,9 @@ # Copyright (c) Mehmet Bektas -from notebook_intelligence.api import ChatResponse, Toolset +from lab_notebook_intelligence.api import ChatResponse, Toolset import logging -import notebook_intelligence.api as nbapi -from notebook_intelligence.api import BuiltinToolset +import lab_notebook_intelligence.api as nbapi +from lab_notebook_intelligence.api import BuiltinToolset log = logging.getLogger(__name__) @@ -13,7 +13,7 @@ async def create_new_notebook(**args) -> str: """Creates a new empty notebook. """ response = args["response"] - ui_cmd_response = await response.run_ui_command('notebook-intelligence:create-new-notebook-from-py', {'code': ''}) + ui_cmd_response = await response.run_ui_command('lab-notebook-intelligence:create-new-notebook-from-py', {'code': ''}) file_path = ui_cmd_response['path'] return f"Created new notebook at {file_path}" @@ -26,7 +26,7 @@ async def rename_notebook(new_name: str, **args) -> str: new_name: New name for the notebook """ response = args["response"] - ui_cmd_response = await response.run_ui_command('notebook-intelligence:rename-notebook', {'newName': new_name}) + ui_cmd_response = await response.run_ui_command('lab-notebook-intelligence:rename-notebook', {'newName': new_name}) return str(ui_cmd_response) @nbapi.auto_approve @@ -37,7 +37,7 @@ async def add_markdown_cell(source: str, **args) -> str: source: Markdown source """ response = args["response"] - ui_cmd_response = await response.run_ui_command('notebook-intelligence:add-markdown-cell-to-active-notebook', {'source': source}) + ui_cmd_response = await response.run_ui_command('lab-notebook-intelligence:add-markdown-cell-to-active-notebook', {'source': source}) return "Added markdown cell to notebook" @@ -49,7 +49,7 @@ async def add_code_cell(source: str, **args) -> str: source: Python code source """ response = args["response"] - ui_cmd_response = await response.run_ui_command('notebook-intelligence:add-code-cell-to-active-notebook', {'source': source}) + ui_cmd_response = await response.run_ui_command('lab-notebook-intelligence:add-code-cell-to-active-notebook', {'source': source}) return "Added code cell to notebook" @@ -59,7 +59,7 @@ async def get_number_of_cells(**args) -> str: """Get number of cells for the active notebook. """ response = args["response"] - ui_cmd_response = await response.run_ui_command('notebook-intelligence:get-number-of-cells', {}) + ui_cmd_response = await response.run_ui_command('lab-notebook-intelligence:get-number-of-cells', {}) return str(ui_cmd_response) @@ -72,7 +72,7 @@ async def get_cell_type_and_source(cell_index: int, **args) -> str: cell_index: Zero based cell index """ response = args["response"] - ui_cmd_response = await response.run_ui_command('notebook-intelligence:get-cell-type-and-source', {"cellIndex": cell_index }) + ui_cmd_response = await response.run_ui_command('lab-notebook-intelligence:get-cell-type-and-source', {"cellIndex": cell_index }) return str(ui_cmd_response) @@ -86,7 +86,7 @@ async def get_cell_output(cell_index: int, **args) -> str: cell_index: Zero based cell index """ response = args["response"] - ui_cmd_response = await response.run_ui_command('notebook-intelligence:get-cell-output', {"cellIndex": cell_index}) + ui_cmd_response = await response.run_ui_command('lab-notebook-intelligence:get-cell-output', {"cellIndex": cell_index}) return str(ui_cmd_response) @@ -101,7 +101,7 @@ async def set_cell_type_and_source(cell_index: int, cell_type: str, source: str, source: Markdown or Python code source """ response = args["response"] - ui_cmd_response = await response.run_ui_command('notebook-intelligence:set-cell-type-and-source', {"cellIndex": cell_index, "cellType": cell_type, "source": source}) + ui_cmd_response = await response.run_ui_command('lab-notebook-intelligence:set-cell-type-and-source', {"cellIndex": cell_index, "cellType": cell_type, "source": source}) return str(ui_cmd_response) @@ -115,7 +115,7 @@ async def delete_cell(cell_index: int, **args) -> str: """ response = args["response"] - ui_cmd_response = await response.run_ui_command('notebook-intelligence:delete-cell-at-index', {"cellIndex": cell_index}) + ui_cmd_response = await response.run_ui_command('lab-notebook-intelligence:delete-cell-at-index', {"cellIndex": cell_index}) return f"Deleted the cell at index: {cell_index}" @@ -130,7 +130,7 @@ async def insert_cell(cell_index: int, cell_type: str, source: str, **args) -> s source: Markdown or Python code source """ response = args["response"] - ui_cmd_response = await response.run_ui_command('notebook-intelligence:insert-cell-at-index', {"cellIndex": cell_index, "cellType": cell_type, "source": source}) + ui_cmd_response = await response.run_ui_command('lab-notebook-intelligence:insert-cell-at-index', {"cellIndex": cell_index, "cellType": cell_type, "source": source}) return str(ui_cmd_response) @@ -144,7 +144,7 @@ async def run_cell(cell_index: int, **args) -> str: """ response = args["response"] - ui_cmd_response = await response.run_ui_command('notebook-intelligence:run-cell-at-index', {"cellIndex": cell_index}) + ui_cmd_response = await response.run_ui_command('lab-notebook-intelligence:run-cell-at-index', {"cellIndex": cell_index}) return f"Ran the cell at index: {cell_index}" @@ -166,7 +166,7 @@ async def create_new_python_file(code: str, **args) -> str: code: Python code source """ response = args["response"] - ui_cmd_response = await response.run_ui_command('notebook-intelligence:create-new-file', {'code': code}) + ui_cmd_response = await response.run_ui_command('lab-notebook-intelligence:create-new-file', {'code': code}) file_path = ui_cmd_response['path'] return f"Created new Python file at {file_path}" @@ -177,7 +177,7 @@ async def get_file_content(**args) -> str: """Returns the content of the current file. """ response = args["response"] - ui_cmd_response = await response.run_ui_command('notebook-intelligence:get-current-file-content', {}) + ui_cmd_response = await response.run_ui_command('lab-notebook-intelligence:get-current-file-content', {}) return f"Received the file content" @@ -189,7 +189,7 @@ async def set_file_content(content: str, **args) -> str: content: File content """ response = args["response"] - ui_cmd_response = await response.run_ui_command('notebook-intelligence:set-current-file-content', {"content": content}) + ui_cmd_response = await response.run_ui_command('lab-notebook-intelligence:set-current-file-content', {"content": content}) return f"Set the file content" diff --git a/notebook_intelligence/config.py b/lab_notebook_intelligence/config.py similarity index 100% rename from notebook_intelligence/config.py rename to lab_notebook_intelligence/config.py diff --git a/notebook_intelligence/extension.py b/lab_notebook_intelligence/extension.py similarity index 95% rename from notebook_intelligence/extension.py rename to lab_notebook_intelligence/extension.py index 858413f3..5c2f8129 100644 --- a/notebook_intelligence/extension.py +++ b/lab_notebook_intelligence/extension.py @@ -18,11 +18,11 @@ import tornado from tornado import websocket from traitlets import Unicode -from notebook_intelligence.api import BuiltinToolset, CancelToken, ChatMode, ChatResponse, ChatRequest, ContextRequest, ContextRequestType, RequestDataType, RequestToolSelection, ResponseStreamData, ResponseStreamDataType, BackendMessageType, SignalImpl -from notebook_intelligence.ai_service_manager import AIServiceManager -import notebook_intelligence.github_copilot as github_copilot -from notebook_intelligence.built_in_toolsets import built_in_toolsets -from notebook_intelligence.util import ThreadSafeWebSocketConnector +from lab_notebook_intelligence.api import BuiltinToolset, CancelToken, ChatMode, ChatResponse, ChatRequest, ContextRequest, ContextRequestType, RequestDataType, RequestToolSelection, ResponseStreamData, ResponseStreamDataType, BackendMessageType, SignalImpl +from lab_notebook_intelligence.ai_service_manager import AIServiceManager +import lab_notebook_intelligence.github_copilot as github_copilot +from lab_notebook_intelligence.built_in_toolsets import built_in_toolsets +from lab_notebook_intelligence.util import ThreadSafeWebSocketConnector ai_service_manager: AIServiceManager = None log = logging.getLogger(__name__) @@ -675,8 +675,8 @@ async def handle_inline_completions(prefix, suffix, language, filename, response response_emitter.finish() class NotebookIntelligence(ExtensionApp): - name = "notebook_intelligence" - default_url = "/notebook-intelligence" + name = "lab_notebook_intelligence" + default_url = "/lab-notebook-intelligence" load_other_extensions = True file_url_prefix = "/render" @@ -724,17 +724,17 @@ def _setup_handlers(self, web_app): host_pattern = ".*$" base_url = web_app.settings["base_url"] - route_pattern_capabilities = url_path_join(base_url, "notebook-intelligence", "capabilities") - route_pattern_config = url_path_join(base_url, "notebook-intelligence", "config") - route_pattern_update_provider_models = url_path_join(base_url, "notebook-intelligence", "update-provider-models") - route_pattern_reload_mcp_servers = url_path_join(base_url, "notebook-intelligence", "reload-mcp-servers") - route_pattern_mcp_config_file = url_path_join(base_url, "notebook-intelligence", "mcp-config-file") - route_pattern_create_dynamic_mcp_config = url_path_join(base_url, "notebook-intelligence", "create-dynamic-mcp-config") - route_pattern_emit_telemetry_event = url_path_join(base_url, "notebook-intelligence", "emit-telemetry-event") - route_pattern_github_login_status = url_path_join(base_url, "notebook-intelligence", "gh-login-status") - route_pattern_github_login = url_path_join(base_url, "notebook-intelligence", "gh-login") - route_pattern_github_logout = url_path_join(base_url, "notebook-intelligence", "gh-logout") - route_pattern_copilot = url_path_join(base_url, "notebook-intelligence", "copilot") + route_pattern_capabilities = url_path_join(base_url, "lab-notebook-intelligence", "capabilities") + route_pattern_config = url_path_join(base_url, "lab-notebook-intelligence", "config") + route_pattern_update_provider_models = url_path_join(base_url, "lab-notebook-intelligence", "update-provider-models") + route_pattern_reload_mcp_servers = url_path_join(base_url, "lab-notebook-intelligence", "reload-mcp-servers") + route_pattern_mcp_config_file = url_path_join(base_url, "lab-notebook-intelligence", "mcp-config-file") + route_pattern_create_dynamic_mcp_config = url_path_join(base_url, "lab-notebook-intelligence", "create-dynamic-mcp-config") + route_pattern_emit_telemetry_event = url_path_join(base_url, "lab-notebook-intelligence", "emit-telemetry-event") + route_pattern_github_login_status = url_path_join(base_url, "lab-notebook-intelligence", "gh-login-status") + route_pattern_github_login = url_path_join(base_url, "lab-notebook-intelligence", "gh-login") + route_pattern_github_logout = url_path_join(base_url, "lab-notebook-intelligence", "gh-logout") + route_pattern_copilot = url_path_join(base_url, "lab-notebook-intelligence", "copilot") GetCapabilitiesHandler.notebook_execute_tool = self.notebook_execute_tool NotebookIntelligence.handlers = [ (route_pattern_capabilities, GetCapabilitiesHandler), diff --git a/notebook_intelligence/github_copilot.py b/lab_notebook_intelligence/github_copilot.py similarity index 98% rename from notebook_intelligence/github_copilot.py rename to lab_notebook_intelligence/github_copilot.py index acf9368d..5b3368c9 100644 --- a/notebook_intelligence/github_copilot.py +++ b/lab_notebook_intelligence/github_copilot.py @@ -3,7 +3,6 @@ # GitHub auth and inline completion sections are derivative of https://github.com/B00TK1D/copilot-api import base64 -from dataclasses import dataclass from enum import Enum import os, json, time, requests, threading from typing import Any @@ -12,8 +11,8 @@ import sseclient import datetime as dt import logging -from notebook_intelligence.api import BackendMessageType, CancelToken, ChatResponse, CompletionContext, MarkdownData -from notebook_intelligence.util import decrypt_with_password, encrypt_with_password, ThreadSafeWebSocketConnector +from lab_notebook_intelligence.api import BackendMessageType, CancelToken, ChatResponse, CompletionContext, MarkdownData +from lab_notebook_intelligence.util import decrypt_with_password, encrypt_with_password, ThreadSafeWebSocketConnector from ._version import __version__ as NBI_VERSION diff --git a/notebook_intelligence/github_copilot_chat_participant.py b/lab_notebook_intelligence/github_copilot_chat_participant.py similarity index 96% rename from notebook_intelligence/github_copilot_chat_participant.py rename to lab_notebook_intelligence/github_copilot_chat_participant.py index d65186aa..8bf38009 100644 --- a/notebook_intelligence/github_copilot_chat_participant.py +++ b/lab_notebook_intelligence/github_copilot_chat_participant.py @@ -1,7 +1,7 @@ # Copyright (c) Mehmet Bektas -from notebook_intelligence.base_chat_participant import BaseChatParticipant -from notebook_intelligence.prompts import Prompts +from lab_notebook_intelligence.base_chat_participant import BaseChatParticipant +from lab_notebook_intelligence.prompts import Prompts import base64 diff --git a/notebook_intelligence/llm_providers/github_copilot_llm_provider.py b/lab_notebook_intelligence/llm_providers/github_copilot_llm_provider.py similarity index 93% rename from notebook_intelligence/llm_providers/github_copilot_llm_provider.py rename to lab_notebook_intelligence/llm_providers/github_copilot_llm_provider.py index 34951128..1abf5bc8 100644 --- a/notebook_intelligence/llm_providers/github_copilot_llm_provider.py +++ b/lab_notebook_intelligence/llm_providers/github_copilot_llm_provider.py @@ -2,9 +2,8 @@ from typing import Any -import requests -from notebook_intelligence.api import ChatModel, EmbeddingModel, InlineCompletionModel, LLMProvider, CancelToken, ChatResponse, CompletionContext -from notebook_intelligence.github_copilot import generate_copilot_headers, completions, inline_completions +from lab_notebook_intelligence.api import ChatModel, EmbeddingModel, InlineCompletionModel, LLMProvider, CancelToken, ChatResponse, CompletionContext +from lab_notebook_intelligence.github_copilot import generate_copilot_headers, completions, inline_completions import logging log = logging.getLogger(__name__) diff --git a/notebook_intelligence/llm_providers/litellm_compatible_llm_provider.py b/lab_notebook_intelligence/llm_providers/litellm_compatible_llm_provider.py similarity index 96% rename from notebook_intelligence/llm_providers/litellm_compatible_llm_provider.py rename to lab_notebook_intelligence/llm_providers/litellm_compatible_llm_provider.py index 10a105d9..8f6e8196 100644 --- a/notebook_intelligence/llm_providers/litellm_compatible_llm_provider.py +++ b/lab_notebook_intelligence/llm_providers/litellm_compatible_llm_provider.py @@ -2,7 +2,7 @@ import json from typing import Any -from notebook_intelligence.api import ChatModel, EmbeddingModel, InlineCompletionModel, LLMProvider, CancelToken, ChatResponse, CompletionContext, LLMProviderProperty +from lab_notebook_intelligence.api import ChatModel, EmbeddingModel, InlineCompletionModel, LLMProvider, CancelToken, ChatResponse, CompletionContext, LLMProviderProperty import litellm DEFAULT_CONTEXT_WINDOW = 4096 diff --git a/notebook_intelligence/llm_providers/ollama_llm_provider.py b/lab_notebook_intelligence/llm_providers/ollama_llm_provider.py similarity index 96% rename from notebook_intelligence/llm_providers/ollama_llm_provider.py rename to lab_notebook_intelligence/llm_providers/ollama_llm_provider.py index 335d1bf6..53d24183 100644 --- a/notebook_intelligence/llm_providers/ollama_llm_provider.py +++ b/lab_notebook_intelligence/llm_providers/ollama_llm_provider.py @@ -2,11 +2,11 @@ import json from typing import Any -from notebook_intelligence.api import ChatModel, EmbeddingModel, InlineCompletionModel, LLMProvider, CancelToken, ChatResponse, CompletionContext +from lab_notebook_intelligence.api import ChatModel, EmbeddingModel, InlineCompletionModel, LLMProvider, CancelToken, ChatResponse, CompletionContext import ollama import logging -from notebook_intelligence.util import extract_llm_generated_code +from lab_notebook_intelligence.util import extract_llm_generated_code log = logging.getLogger(__name__) diff --git a/notebook_intelligence/llm_providers/openai_compatible_llm_provider.py b/lab_notebook_intelligence/llm_providers/openai_compatible_llm_provider.py similarity index 96% rename from notebook_intelligence/llm_providers/openai_compatible_llm_provider.py rename to lab_notebook_intelligence/llm_providers/openai_compatible_llm_provider.py index 4f6b5451..caf6713b 100644 --- a/notebook_intelligence/llm_providers/openai_compatible_llm_provider.py +++ b/lab_notebook_intelligence/llm_providers/openai_compatible_llm_provider.py @@ -2,7 +2,7 @@ import json from typing import Any -from notebook_intelligence.api import ChatModel, EmbeddingModel, InlineCompletionModel, LLMProvider, CancelToken, ChatResponse, CompletionContext, LLMProviderProperty +from lab_notebook_intelligence.api import ChatModel, EmbeddingModel, InlineCompletionModel, LLMProvider, CancelToken, ChatResponse, CompletionContext, LLMProviderProperty from openai import OpenAI DEFAULT_CONTEXT_WINDOW = 4096 diff --git a/notebook_intelligence/mcp_manager.py b/lab_notebook_intelligence/mcp_manager.py similarity index 98% rename from notebook_intelligence/mcp_manager.py rename to lab_notebook_intelligence/mcp_manager.py index 6a2a7d07..5b1b57c1 100644 --- a/notebook_intelligence/mcp_manager.py +++ b/lab_notebook_intelligence/mcp_manager.py @@ -8,9 +8,9 @@ from fastmcp.client import StdioTransport, StreamableHttpTransport from mcp import StdioServerParameters from mcp.client.stdio import get_default_environment as mcp_get_default_environment -from mcp.types import CallToolResult, TextContent, ImageContent -from notebook_intelligence.api import ChatCommand, ChatRequest, ChatResponse, HTMLFrameData, ImageData, MCPServer, MarkdownData, ProgressData, Tool, ToolPreInvokeResponse -from notebook_intelligence.base_chat_participant import BaseChatParticipant +from mcp.types import TextContent, ImageContent +from lab_notebook_intelligence.api import ChatCommand, ChatRequest, ChatResponse, HTMLFrameData, ImageData, MCPServer, MarkdownData, ProgressData, Tool, ToolPreInvokeResponse +from lab_notebook_intelligence.base_chat_participant import BaseChatParticipant import logging from fastmcp import Client diff --git a/notebook_intelligence/prompts.py b/lab_notebook_intelligence/prompts.py similarity index 91% rename from notebook_intelligence/prompts.py rename to lab_notebook_intelligence/prompts.py index b973587e..a1acc0aa 100644 --- a/notebook_intelligence/prompts.py +++ b/lab_notebook_intelligence/prompts.py @@ -10,7 +10,8 @@ Follow the user's requirements carefully & to the letter. Follow Microsoft content policies. Avoid content that violates copyrights. -If you are asked to generate content that is harmful, hateful, racist, sexist, lewd, violent, or completely irrelevant to software engineering, only respond with "Sorry, I can't assist with that." +If you are asked about yourself or your capabilities, answer truthfully but concisely. +If you are asked to generate content that is harmful, hateful, racist, sexist, lewd, violent, or irrelevant to software engineering, only respond with "Sorry, I can't assist with that. I'm an agent designed to help with programming tasks." Keep your answers short and impersonal. You can answer general programming questions and perform the following tasks: * Ask a question about the files in your current workspace diff --git a/notebook_intelligence/util.py b/lab_notebook_intelligence/util.py similarity index 100% rename from notebook_intelligence/util.py rename to lab_notebook_intelligence/util.py diff --git a/package.json b/package.json index 3ab744ed..bdb72574 100644 --- a/package.json +++ b/package.json @@ -1,24 +1,31 @@ { - "name": "@notebook-intelligence/notebook-intelligence", - "version": "2.4.2", - "description": "AI coding assistant for JupyterLab", + "name": "@qbraid/lab-notebook-intelligence", + "version": "0.0.1", + "description": "AI coding assistant for qbraid Lab", "keywords": [ "AI", "notebook", "intelligence", "jupyter", "jupyterlab", - "jupyterlab-extension" + "jupyterlab-extension", + "quantum" ], - "homepage": "https://github.com/notebook-intelligence/notebook-intelligence", + "homepage": "https://github.com/qBraid/lab-notebook-intelligence", "bugs": { - "url": "https://github.com/notebook-intelligence/notebook-intelligence/issues" + "url": "https://github.com/qBraid/lab-notebook-intelligence/issues" }, "license": "GPL-3.0", - "author": { - "name": "Mehmet Bektas", - "email": "mbektasgh@outlook.com" - }, + "authors": [ + { + "name": "Mehmet Bektas", + "email": "mbektasgh@outlook.com" + }, + { + "name": "qBraid Development Team", + "email": "contact@qbraid.com" + } + ], "files": [ "lib/**/*.{d.ts,eot,gif,html,jpg,js,js.map,json,png,svg,woff2,ttf}", "style/**/*.{css,js,eot,gif,html,jpg,json,png,svg,woff2,ttf}", @@ -30,7 +37,7 @@ "style": "style/index.css", "repository": { "type": "git", - "url": "https://github.com/notebook-intelligence/notebook-intelligence.git" + "url": "https://github.com/qBraid/lab-notebook-intelligence.git" }, "scripts": { "build": "jlpm build:lib && jlpm build:labextension:dev", @@ -42,7 +49,7 @@ "clean": "jlpm clean:lib", "clean:lib": "rimraf lib tsconfig.tsbuildinfo", "clean:lintcache": "rimraf .eslintcache .stylelintcache", - "clean:labextension": "rimraf notebook_intelligence/labextension notebook_intelligence/_version.py", + "clean:labextension": "rimraf lab_notebook_intelligence/labextension lab_notebook_intelligence/_version.py", "clean:all": "jlpm clean:lib && jlpm clean:labextension && jlpm clean:lintcache", "eslint": "jlpm eslint:check --fix", "eslint:check": "eslint . --cache --ext .ts,.tsx", @@ -116,16 +123,16 @@ "pip" ], "base": { - "name": "notebook_intelligence" + "name": "lab_notebook_intelligence" } } }, "extension": true, - "outputDir": "notebook_intelligence/labextension", + "outputDir": "lab_notebook_intelligence/labextension", "schemaDir": "schema", "webpackConfig": "./webpack.config.js", "sharedPackages": { - "@notebook-intelligence/notebook-intelligence": { + "@qbraid/lab-notebook-intelligence": { "singleton": true } } diff --git a/pyproject.toml b/pyproject.toml index 27f8743d..04007403 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,7 +3,7 @@ requires = ["hatchling>=1.5.0", "jupyterlab>=4.0.0,<5", "hatch-nodejs-version>=0 build-backend = "hatchling.build" [project] -name = "notebook_intelligence" +name = "lab_notebook_intelligence" readme = "README.md" license = { file = "LICENSE" } requires-python = ">=3.10" @@ -40,25 +40,25 @@ source = "nodejs" fields = ["description", "authors", "urls", "keywords"] [tool.hatch.build.targets.sdist] -artifacts = ["notebook_intelligence/labextension"] +artifacts = ["lab_notebook_intelligence/labextension"] exclude = [".github", "binder", "src", "style", "media"] [tool.hatch.build.targets.wheel.shared-data] -"notebook_intelligence/labextension" = "share/jupyter/labextensions/@notebook-intelligence/notebook-intelligence" -"install.json" = "share/jupyter/labextensions/@notebook-intelligence/notebook-intelligence/install.json" +"lab_notebook_intelligence/labextension" = "share/jupyter/labextensions/@qbraid/lab-notebook-intelligence" +"install.json" = "share/jupyter/labextensions/@qbraid/lab-notebook-intelligence/install.json" "jupyter-config/server-config" = "etc/jupyter/jupyter_server_config.d" [tool.hatch.build.hooks.version] -path = "notebook_intelligence/_version.py" +path = "lab_notebook_intelligence/_version.py" [tool.hatch.build.hooks.jupyter-builder] dependencies = ["hatch-jupyter-builder>=0.5"] build-function = "hatch_jupyter_builder.npm_builder" ensured-targets = [ - "notebook_intelligence/labextension/static/style.js", - "notebook_intelligence/labextension/package.json", + "lab_notebook_intelligence/labextension/static/style.js", + "lab_notebook_intelligence/labextension/package.json", ] -skip-if-exists = ["notebook_intelligence/labextension/static/style.js"] +skip-if-exists = ["lab_notebook_intelligence/labextension/static/style.js"] [tool.hatch.build.hooks.jupyter-builder.build-kwargs] build_cmd = "build:prod" @@ -68,7 +68,7 @@ npm = ["jlpm"] build_cmd = "install:extension" npm = ["jlpm"] source_dir = "src" -build_dir = "notebook_intelligence/labextension" +build_dir = "lab_notebook_intelligence/labextension" [tool.jupyter-releaser.options] version_cmd = "hatch version" diff --git a/schema/plugin.json b/schema/plugin.json index 452b5b92..7bfc9b70 100644 --- a/schema/plugin.json +++ b/schema/plugin.json @@ -7,9 +7,9 @@ "jupyter.lab.toolbars": { "Cell": [ { - "name": "notebook-intelligence:editor-generate-code", - "command": "notebook-intelligence:editor-generate-code", - "icon": "notebook-intelligence:sparkles-icon", + "name": "lab-notebook-intelligence:editor-generate-code", + "command": "lab-notebook-intelligence:editor-generate-code", + "icon": "lab-notebook-intelligence:sparkles-icon", "caption": "Generate code", "rank": 0 } @@ -17,13 +17,13 @@ }, "jupyter.lab.shortcuts": [ { - "command": "notebook-intelligence:editor-generate-code", + "command": "lab-notebook-intelligence:editor-generate-code", "keys": ["Accel G"], "selector": ".jp-Editor", "preventDefault": true }, { - "command": "notebook-intelligence:editor-generate-code", + "command": "lab-notebook-intelligence:editor-generate-code", "keys": ["Accel G"], "selector": ".jp-CodeCell", "preventDefault": true diff --git a/src/api.ts b/src/api.ts index e48a8e91..b7439877 100644 --- a/src/api.ts +++ b/src/api.ts @@ -114,7 +114,7 @@ export class NBIAPI { const serverSettings = ServerConnection.makeSettings(); const wsUrl = URLExt.join( serverSettings.wsUrl, - 'notebook-intelligence', + 'lab-notebook-intelligence', 'copilot' ); diff --git a/src/chat-sidebar.tsx b/src/chat-sidebar.tsx index 6012c89a..64e79324 100644 --- a/src/chat-sidebar.tsx +++ b/src/chat-sidebar.tsx @@ -595,7 +595,7 @@ function ChatResponse(props: any) { onClick={() => { markFormConfirmed(item.id); runCommand( - 'notebook-intelligence:chat-user-input', + 'lab-notebook-intelligence:chat-user-input', item.content.confirmArgs ); }} @@ -609,7 +609,7 @@ function ChatResponse(props: any) { onClick={() => { markFormCanceled(item.id); runCommand( - 'notebook-intelligence:chat-user-input', + 'lab-notebook-intelligence:chat-user-input', item.content.cancelArgs ); }} @@ -1233,7 +1233,7 @@ function SidebarComponent(props: any) { setShowModeTools(false); props .getApp() - .commands.execute('notebook-intelligence:open-configuration-dialog'); + .commands.execute('lab-notebook-intelligence:open-configuration-dialog'); }; const handleChatToolsButtonClick = async () => { @@ -1583,14 +1583,14 @@ function SidebarComponent(props: any) { const handleConfigurationClick = async () => { props .getApp() - .commands.execute('notebook-intelligence:open-configuration-dialog'); + .commands.execute('lab-notebook-intelligence:open-configuration-dialog'); }; const handleLoginClick = async () => { props .getApp() .commands.execute( - 'notebook-intelligence:open-github-copilot-login-dialog' + 'lab-notebook-intelligence:open-github-copilot-login-dialog' ); }; @@ -2376,7 +2376,7 @@ function GitHubCopilotStatusComponent(props: any) { props .getApp() .commands.execute( - 'notebook-intelligence:open-github-copilot-login-dialog' + 'lab-notebook-intelligence:open-github-copilot-login-dialog' ); }; @@ -2965,7 +2965,7 @@ function ConfigurationDialogBodyComponent(props: any) {
GitHub Copilot login{' '} {' '} diff --git a/src/handler.ts b/src/handler.ts index 6f173bbc..85234c87 100644 --- a/src/handler.ts +++ b/src/handler.ts @@ -19,7 +19,7 @@ export async function requestAPI( const settings = ServerConnection.makeSettings(); const requestUrl = URLExt.join( settings.baseUrl, - 'notebook-intelligence', // API Namespace + 'lab-notebook-intelligence', // API Namespace endPoint ); diff --git a/src/index.ts b/src/index.ts index e8a6e482..693e0b75 100644 --- a/src/index.ts +++ b/src/index.ts @@ -83,60 +83,65 @@ import { UUID } from '@lumino/coreutils'; import * as path from 'path'; namespace CommandIDs { - export const chatuserInput = 'notebook-intelligence:chat-user-input'; - export const insertAtCursor = 'notebook-intelligence:insert-at-cursor'; - export const addCodeAsNewCell = 'notebook-intelligence:add-code-as-new-cell'; - export const createNewFile = 'notebook-intelligence:create-new-file'; + export const chatuserInput = 'lab-notebook-intelligence:chat-user-input'; + export const insertAtCursor = 'lab-notebook-intelligence:insert-at-cursor'; + export const addCodeAsNewCell = + 'lab-notebook-intelligence:add-code-as-new-cell'; + export const createNewFile = 'lab-notebook-intelligence:create-new-file'; export const createNewNotebookFromPython = - 'notebook-intelligence:create-new-notebook-from-py'; - export const renameNotebook = 'notebook-intelligence:rename-notebook'; + 'lab-notebook-intelligence:create-new-notebook-from-py'; + export const renameNotebook = 'lab-notebook-intelligence:rename-notebook'; export const addCodeCellToNotebook = - 'notebook-intelligence:add-code-cell-to-notebook'; + 'lab-notebook-intelligence:add-code-cell-to-notebook'; export const addMarkdownCellToNotebook = - 'notebook-intelligence:add-markdown-cell-to-notebook'; + 'lab-notebook-intelligence:add-markdown-cell-to-notebook'; export const editorGenerateCode = - 'notebook-intelligence:editor-generate-code'; + 'lab-notebook-intelligence:editor-generate-code'; export const editorExplainThisCode = - 'notebook-intelligence:editor-explain-this-code'; - export const editorFixThisCode = 'notebook-intelligence:editor-fix-this-code'; + 'lab-notebook-intelligence:editor-explain-this-code'; + export const editorFixThisCode = + 'lab-notebook-intelligence:editor-fix-this-code'; export const editorExplainThisOutput = - 'notebook-intelligence:editor-explain-this-output'; + 'lab-notebook-intelligence:editor-explain-this-output'; export const editorTroubleshootThisOutput = - 'notebook-intelligence:editor-troubleshoot-this-output'; + 'lab-notebook-intelligence:editor-troubleshoot-this-output'; export const openGitHubCopilotLoginDialog = - 'notebook-intelligence:open-github-copilot-login-dialog'; + 'lab-notebook-intelligence:open-github-copilot-login-dialog'; export const openConfigurationDialog = - 'notebook-intelligence:open-configuration-dialog'; + 'lab-notebook-intelligence:open-configuration-dialog'; export const addMarkdownCellToActiveNotebook = - 'notebook-intelligence:add-markdown-cell-to-active-notebook'; + 'lab-notebook-intelligence:add-markdown-cell-to-active-notebook'; export const addCodeCellToActiveNotebook = - 'notebook-intelligence:add-code-cell-to-active-notebook'; - export const deleteCellAtIndex = 'notebook-intelligence:delete-cell-at-index'; - export const insertCellAtIndex = 'notebook-intelligence:insert-cell-at-index'; + 'lab-notebook-intelligence:add-code-cell-to-active-notebook'; + export const deleteCellAtIndex = + 'lab-notebook-intelligence:delete-cell-at-index'; + export const insertCellAtIndex = + 'lab-notebook-intelligence:insert-cell-at-index'; export const getCellTypeAndSource = - 'notebook-intelligence:get-cell-type-and-source'; + 'lab-notebook-intelligence:get-cell-type-and-source'; export const setCellTypeAndSource = - 'notebook-intelligence:set-cell-type-and-source'; - export const getNumberOfCells = 'notebook-intelligence:get-number-of-cells'; - export const getCellOutput = 'notebook-intelligence:get-cell-output'; - export const runCellAtIndex = 'notebook-intelligence:run-cell-at-index'; + 'lab-notebook-intelligence:set-cell-type-and-source'; + export const getNumberOfCells = + 'lab-notebook-intelligence:get-number-of-cells'; + export const getCellOutput = 'lab-notebook-intelligence:get-cell-output'; + export const runCellAtIndex = 'lab-notebook-intelligence:run-cell-at-index'; export const getCurrentFileContent = - 'notebook-intelligence:get-current-file-content'; + 'lab-notebook-intelligence:get-current-file-content'; export const setCurrentFileContent = - 'notebook-intelligence:set-current-file-content'; + 'lab-notebook-intelligence:set-current-file-content'; export const openMCPConfigEditor = - 'notebook-intelligence:open-mcp-config-editor'; + 'lab-notebook-intelligence:open-mcp-config-editor'; } const DOCUMENT_WATCH_INTERVAL = 1000; const MAX_TOKENS = 4096; const githubCopilotIcon = new LabIcon({ - name: 'notebook-intelligence:github-copilot-icon', + name: 'lab-notebook-intelligence:github-copilot-icon', svgstr: copilotSvgstr }); const sparkleIcon = new LabIcon({ - name: 'notebook-intelligence:sparkles-icon', + name: 'lab-notebook-intelligence:sparkles-icon', svgstr: sparklesSvgstr }); @@ -459,7 +464,7 @@ class NBIInlineCompletionProvider } get identifier(): string { - return '@notebook-intelligence/notebook-intelligence'; + return '@notebook-intelligence/lab-notebook-intelligence'; } get icon(): LabIcon.ILabIcon { @@ -599,10 +604,10 @@ class MCPConfigEditor { } /** - * Initialization data for the @notebook-intelligence/notebook-intelligence extension. + * Initialization data for the @qbraid/lab-notebook-intelligence extension. */ const plugin: JupyterFrontEndPlugin = { - id: '@notebook-intelligence/notebook-intelligence:plugin', + id: '@qbraid/lab-notebook-intelligence:plugin', description: 'Notebook Intelligence', autoStart: true, requires: [ @@ -627,7 +632,7 @@ const plugin: JupyterFrontEndPlugin = { statusBar: IStatusBar | null ) => { console.log( - 'JupyterLab extension @notebook-intelligence/notebook-intelligence is activated!' + 'JupyterLab extension @qbraid/lab-notebook-intelligence is activated!' ); const telemetryEmitter = new TelemetryEmitter(); @@ -674,7 +679,7 @@ const plugin: JupyterFrontEndPlugin = { }) .catch(reason => { console.error( - 'Failed to load settings for @notebook-intelligence/notebook-intelligence.', + 'Failed to load settings for @notebook-intelligence/lab-notebook-intelligence.', reason ); }); @@ -717,7 +722,7 @@ const plugin: JupyterFrontEndPlugin = { }; const panel = new Panel(); - panel.id = 'notebook-intelligence-tab'; + panel.id = 'lab-notebook-intelligence-tab'; panel.title.caption = 'Notebook Intelligence'; const sidebarIcon = new LabIcon({ name: 'ui-components:palette', @@ -1250,7 +1255,7 @@ const plugin: JupyterFrontEndPlugin = { onEditMCPConfigClicked: () => { dialog?.dispose(); app.commands.execute( - 'notebook-intelligence:open-mcp-config-editor' + 'lab-notebook-intelligence:open-mcp-config-editor' ); } }); @@ -1739,7 +1744,7 @@ const plugin: JupyterFrontEndPlugin = { }); const copilotContextMenu = new Menu({ commands: copilotMenuCommands }); - copilotContextMenu.id = 'notebook-intelligence:editor-context-menu'; + copilotContextMenu.id = 'lab-notebook-intelligence:editor-context-menu'; copilotContextMenu.title.label = 'Notebook Intelligence'; copilotContextMenu.title.icon = sidebarIcon; copilotContextMenu.addItem({ command: CommandIDs.editorGenerateCode }); @@ -1770,7 +1775,7 @@ const plugin: JupyterFrontEndPlugin = { }); statusBar.registerStatusItem( - 'notebook-intelligence:github-copilot-status', + 'lab-notebook-intelligence:github-copilot-status', { item: githubCopilotStatusBarItem, align: 'right', diff --git a/src/markdown-renderer.tsx b/src/markdown-renderer.tsx index 5db6dc71..89a3f7fd 100644 --- a/src/markdown-renderer.tsx +++ b/src/markdown-renderer.tsx @@ -48,21 +48,24 @@ export function MarkdownRenderer({ }; const handleInsertAtCursorClick = () => { - app.commands.execute('notebook-intelligence:insert-at-cursor', { + app.commands.execute('lab-notebook-intelligence:insert-at-cursor', { language, code: codeString }); }; const handleAddCodeAsNewCell = () => { - app.commands.execute('notebook-intelligence:add-code-as-new-cell', { - language, - code: codeString - }); + app.commands.execute( + 'lab-notebook-intelligence:add-code-as-new-cell', + { + language, + code: codeString + } + ); }; const handleCreateNewFileClick = () => { - app.commands.execute('notebook-intelligence:create-new-file', { + app.commands.execute('lab-notebook-intelligence:create-new-file', { language, code: codeString }); @@ -70,7 +73,7 @@ export function MarkdownRenderer({ const handleCreateNewNotebookClick = () => { app.commands.execute( - 'notebook-intelligence:create-new-notebook-from-py', + 'lab-notebook-intelligence:create-new-notebook-from-py', { language, code: codeString } ); }; diff --git a/src/tokens.ts b/src/tokens.ts index 52377526..acfb6f66 100644 --- a/src/tokens.ts +++ b/src/tokens.ts @@ -121,7 +121,7 @@ export interface ITelemetryEmitter { } export const INotebookIntelligence = new Token( - '@notebook-intelligence/notebook-intelligence:INotebookIntelligence', + '@qbraid/lab-notebook-intelligence:INotebookIntelligence', 'AI coding assistant for JupyterLab.' ); diff --git a/style/base.css b/style/base.css index d9de133a..b2b7a2ac 100644 --- a/style/base.css +++ b/style/base.css @@ -8,6 +8,7 @@ .sidebar { display: flex; flex-direction: column; + min-width: 25%; height: 100%; } diff --git a/yarn.lock b/yarn.lock index f56b74db..d5cb4346 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2248,9 +2248,23 @@ __metadata: languageName: node linkType: hard -"@notebook-intelligence/notebook-intelligence@workspace:.": +"@pkgjs/parseargs@npm:^0.11.0": + version: 0.11.0 + resolution: "@pkgjs/parseargs@npm:0.11.0" + checksum: 6ad6a00fc4f2f2cfc6bff76fb1d88b8ee20bc0601e18ebb01b6d4be583733a860239a521a7fbca73b612e66705078809483549d2b18f370eb346c5155c8e4a0f + languageName: node + linkType: hard + +"@pkgr/core@npm:^0.1.0": + version: 0.1.1 + resolution: "@pkgr/core@npm:0.1.1" + checksum: 6f25fd2e3008f259c77207ac9915b02f1628420403b2630c92a07ff963129238c9262afc9e84344c7a23b5cc1f3965e2cd17e3798219f5fd78a63d144d3cceba + languageName: node + linkType: hard + +"@qbraid/lab-notebook-intelligence@workspace:.": version: 0.0.0-use.local - resolution: "@notebook-intelligence/notebook-intelligence@workspace:." + resolution: "@qbraid/lab-notebook-intelligence@workspace:." dependencies: "@jupyterlab/application": ^4.0.0 "@jupyterlab/builder": ^4.0.0 @@ -2294,20 +2308,6 @@ __metadata: languageName: unknown linkType: soft -"@pkgjs/parseargs@npm:^0.11.0": - version: 0.11.0 - resolution: "@pkgjs/parseargs@npm:0.11.0" - checksum: 6ad6a00fc4f2f2cfc6bff76fb1d88b8ee20bc0601e18ebb01b6d4be583733a860239a521a7fbca73b612e66705078809483549d2b18f370eb346c5155c8e4a0f - languageName: node - linkType: hard - -"@pkgr/core@npm:^0.1.0": - version: 0.1.1 - resolution: "@pkgr/core@npm:0.1.1" - checksum: 6f25fd2e3008f259c77207ac9915b02f1628420403b2630c92a07ff963129238c9262afc9e84344c7a23b5cc1f3965e2cd17e3798219f5fd78a63d144d3cceba - languageName: node - linkType: hard - "@rjsf/core@npm:^5.13.4": version: 5.21.1 resolution: "@rjsf/core@npm:5.21.1"