From 41b3233693c34cd81c872a1e7279721b5f640d60 Mon Sep 17 00:00:00 2001 From: Nate Sesti Date: Wed, 6 Sep 2023 19:40:09 -0700 Subject: fix: :bug: fixes for a few context_providers --- continuedev/src/continuedev/core/context.py | 32 +++++++++++++++++----- .../continuedev/plugins/context_providers/file.py | 17 +----------- .../plugins/context_providers/search.py | 8 ++++++ .../plugins/context_providers/terminal.py | 16 +++++++++-- continuedev/src/continuedev/server/ide.py | 7 +++-- continuedev/src/continuedev/server/ide_protocol.py | 2 +- extension/src/continueIdeClient.ts | 16 +++++++++-- 7 files changed, 65 insertions(+), 33 deletions(-) diff --git a/continuedev/src/continuedev/core/context.py b/continuedev/src/continuedev/core/context.py index 47763d8b..17e6e85c 100644 --- a/continuedev/src/continuedev/core/context.py +++ b/continuedev/src/continuedev/core/context.py @@ -252,9 +252,9 @@ class ContextManager: await index.add_documents(documents or []) try: - await asyncio.wait_for(add_docs(), timeout=5) + await asyncio.wait_for(add_docs(), timeout=20) except asyncio.TimeoutError: - logger.warning("Failed to add document to meilisearch in 5 seconds") + logger.warning("Failed to add document to meilisearch in 20 seconds") except Exception as e: logger.warning(f"Error adding document to meilisearch: {e}") @@ -266,7 +266,7 @@ class ContextManager: async with Client("http://localhost:7700") as search_client: await asyncio.wait_for( search_client.index(SEARCH_INDEX_NAME).delete_documents(ids), - timeout=5, + timeout=20, ) async def load_index(self, workspace_dir: str): @@ -284,7 +284,7 @@ class ContextManager: ) await globalSearchIndex.update_filterable_attributes(["workspace_dir"]) - for _, provider in self.context_providers.items(): + async def load_context_provider(provider: ContextProvider): ti = time.time() context_items = await provider.provide_context_items(workspace_dir) @@ -299,14 +299,32 @@ class ContextManager: for item in context_items ] if len(documents) > 0: - await asyncio.wait_for( - globalSearchIndex.add_documents(documents), timeout=5 - ) + try: + await asyncio.wait_for( + globalSearchIndex.add_documents(documents), timeout=20 + ) + except asyncio.TimeoutError: + logger.warning( + f"Failed to add documents to meilisearch for context provider {provider.__class__.__name__} in 20 seconds" + ) + return + except Exception as e: + logger.warning( + f"Error adding documents to meilisearch for context provider {provider.__class__.__name__}: {e}" + ) + return tf = time.time() logger.debug( f"Loaded {len(documents)} documents into meilisearch in {tf - ti} seconds for context provider {provider.title}" ) + + tasks = [ + load_context_provider(provider) + for _, provider in self.context_providers.items() + ] + await asyncio.wait_for(asyncio.gather(*tasks), timeout=20) + except Exception as e: logger.debug(f"Error loading meilisearch index: {e}") diff --git a/continuedev/src/continuedev/plugins/context_providers/file.py b/continuedev/src/continuedev/plugins/context_providers/file.py index a824a44d..6b27a889 100644 --- a/continuedev/src/continuedev/plugins/context_providers/file.py +++ b/continuedev/src/continuedev/plugins/context_providers/file.py @@ -101,7 +101,7 @@ class FileContextProvider(ContextProvider): ) async def provide_context_items(self, workspace_dir: str) -> List[ContextItem]: - contents = await self.sdk.ide.listDirectoryContents(workspace_dir, False) + contents = await self.sdk.ide.listDirectoryContents(workspace_dir, True) if contents is None: return [] @@ -109,21 +109,6 @@ class FileContextProvider(ContextProvider): for filepath in contents[:1000]: absolute_filepaths.append(filepath) - # for root, dir_names, file_names in os.walk(workspace_dir): - # dir_names[:] = [ - # d - # for d in dir_names - # if not any(fnmatch(d, pattern) for pattern in self.ignore_patterns) - # ] - # for file_name in file_names: - # absolute_filepaths.append(os.path.join(root, file_name)) - - # if len(absolute_filepaths) > 1000: - # break - - # if len(absolute_filepaths) > 1000: - # break - items = await asyncio.gather( *[ self.get_context_item_for_filepath(filepath) diff --git a/continuedev/src/continuedev/plugins/context_providers/search.py b/continuedev/src/continuedev/plugins/context_providers/search.py index 6aecb5bf..8a3a3689 100644 --- a/continuedev/src/continuedev/plugins/context_providers/search.py +++ b/continuedev/src/continuedev/plugins/context_providers/search.py @@ -5,6 +5,7 @@ from ripgrepy import Ripgrepy from ...core.context import ContextProvider from ...core.main import ContextItem, ContextItemDescription, ContextItemId +from ...libs.util.logging import logger from .util import remove_meilisearch_disallowed_chars @@ -75,6 +76,13 @@ class SearchContextProvider(ContextProvider): async def provide_context_items(self, workspace_dir: str) -> List[ContextItem]: self.workspace_dir = workspace_dir + + try: + Ripgrepy("", workspace_dir, rg_path=self._get_rg_path()) + except Exception as e: + logger.warning(f"Failed to initialize ripgrepy: {e}") + return [] + return [self.BASE_CONTEXT_ITEM] async def get_item(self, id: ContextItemId, query: str) -> ContextItem: diff --git a/continuedev/src/continuedev/plugins/context_providers/terminal.py b/continuedev/src/continuedev/plugins/context_providers/terminal.py index c7e91945..57d06a4f 100644 --- a/continuedev/src/continuedev/plugins/context_providers/terminal.py +++ b/continuedev/src/continuedev/plugins/context_providers/terminal.py @@ -1,13 +1,14 @@ -from typing import List +from typing import Any, Coroutine, List from ...core.context import ContextProvider -from ...core.main import ContextItem, ContextItemDescription, ContextItemId +from ...core.main import ChatMessage, ContextItem, ContextItemDescription, ContextItemId class TerminalContextProvider(ContextProvider): title = "terminal" workspace_dir: str = None + get_last_n_commands: int = 3 def _terminal_context_item(self, content: str = ""): return ContextItem( @@ -19,6 +20,12 @@ class TerminalContextProvider(ContextProvider): ), ) + async def get_chat_messages(self) -> Coroutine[Any, Any, List[ChatMessage]]: + msgs = await super().get_chat_messages() + for msg in msgs: + msg.summary = msg.content[-1000:] + return msgs + async def provide_context_items(self, workspace_dir: str) -> List[ContextItem]: self.workspace_dir = workspace_dir return [self._terminal_context_item()] @@ -27,6 +34,9 @@ class TerminalContextProvider(ContextProvider): if not id.item_id == self.title: raise Exception("Invalid item id") - terminal_contents = await self.sdk.ide.getTerminalContents() + terminal_contents = await self.sdk.ide.getTerminalContents( + self.get_last_n_commands + ) + terminal_contents = terminal_contents[-5000:] return self._terminal_context_item(terminal_contents) diff --git a/continuedev/src/continuedev/server/ide.py b/continuedev/src/continuedev/server/ide.py index fba455c4..5d1d897e 100644 --- a/continuedev/src/continuedev/server/ide.py +++ b/continuedev/src/continuedev/server/ide.py @@ -451,9 +451,10 @@ class IdeProtocolServer(AbstractIdeProtocolServer): ) return resp.visibleFiles - async def getTerminalContents(self) -> str: + async def getTerminalContents(self, commands: int = -1) -> str: + """Get the contents of the terminal, up to the last 'commands' commands, or all if commands is -1""" resp = await self._send_and_receive_json( - {}, TerminalContentsResponse, "getTerminalContents" + {"commands": commands}, TerminalContentsResponse, "getTerminalContents" ) return resp.contents @@ -604,7 +605,7 @@ async def websocket_endpoint(websocket: WebSocket, session_id: str = None): message_type = message["messageType"] data = message["data"] - logger.debug(f"Received IDE message: {message_type}") + # logger.debug(f"Received IDE message: {message_type}") create_async_task( ideProtocolServer.handle_json(message_type, data), ideProtocolServer.on_error, diff --git a/continuedev/src/continuedev/server/ide_protocol.py b/continuedev/src/continuedev/server/ide_protocol.py index 2a07ae2a..34030047 100644 --- a/continuedev/src/continuedev/server/ide_protocol.py +++ b/continuedev/src/continuedev/server/ide_protocol.py @@ -158,7 +158,7 @@ class AbstractIdeProtocolServer(ABC): """Check if a file exists""" @abstractmethod - async def getTerminalContents(self) -> str: + async def getTerminalContents(self, commands: int = -1) -> str: """Get the terminal contents""" workspace_directory: str diff --git a/extension/src/continueIdeClient.ts b/extension/src/continueIdeClient.ts index 48000b76..3b46d90a 100644 --- a/extension/src/continueIdeClient.ts +++ b/extension/src/continueIdeClient.ts @@ -294,7 +294,7 @@ class IdeProtocolClient { break; case "getTerminalContents": messenger.send("getTerminalContents", { - contents: await this.getTerminalContents(), + contents: await this.getTerminalContents(data.commands), }); break; case "listDirectoryContents": @@ -631,9 +631,19 @@ class IdeProtocolClient { return contents; } - async getTerminalContents(): Promise { + async getTerminalContents(commands: number = -1): Promise { const tempCopyBuffer = await vscode.env.clipboard.readText(); - await vscode.commands.executeCommand("workbench.action.terminal.selectAll"); + if (commands < 0) { + await vscode.commands.executeCommand( + "workbench.action.terminal.selectAll" + ); + } else { + for (let i = 0; i < commands; i++) { + await vscode.commands.executeCommand( + "workbench.action.terminal.selectToPreviousCommand" + ); + } + } await vscode.commands.executeCommand( "workbench.action.terminal.copySelection" ); -- cgit v1.2.3-70-g09d2