From 4e3d4a4add0fd89fc74431213151d15fd41d47e9 Mon Sep 17 00:00:00 2001 From: TheGupta2012 Date: Mon, 29 Sep 2025 13:48:36 +0530 Subject: [PATCH 1/3] add copilot auto login through env vars --- .../ai_service_manager.py | 8 ++--- lab_notebook_intelligence/github_copilot.py | 35 +++++++++++++------ 2 files changed, 27 insertions(+), 16 deletions(-) diff --git a/lab_notebook_intelligence/ai_service_manager.py b/lab_notebook_intelligence/ai_service_manager.py index c4c285c..4007de1 100644 --- a/lab_notebook_intelligence/ai_service_manager.py +++ b/lab_notebook_intelligence/ai_service_manager.py @@ -31,18 +31,14 @@ ) 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.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.ollama_llm_provider import OllamaLLMProvider from lab_notebook_intelligence.llm_providers.openai_compatible_llm_provider import ( OpenAICompatibleLLMProvider, ) diff --git a/lab_notebook_intelligence/github_copilot.py b/lab_notebook_intelligence/github_copilot.py index bbedf43..6911acd 100644 --- a/lab_notebook_intelligence/github_copilot.py +++ b/lab_notebook_intelligence/github_copilot.py @@ -78,6 +78,21 @@ websocket_connector: ThreadSafeWebSocketConnector = None github_login_status_change_updater_enabled = False +deprecated_user_data_file = os.path.join(os.path.expanduser("~"), ".jupyter", "nbi-data.json") +user_data_file = os.path.join(os.path.expanduser("~"), ".jupyter", "nbi", "user-data.json") +access_token_password = os.getenv("NBI_GH_ACCESS_TOKEN_PASSWORD", "nbi-access-token-password") + + +def get_gh_access_token_from_env() -> str: + access_token = os.environ.get("NBI_GH_ACCESS_TOKEN_ENCRYPTED") + if access_token is not None: + try: + base64_bytes = base64.b64decode(access_token.encode("utf-8")) + return decrypt_with_password(access_token_password, base64_bytes).decode("utf-8") + except Exception as e: + log.error(f"Failed to decrypt GitHub access token from environment variable: {e}") + return None + def enable_github_login_status_change_updater(enabled: bool): global github_login_status_change_updater_enabled @@ -109,11 +124,6 @@ def get_login_status(): return response -deprecated_user_data_file = os.path.join(os.path.expanduser("~"), ".jupyter", "nbi-data.json") -user_data_file = os.path.join(os.path.expanduser("~"), ".jupyter", "nbi", "user-data.json") -access_token_password = os.getenv("NBI_GH_ACCESS_TOKEN_PASSWORD", "nbi-access-token-password") - - def read_stored_github_access_token() -> str: try: if os.path.exists(user_data_file): @@ -186,7 +196,12 @@ def login_with_existing_credentials(store_access_token: bool): if github_auth["status"] is not LoginStatus.NOT_LOGGED_IN: return - if store_access_token: + # Check for GitHub access token in environment variable + github_access_token_provided = get_gh_access_token_from_env() + if github_access_token_provided: + log.info("Using GitHub access token from environment variable") + remember_github_access_token = False # Do not store the token if it's from the environment + elif store_access_token: github_access_token_provided = read_stored_github_access_token() remember_github_access_token = True else: @@ -331,8 +346,7 @@ def wait_for_user_access_token_thread_func(): def get_token(): global github_auth, github_access_token_provided, API_ENDPOINT, PROXY_ENDPOINT, TOKEN_REFRESH_INTERVAL - access_token = github_auth["access_token"] - + access_token = get_gh_access_token_from_env() or github_auth["access_token"] if access_token is None: return @@ -351,7 +365,6 @@ def get_token(): ) resp_json = resp.json() - if resp.status_code == 401: github_access_token_provided = None logout() @@ -393,7 +406,9 @@ def get_token_thread_func(): return token = github_auth["token"] # update token if 10 seconds or less left to expiration - if github_auth["access_token"] is not None and ( + access_token = get_gh_access_token_from_env() or github_auth["access_token"] + + if access_token and ( token is None or (dt.datetime.now() - github_auth["token_expires_at"]).total_seconds() > -10 ): From 8d25c9647a2847cf34331b483f97fdb69e411090 Mon Sep 17 00:00:00 2001 From: TheGupta2012 Date: Mon, 29 Sep 2025 19:21:54 +0530 Subject: [PATCH 2/3] restrict inline completions --- src/chat-sidebar.tsx | 4 +--- src/index.ts | 33 +++++++++++++++++++++++++++++---- style/base.css | 2 +- 3 files changed, 31 insertions(+), 8 deletions(-) diff --git a/src/chat-sidebar.tsx b/src/chat-sidebar.tsx index 38b371b..ff96ca2 100644 --- a/src/chat-sidebar.tsx +++ b/src/chat-sidebar.tsx @@ -1323,7 +1323,7 @@ function SidebarComponent(props: any) { } setCopilotRequestInProgress(true); - + console.log('Request triggered on input - ', prompt); const activeDocInfo: IActiveDocumentInfo = props.getActiveDocumentInfo(); const extractedPrompt = prompt; const contents: IChatMessageContent[] = []; @@ -1363,8 +1363,6 @@ function SidebarComponent(props: any) { } } - console.log('Complete context : ', additionalContext); - submitCompletionRequest( { messageId: lastMessageId.current, diff --git a/src/index.ts b/src/index.ts index 5b4cf94..6f86abb 100644 --- a/src/index.ts +++ b/src/index.ts @@ -345,7 +345,7 @@ class NBIInlineCompletionProvider get schema(): ISettingRegistry.IProperty { return { default: { - debouncerDelay: 200, + debouncerDelay: 100, timeout: 15000 } }; @@ -438,7 +438,6 @@ class NBIInlineCompletionProvider editorType } }); - return new Promise((resolve, reject) => { const items: IInlineCompletionItem[] = []; @@ -453,11 +452,35 @@ class NBIInlineCompletionProvider RequestDataType.CancelInlineCompletionRequest, { chatId: this._lastRequestInfo.chatId } ); + + if ( + this._lastRequestInfo.completion && + preCursor.length > 0 && + preCursor[preCursor.length - 1] === + this._lastRequestInfo.completion[0] + ) { + // if the last element of the preCursor is the first element of the completion + // we do not need to make a completion request on the assumption that the + // user is about to type the rest of the completion + resolve({ + items: [ + { insertText: this._lastRequestInfo.completion.substring(1) } + ] + }); + this._lastRequestInfo.completion = + this._lastRequestInfo.completion.substring(1); + return; + } } const messageId = UUID.uuid4(); const chatId = UUID.uuid4(); - this._lastRequestInfo = { chatId, messageId, requestTime: new Date() }; + this._lastRequestInfo = { + chatId, + messageId, + completion: '', + requestTime: new Date() + }; NBIAPI.inlineCompletionsRequest( chatId, @@ -475,6 +498,7 @@ class NBIInlineCompletionProvider items.push({ insertText: response.data.completions }); + this._lastRequestInfo.completion = response.data.completions; const timeElapsed = (new Date().getTime() - @@ -518,6 +542,7 @@ class NBIInlineCompletionProvider private _lastRequestInfo: { chatId: string; messageId: string; + completion: string; requestTime: Date; } = null; private _telemetryEmitter: TelemetryEmitter; @@ -721,7 +746,7 @@ const plugin: JupyterFrontEndPlugin = { }) .catch(reason => { console.error( - 'Failed to load settings for @notebook-intelligence/lab-notebook-intelligence.', + 'Failed to load settings for @lab-notebook-intelligence/lab-notebook-intelligence.', reason ); }); diff --git a/style/base.css b/style/base.css index a557e45..e79f628 100644 --- a/style/base.css +++ b/style/base.css @@ -8,7 +8,7 @@ .sidebar { display: flex; flex-direction: column; - min-width: 40%; + min-width: 50%; height: 100%; } From 90ae82de0e28f246de4a817852535b69dfd61e70 Mon Sep 17 00:00:00 2001 From: TheGupta2012 Date: Mon, 29 Sep 2025 19:45:14 +0530 Subject: [PATCH 3/3] add todo --- src/index.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/index.ts b/src/index.ts index 6f86abb..b71f0f9 100644 --- a/src/index.ts +++ b/src/index.ts @@ -453,6 +453,7 @@ class NBIInlineCompletionProvider { chatId: this._lastRequestInfo.chatId } ); + // TODO: handle fast-typers if ( this._lastRequestInfo.completion && preCursor.length > 0 &&