From fed54b854e16a68f2951987a562d23adab1a80b4 Mon Sep 17 00:00:00 2001 From: Philipp Spiess Date: Tue, 25 Apr 2023 15:36:34 +0200 Subject: [PATCH] Cody Web: Fix no embeddings use case (#51082) Reported here: https://github.com/sourcegraph/sourcegraph/pull/51072#issuecomment-1521295540 Right now, Cody web simply crashes when encountering a repo that has no embeddings. This is because it falls back to the keyword based implementation which throws on the web (we won't have it there for a while, because the vs code extension uses a native library to implement that). Since Cody is now useful even for unindexed repos (because we add the currently viewed file into the context automatically), I think making it gracefully handle this situation is better than disabling Cody for these views. ## Test plan Screenshot 2023-04-25 at 12 15 13 --- client/cody-shared/src/chat/client.ts | 10 +--------- client/cody-shared/src/chat/context.ts | 1 + client/cody-shared/src/codebase-context/index.ts | 6 +++++- .../cody-ui/src/chat/inputContext/ChatInputContext.tsx | 9 ++++++--- client/cody/src/chat/ChatViewProvider.ts | 1 + client/web/src/stores/codyChat.ts | 1 + 6 files changed, 15 insertions(+), 13 deletions(-) diff --git a/client/cody-shared/src/chat/client.ts b/client/cody-shared/src/chat/client.ts index b7ef7d4642f..ac080f69a63 100644 --- a/client/cody-shared/src/chat/client.ts +++ b/client/cody-shared/src/chat/client.ts @@ -4,7 +4,6 @@ import { Editor } from '../editor' import { PrefilledOptions, withPreselectedOptions } from '../editor/withPreselectedOptions' import { SourcegraphEmbeddingsSearchClient } from '../embeddings/client' import { SourcegraphIntentDetectorClient } from '../intent-detector/client' -import { KeywordContextFetcher } from '../keyword-context' import { SourcegraphBrowserCompletionsClient } from '../sourcegraph-api/completions/browserClient' import { SourcegraphGraphQLAPIClient } from '../sourcegraph-api/graphql/client' import { isError } from '../utils' @@ -63,7 +62,7 @@ export async function createClient({ const embeddingsSearch = repoId ? new SourcegraphEmbeddingsSearchClient(graphqlClient, repoId) : null - const codebaseContext = new CodebaseContext(config, embeddingsSearch, noopKeywordFetcher) + const codebaseContext = new CodebaseContext(config, embeddingsSearch, null) const intentDetector = new SourcegraphIntentDetectorClient(graphqlClient) @@ -142,10 +141,3 @@ export async function createClient({ }, } } - -const noopKeywordFetcher: KeywordContextFetcher = { - // eslint-disable-next-line @typescript-eslint/require-await - async getContext() { - throw new Error('noopKeywordFetcher: not implemented') - }, -} diff --git a/client/cody-shared/src/chat/context.ts b/client/cody-shared/src/chat/context.ts index e065459e5e3..923b785f955 100644 --- a/client/cody-shared/src/chat/context.ts +++ b/client/cody-shared/src/chat/context.ts @@ -5,4 +5,5 @@ export interface ChatContextStatus { connection?: boolean codebase?: string filePath?: string + supportsKeyword?: boolean } diff --git a/client/cody-shared/src/codebase-context/index.ts b/client/cody-shared/src/codebase-context/index.ts index f6b816cc9c8..2fc82ed255c 100644 --- a/client/cody-shared/src/codebase-context/index.ts +++ b/client/cody-shared/src/codebase-context/index.ts @@ -17,7 +17,7 @@ export class CodebaseContext { constructor( private config: Pick, private embeddings: EmbeddingsSearch | null, - private keywords: KeywordContextFetcher + private keywords: KeywordContextFetcher | null ) {} public onConfigurationChange(newConfig: typeof this.config): void { @@ -81,6 +81,10 @@ export class CodebaseContext { } private async getKeywordContextMessages(query: string, options: ContextSearchOptions): Promise { + if (!this.keywords) { + return [] + } + const results = await this.keywords.getContext(query, options.numCodeResults + options.numTextResults) return results.flatMap(({ content, fileName }) => { const messageText = populateCodeContextTemplate(content, fileName) diff --git a/client/cody-ui/src/chat/inputContext/ChatInputContext.tsx b/client/cody-ui/src/chat/inputContext/ChatInputContext.tsx index adc287f1c09..7624b88c0ae 100644 --- a/client/cody-ui/src/chat/inputContext/ChatInputContext.tsx +++ b/client/cody-ui/src/chat/inputContext/ChatInputContext.tsx @@ -37,9 +37,12 @@ export const ChatInputContext: React.FunctionComponent<{ return (
-

- {contextStatus.mode && contextStatus.connection ? 'Embeddings' : 'Keyword'} -

+ {contextStatus.mode && contextStatus.connection ? ( +

Embeddings

+ ) : contextStatus.supportsKeyword ? ( +

Keyword

+ ) : null} + {items.length > 0 && (
    {items.map(({ icon, text, tooltip }, index) => ( diff --git a/client/cody/src/chat/ChatViewProvider.ts b/client/cody/src/chat/ChatViewProvider.ts index b8cc510a2d6..6211cdc458a 100644 --- a/client/cody/src/chat/ChatViewProvider.ts +++ b/client/cody/src/chat/ChatViewProvider.ts @@ -326,6 +326,7 @@ export class ChatViewProvider implements vscode.WebviewViewProvider, vscode.Disp connection: this.codebaseContext.checkEmbeddingsConnection(), codebase: this.config.codebase, filePath: editorContext ? vscode.workspace.asRelativePath(editorContext.filePath) : undefined, + supportsKeyword: true, }, }) } diff --git a/client/web/src/stores/codyChat.ts b/client/web/src/stores/codyChat.ts index ded1268d4d8..edfc0d4b965 100644 --- a/client/web/src/stores/codyChat.ts +++ b/client/web/src/stores/codyChat.ts @@ -187,6 +187,7 @@ export const useChatStoreState = create((set, get): CodyChatStore return { codebase: config?.codebase, filePath: editor?.getActiveTextEditorSelectionOrEntireFile()?.fileName, + supportsKeyword: false, mode: config?.useContext, connection: true, }